diff --git a/crates/typst/src/eval/ops.rs b/crates/typst/src/eval/ops.rs index b4803ab4b..76456afe4 100644 --- a/crates/typst/src/eval/ops.rs +++ b/crates/typst/src/eval/ops.rs @@ -6,7 +6,7 @@ use ecow::eco_format; use crate::diag::{bail, At, SourceResult, StrResult}; use crate::eval::{access_dict, Access, Eval, Vm}; -use crate::foundations::{format_str, Datetime, IntoValue, Regex, Repr, Smart, Value}; +use crate::foundations::{format_str, Datetime, IntoValue, Regex, Repr, Value}; use crate::layout::{Align, Length, Rel}; use crate::syntax::ast::{self, AstNode}; use crate::text::TextElem; @@ -217,28 +217,15 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult { (Array(a), Array(b)) => Array(a + b), (Dict(a), Dict(b)) => Dict(a + b), - (Color(color), Length(thickness)) | (Length(thickness), Color(color)) => Stroke { - paint: Smart::Custom(color.into()), - thickness: Smart::Custom(thickness), - ..Stroke::default() + (Color(color), Length(thickness)) | (Length(thickness), Color(color)) => { + Stroke::from_pair(color, thickness).into_value() } - .into_value(), - (Gradient(gradient), Length(thickness)) - | (Length(thickness), Gradient(gradient)) => Stroke { - paint: Smart::Custom(gradient.into()), - thickness: Smart::Custom(thickness), - ..Stroke::default() + | (Length(thickness), Gradient(gradient)) => { + Stroke::from_pair(gradient, thickness).into_value() } - .into_value(), - (Pattern(pattern), Length(thickness)) | (Length(thickness), Pattern(pattern)) => { - Stroke { - paint: Smart::Custom(pattern.into()), - thickness: Smart::Custom(thickness), - ..Stroke::default() - } - .into_value() + Stroke::from_pair(pattern, thickness).into_value() } (Duration(a), Duration(b)) => Duration(a + b), diff --git a/crates/typst/src/layout/frame.rs b/crates/typst/src/layout/frame.rs index af1fd5d1a..40dbba8e0 100644 --- a/crates/typst/src/layout/frame.rs +++ b/crates/typst/src/layout/frame.rs @@ -384,11 +384,8 @@ impl Frame { 1, Point::with_y(self.baseline()), FrameItem::Shape( - Geometry::Line(Point::with_x(self.size.x)).stroked(FixedStroke { - paint: Color::RED.into(), - thickness: Abs::pt(1.0), - ..FixedStroke::default() - }), + Geometry::Line(Point::with_x(self.size.x)) + .stroked(FixedStroke::from_pair(Color::RED, Abs::pt(1.0))), Span::detached(), ), ); @@ -411,11 +408,8 @@ impl Frame { self.push( Point::with_y(y), FrameItem::Shape( - Geometry::Line(Point::with_x(self.size.x)).stroked(FixedStroke { - paint: Color::GREEN.into(), - thickness: Abs::pt(1.0), - ..FixedStroke::default() - }), + Geometry::Line(Point::with_x(self.size.x)) + .stroked(FixedStroke::from_pair(Color::GREEN, Abs::pt(1.0))), Span::detached(), ), ); diff --git a/crates/typst/src/math/frac.rs b/crates/typst/src/math/frac.rs index 4d0e5dc7d..b5ced71d9 100644 --- a/crates/typst/src/math/frac.rs +++ b/crates/typst/src/math/frac.rs @@ -152,11 +152,12 @@ fn layout( frame.push( line_pos, FrameItem::Shape( - Geometry::Line(Point::with_x(line_width)).stroked(FixedStroke { - paint: TextElem::fill_in(ctx.styles()).as_decoration(), - thickness, - ..FixedStroke::default() - }), + Geometry::Line(Point::with_x(line_width)).stroked( + FixedStroke::from_pair( + TextElem::fill_in(ctx.styles()).as_decoration(), + thickness, + ), + ), span, ), ); diff --git a/crates/typst/src/math/root.rs b/crates/typst/src/math/root.rs index 9a162b60e..badb8e864 100644 --- a/crates/typst/src/math/root.rs +++ b/crates/typst/src/math/root.rs @@ -131,11 +131,12 @@ fn layout( frame.push( line_pos, FrameItem::Shape( - Geometry::Line(Point::with_x(radicand.width())).stroked(FixedStroke { - paint: TextElem::fill_in(ctx.styles()).as_decoration(), - thickness, - ..FixedStroke::default() - }), + Geometry::Line(Point::with_x(radicand.width())).stroked( + FixedStroke::from_pair( + TextElem::fill_in(ctx.styles()).as_decoration(), + thickness, + ), + ), span, ), ); diff --git a/crates/typst/src/text/deco.rs b/crates/typst/src/text/deco.rs index bb85f54ef..4aced36d9 100644 --- a/crates/typst/src/text/deco.rs +++ b/crates/typst/src/text/deco.rs @@ -410,11 +410,10 @@ pub(crate) fn decorate( }; let offset = offset.unwrap_or(-metrics.position.at(text.size)) - shift; - let stroke = stroke.clone().unwrap_or(FixedStroke { - paint: text.fill.as_decoration(), - thickness: metrics.thickness.at(text.size), - ..FixedStroke::default() - }); + let stroke = stroke.clone().unwrap_or(FixedStroke::from_pair( + text.fill.as_decoration(), + metrics.thickness.at(text.size), + )); let gap_padding = 0.08 * text.size; let min_width = 0.162 * text.size; diff --git a/crates/typst/src/visualize/stroke.rs b/crates/typst/src/visualize/stroke.rs index 1761d087a..3686831d4 100644 --- a/crates/typst/src/visualize/stroke.rs +++ b/crates/typst/src/visualize/stroke.rs @@ -66,6 +66,17 @@ pub struct Stroke { pub miter_limit: Smart, } +impl Stroke { + /// Create a stroke from a paint and a thickness. + pub fn from_pair(paint: impl Into, thickness: Length) -> Self { + Self { + paint: Smart::Custom(paint.into()), + thickness: Smart::Custom(thickness), + ..Default::default() + } + } +} + #[scope] impl Stroke { /// Converts a value to a stroke or constructs a stroke with the given @@ -583,6 +594,17 @@ pub struct FixedStroke { pub miter_limit: Scalar, } +impl FixedStroke { + /// Create a stroke from a paint and a thickness. + pub fn from_pair(paint: impl Into, thickness: Abs) -> Self { + Self { + paint: paint.into(), + thickness, + ..Default::default() + } + } +} + impl Default for FixedStroke { fn default() -> Self { Self {