summaryrefslogtreecommitdiff
path: root/src/library/text.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-07-29 13:21:25 +0200
committerLaurenz <laurmaedje@gmail.com>2021-07-29 13:28:19 +0200
commit2c6127dea611944abb09a0d38375ad7cf9baced0 (patch)
tree6572d169d4ce26edc38a880860ebae2f49639fb8 /src/library/text.rs
parent7d15dc634b3be1b6e284bb6b2450e3736d3e6e8d (diff)
Refactor state
Diffstat (limited to 'src/library/text.rs')
-rw-r--r--src/library/text.rs96
1 files changed, 49 insertions, 47 deletions
diff --git a/src/library/text.rs b/src/library/text.rs
index b56cbcd3..54e9794a 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -1,17 +1,10 @@
-use crate::exec::{LineState, TextState};
+use crate::exec::{FontState, LineState};
use crate::layout::Paint;
use super::*;
/// `font`: Configure the font.
pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let families: Vec<_> = args.all().collect();
- let list = if families.is_empty() {
- args.named(ctx, "family")
- } else {
- Some(FontDef(families))
- };
-
let size = args.eat::<Linear>().or_else(|| args.named(ctx, "size"));
let style = args.named(ctx, "style");
let weight = args.named(ctx, "weight");
@@ -19,20 +12,25 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let top_edge = args.named(ctx, "top-edge");
let bottom_edge = args.named(ctx, "bottom-edge");
let fill = args.named(ctx, "fill");
+
+ let families: Vec<_> = args.all().collect();
+ let list = if families.is_empty() {
+ args.named(ctx, "family")
+ } else {
+ Some(FontDef(Rc::new(families)))
+ };
+
let serif = args.named(ctx, "serif");
let sans_serif = args.named(ctx, "sans-serif");
let monospace = args.named(ctx, "monospace");
+
let body = args.expect::<Template>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
- let state = ctx.state.text_mut();
+ let state = ctx.state.font_mut();
- if let Some(linear) = size {
- state.size = linear.resolve(state.size);
- }
-
- if let Some(FontDef(list)) = &list {
- state.families_mut().list = list.clone();
+ if let Some(size) = size {
+ state.size = size.resolve(state.size);
}
if let Some(style) = style {
@@ -59,6 +57,10 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
state.fill = Paint::Color(fill);
}
+ if let Some(FontDef(list)) = &list {
+ state.families_mut().list = list.clone();
+ }
+
if let Some(FamilyDef(serif)) = &serif {
state.families_mut().serif = serif.clone();
}
@@ -75,41 +77,42 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
})
}
-struct FontDef(Vec<FontFamily>);
+struct FontDef(Rc<Vec<FontFamily>>);
castable! {
FontDef: "font family or array of font families",
- Value::Str(string) => Self(vec![FontFamily::Named(string.to_lowercase())]),
- Value::Array(values) => Self(values
- .into_iter()
- .filter_map(|v| v.cast().ok())
- .collect()
- ),
- @family: FontFamily => Self(vec![family.clone()]),
+ Value::Str(string) => Self(Rc::new(vec![FontFamily::Named(string.to_lowercase())])),
+ Value::Array(values) => Self(Rc::new(
+ values
+ .into_iter()
+ .filter_map(|v| v.cast().ok())
+ .collect()
+ )),
+ @family: FontFamily => Self(Rc::new(vec![family.clone()])),
}
-struct FamilyDef(Vec<String>);
+struct FamilyDef(Rc<Vec<String>>);
castable! {
FamilyDef: "string or array of strings",
- Value::Str(string) => Self(vec![string.to_lowercase()]),
- Value::Array(values) => Self(values
- .into_iter()
- .filter_map(|v| v.cast().ok())
- .map(|string: EcoString| string.to_lowercase())
- .collect()
- ),
+ Value::Str(string) => Self(Rc::new(vec![string.to_lowercase()])),
+ Value::Array(values) => Self(Rc::new(
+ values
+ .into_iter()
+ .filter_map(|v| v.cast().ok())
+ .map(|string: EcoString| string.to_lowercase())
+ .collect()
+ )),
}
/// `par`: Configure paragraphs.
pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let par_spacing = args.named(ctx, "spacing");
let line_spacing = args.named(ctx, "leading");
- let word_spacing = args.named(ctx, "word-spacing");
let body = args.expect::<Template>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
- let state = ctx.state.text_mut();
+ let state = ctx.state.par_mut();
if let Some(par_spacing) = par_spacing {
state.par_spacing = par_spacing;
@@ -119,10 +122,6 @@ pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
state.line_spacing = line_spacing;
}
- if let Some(word_spacing) = word_spacing {
- state.word_spacing = word_spacing;
- }
-
ctx.parbreak();
body.exec(ctx);
})
@@ -130,20 +129,23 @@ pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
/// `lang`: Configure the language.
pub fn lang(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let iso = args.eat::<EcoString>().map(|s| lang_dir(&s));
- let dir = match args.named::<Spanned<Dir>>(ctx, "dir") {
- Some(dir) if dir.v.axis() == SpecAxis::Horizontal => Some(dir.v),
- Some(dir) => {
+ let iso = args.eat::<EcoString>();
+ let dir = if let Some(dir) = args.named::<Spanned<Dir>>(ctx, "dir") {
+ if dir.v.axis() == SpecAxis::Horizontal {
+ Some(dir.v)
+ } else {
ctx.diag(error!(dir.span, "must be horizontal"));
None
}
- None => None,
+ } else {
+ iso.as_deref().map(lang_dir)
};
+
let body = args.expect::<Template>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
- if let Some(dir) = dir.or(iso) {
- ctx.state.dir = dir;
+ if let Some(dir) = dir {
+ ctx.state.dirs.cross = dir;
}
ctx.parbreak();
@@ -151,7 +153,7 @@ pub fn lang(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
})
}
-/// The default direction for the language identified by `iso`.
+/// The default direction for the language identified by the given `iso` code.
fn lang_dir(iso: &str) -> Dir {
match iso.to_ascii_lowercase().as_str() {
"ar" | "he" | "fa" | "ur" | "ps" | "yi" => Dir::RTL,
@@ -178,7 +180,7 @@ pub fn overline(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
fn line_impl(
ctx: &mut EvalContext,
args: &mut FuncArgs,
- substate: fn(&mut TextState) -> &mut Option<Rc<LineState>>,
+ substate: fn(&mut FontState) -> &mut Option<Rc<LineState>>,
) -> Value {
let stroke = args.eat().or_else(|| args.named(ctx, "stroke"));
let thickness = args.eat::<Linear>().or_else(|| args.named(ctx, "thickness"));
@@ -197,7 +199,7 @@ fn line_impl(
});
Value::template(move |ctx| {
- *substate(ctx.state.text_mut()) = state.clone();
+ *substate(ctx.state.font_mut()) = state.clone();
body.exec(ctx);
})
}