diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/exec/state.rs | 8 | ||||
| -rw-r--r-- | src/layout/shaping.rs | 19 | ||||
| -rw-r--r-- | src/library/text.rs | 30 |
3 files changed, 32 insertions, 25 deletions
diff --git a/src/exec/state.rs b/src/exec/state.rs index 6f900b54..24e4b9f3 100644 --- a/src/exec/state.rs +++ b/src/exec/state.rs @@ -165,17 +165,17 @@ impl Default for FontState { /// Describes a line that could be positioned over, under or on top of text. #[derive(Debug, Copy, Clone, PartialEq, Hash)] pub struct LineState { + /// Stroke color of the line. Defaults to the text color if `None`. + pub stroke: Option<Fill>, /// Thickness of the line's stroke. Calling functions should attempt to /// read this value from the appropriate font tables if this is `None`. - pub strength: Option<Linear>, + pub thickness: Option<Linear>, /// Position of the line relative to the baseline. Calling functions should /// attempt to read this value from the appropriate font tables if this is /// `None`. - pub position: Option<Linear>, + pub offset: Option<Linear>, /// Amount that the line will be longer or shorter than its associated text. pub extent: Linear, - /// Color of the line. Will default to text color if `None`. - pub fill: Option<Fill>, } /// Font family definitions. diff --git a/src/layout/shaping.rs b/src/layout/shaping.rs index 2496aae0..c37300f7 100644 --- a/src/layout/shaping.rs +++ b/src/layout/shaping.rs @@ -396,23 +396,24 @@ fn decorate( let mut apply = |substate: &LineState, metrics: fn(&Face) -> &LineMetrics| { let metrics = metrics(&ctx.cache.font.get(face_id)); - let strength = substate - .strength + let stroke = substate.stroke.unwrap_or(state.fill); + + let thickness = substate + .thickness .map(|s| s.resolve(state.size)) .unwrap_or(metrics.strength.to_length(state.size)); - let position = substate - .position + let offset = substate + .offset .map(|s| s.resolve(state.size)) - .unwrap_or(metrics.position.to_length(state.size)); + .unwrap_or(-metrics.position.to_length(state.size)); let extent = substate.extent.resolve(state.size); - let fill = substate.fill.unwrap_or(state.fill); - let pos = Point::new(pos.x - extent, pos.y - position); + let pos = Point::new(pos.x - extent, pos.y + offset); let target = Point::new(width + 2.0 * extent, Length::zero()); - let shape = Shape::Line(target, strength); - let element = Element::Geometry(shape, fill); + let shape = Shape::Line(target, thickness); + let element = Element::Geometry(shape, stroke); frame.push(pos, element); }; diff --git a/src/library/text.rs b/src/library/text.rs index bf0d49a4..9c2863bc 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -6,14 +6,20 @@ use super::*; /// `font`: Configure the font. pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { - let list = args.named(ctx, "family"); - let size = args.named::<Linear>(ctx, "size"); + let families = args.all(ctx); + let list = if families.is_empty() { + args.named(ctx, "family") + } else { + Some(FontDef(families)) + }; + + let size = args.eat(ctx).or_else(|| args.named::<Linear>(ctx, "size")); let style = args.named(ctx, "style"); let weight = args.named(ctx, "weight"); let stretch = args.named(ctx, "stretch"); let top_edge = args.named(ctx, "top-edge"); let bottom_edge = args.named(ctx, "bottom-edge"); - let color = args.named(ctx, "color"); + let fill = args.named(ctx, "fill"); let serif = args.named(ctx, "serif"); let sans_serif = args.named(ctx, "sans-serif"); let monospace = args.named(ctx, "monospace"); @@ -50,8 +56,8 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { font.bottom_edge = bottom_edge; } - if let Some(color) = color { - font.fill = Fill::Color(color); + if let Some(fill) = fill { + font.fill = Fill::Color(fill); } if let Some(FamilyDef(serif)) = &serif { @@ -229,19 +235,19 @@ fn line_impl( args: &mut FuncArgs, substate: fn(&mut FontState) -> &mut Option<Rc<LineState>>, ) -> Value { - let color = args.named(ctx, "color"); - let position = args.named(ctx, "position"); - let strength = args.named::<Linear>(ctx, "strength"); + let stroke = args.eat(ctx).or_else(|| args.named(ctx, "stroke")); + let thickness = args.eat(ctx).or_else(|| args.named::<Linear>(ctx, "thickness")); + let offset = args.named(ctx, "offset"); let extent = args.named(ctx, "extent").unwrap_or_default(); let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default(); // Suppress any existing strikethrough if strength is explicitly zero. - let state = strength.map_or(true, |s| !s.is_zero()).then(|| { + let state = thickness.map_or(true, |s| !s.is_zero()).then(|| { Rc::new(LineState { - strength, - position, + stroke: stroke.map(Fill::Color), + thickness, + offset, extent, - fill: color.map(Fill::Color), }) }); |
