diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-04-08 17:08:30 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-04-09 12:02:35 +0200 |
| commit | 29eb13ca6214461a4b0deb63d589cd39ad6d41c2 (patch) | |
| tree | c86797d440cfcc801c87a3c64f479e39f2c068b1 /src/library | |
| parent | 712c00ecb72b67da2c0788e5d3eb4dcc6366b2a7 (diff) | |
Sum color and length into stroke
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/graphics/line.rs | 17 | ||||
| -rw-r--r-- | src/library/graphics/shape.rs | 15 | ||||
| -rw-r--r-- | src/library/mod.rs | 62 | ||||
| -rw-r--r-- | src/library/prelude.rs | 2 | ||||
| -rw-r--r-- | src/library/structure/table.rs | 10 | ||||
| -rw-r--r-- | src/library/text/deco.rs | 27 |
6 files changed, 26 insertions, 107 deletions
diff --git a/src/library/graphics/line.rs b/src/library/graphics/line.rs index 1dd138e6..de2e4aa1 100644 --- a/src/library/graphics/line.rs +++ b/src/library/graphics/line.rs @@ -12,10 +12,8 @@ pub struct LineNode { #[node] impl LineNode { /// How to stroke the line. - pub const STROKE: Paint = Color::BLACK.into(); - /// The line's thickness. - #[property(resolve)] - pub const THICKNESS: RawLength = Length::pt(1.0).into(); + #[property(resolve, fold)] + pub const STROKE: RawStroke = RawStroke::default(); fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { let origin = args.named("origin")?.unwrap_or_default(); @@ -46,11 +44,7 @@ impl Layout for LineNode { regions: &Regions, styles: StyleChain, ) -> TypResult<Vec<Arc<Frame>>> { - let thickness = styles.get(Self::THICKNESS); - let stroke = Some(Stroke { - paint: styles.get(Self::STROKE), - thickness, - }); + let stroke = styles.get(Self::STROKE).unwrap_or_default(); let origin = self .origin @@ -64,11 +58,10 @@ impl Layout for LineNode { .zip(regions.base) .map(|(l, b)| l.relative_to(b)); - let geometry = Geometry::Line(delta.to_point()); - let shape = Shape { geometry, fill: None, stroke }; - let target = regions.expand.select(regions.first, Size::zero()); let mut frame = Frame::new(target); + + let shape = Geometry::Line(delta.to_point()).stroked(stroke); frame.push(origin.to_point(), Element::Shape(shape)); Ok(vec![Arc::new(frame)]) diff --git a/src/library/graphics/shape.rs b/src/library/graphics/shape.rs index ec6f735b..a159a3af 100644 --- a/src/library/graphics/shape.rs +++ b/src/library/graphics/shape.rs @@ -24,10 +24,8 @@ impl<const S: ShapeKind> ShapeNode<S> { /// How to fill the shape. pub const FILL: Option<Paint> = None; /// How to stroke the shape. - pub const STROKE: Smart<Option<Paint>> = Smart::Auto; - /// The stroke's thickness. - #[property(resolve)] - pub const THICKNESS: RawLength = Length::pt(1.0).into(); + #[property(resolve, fold)] + pub const STROKE: Smart<Option<RawStroke>> = Smart::Auto; /// How much to pad the shape's content. pub const PADDING: Relative<RawLength> = Relative::zero(); @@ -115,11 +113,10 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> { // Add fill and/or stroke. let fill = styles.get(Self::FILL); - let thickness = styles.get(Self::THICKNESS); - let stroke = styles - .get(Self::STROKE) - .unwrap_or(fill.is_none().then(|| Color::BLACK.into())) - .map(|paint| Stroke { paint, thickness }); + let stroke = match styles.get(Self::STROKE) { + Smart::Auto => fill.is_none().then(Stroke::default), + Smart::Custom(stroke) => stroke.map(RawStroke::unwrap_or_default), + }; if fill.is_some() || stroke.is_some() { let geometry = if is_round(S) { diff --git a/src/library/mod.rs b/src/library/mod.rs index a5f0b50c..0034b581 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -124,65 +124,3 @@ pub fn new() -> Scope { std } - -dynamic! { - Dir: "direction", -} - -dynamic! { - RawAlign: "alignment", -} - -dynamic! { - Spec<RawAlign>: "2d alignment", -} - -castable! { - Spec<Option<RawAlign>>, - Expected: "1d or 2d alignment", - @align: RawAlign => { - let mut aligns = Spec::default(); - aligns.set(align.axis(), Some(*align)); - aligns - }, - @aligns: Spec<RawAlign> => aligns.map(Some), -} - -castable! { - usize, - Expected: "non-negative integer", - Value::Int(int) => int.try_into().map_err(|_| { - if int < 0 { - "must be at least zero" - } else { - "number too large" - } - })?, -} - -castable! { - NonZeroUsize, - Expected: "positive integer", - Value::Int(int) => Value::Int(int) - .cast::<usize>()? - .try_into() - .map_err(|_| "must be positive")?, -} - -castable! { - Paint, - Expected: "color", - Value::Color(color) => Paint::Solid(color), -} - -castable! { - String, - Expected: "string", - Value::Str(string) => string.into(), -} - -castable! { - LayoutNode, - Expected: "content", - Value::Content(content) => content.pack(), -} diff --git a/src/library/prelude.rs b/src/library/prelude.rs index d74a5d85..a1ebe6ef 100644 --- a/src/library/prelude.rs +++ b/src/library/prelude.rs @@ -10,7 +10,7 @@ pub use typst_macros::node; pub use crate::diag::{with_alternative, At, Error, StrResult, TypError, TypResult}; pub use crate::eval::{ Arg, Args, Array, Cast, Content, Dict, Fold, Func, Key, Layout, LayoutNode, Merge, - Node, RawAlign, RawLength, Regions, Resolve, Scope, Show, ShowNode, Smart, + Node, RawAlign, RawLength, RawStroke, Regions, Resolve, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value, }; pub use crate::frame::*; diff --git a/src/library/structure/table.rs b/src/library/structure/table.rs index d0ab0716..40f25749 100644 --- a/src/library/structure/table.rs +++ b/src/library/structure/table.rs @@ -19,10 +19,8 @@ impl TableNode { /// The secondary cell fill color. pub const SECONDARY: Option<Paint> = None; /// How to stroke the cells. - pub const STROKE: Option<Paint> = Some(Color::BLACK.into()); - /// The stroke's thickness. - #[property(resolve)] - pub const THICKNESS: RawLength = Length::pt(1.0).into(); + #[property(resolve, fold)] + pub const STROKE: Option<RawStroke> = Some(RawStroke::default()); /// How much to pad the cells's content. pub const PADDING: Relative<RawLength> = Length::pt(5.0).into(); @@ -48,7 +46,6 @@ impl TableNode { styles.set_opt(Self::PRIMARY, args.named("primary")?.or(fill)); styles.set_opt(Self::SECONDARY, args.named("secondary")?.or(fill)); styles.set_opt(Self::STROKE, args.named("stroke")?); - styles.set_opt(Self::THICKNESS, args.named("thickness")?); styles.set_opt(Self::PADDING, args.named("padding")?); Ok(styles) } @@ -63,8 +60,7 @@ impl Show for TableNode { let primary = styles.get(Self::PRIMARY); let secondary = styles.get(Self::SECONDARY); - let thickness = styles.get(Self::THICKNESS); - let stroke = styles.get(Self::STROKE).map(|paint| Stroke { paint, thickness }); + let stroke = styles.get(Self::STROKE).map(RawStroke::unwrap_or_default); let padding = styles.get(Self::PADDING); let cols = self.tracks.x.len().max(1); diff --git a/src/library/text/deco.rs b/src/library/text/deco.rs index f5ed4744..b8a0b3cb 100644 --- a/src/library/text/deco.rs +++ b/src/library/text/deco.rs @@ -20,12 +20,10 @@ pub type OverlineNode = DecoNode<OVERLINE>; #[node(showable)] impl<const L: DecoLine> DecoNode<L> { - /// Stroke color of the line, defaults to the text color if `None`. - #[property(shorthand)] - pub const STROKE: Option<Paint> = None; - /// Thickness of the line's strokes, read from the font tables if `auto`. - #[property(shorthand, resolve)] - pub const THICKNESS: Smart<RawLength> = Smart::Auto; + /// How to stroke the line. The text color and thickness read from the font + /// tables if `auto`. + #[property(shorthand, resolve, fold)] + pub const STROKE: Smart<RawStroke> = Smart::Auto; /// Position of the line relative to the baseline, read from the font tables /// if `auto`. #[property(resolve)] @@ -49,8 +47,7 @@ impl<const L: DecoLine> Show for DecoNode<L> { .unwrap_or_else(|| { self.0.clone().styled(TextNode::DECO, Decoration { line: L, - stroke: styles.get(Self::STROKE), - thickness: styles.get(Self::THICKNESS), + stroke: styles.get(Self::STROKE).unwrap_or_default(), offset: styles.get(Self::OFFSET), extent: styles.get(Self::EXTENT), evade: styles.get(Self::EVADE), @@ -65,8 +62,7 @@ impl<const L: DecoLine> Show for DecoNode<L> { #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct Decoration { pub line: DecoLine, - pub stroke: Option<Paint>, - pub thickness: Smart<Length>, + pub stroke: RawStroke<Length>, pub offset: Smart<Length>, pub extent: Length, pub evade: bool, @@ -103,11 +99,10 @@ pub fn decorate( let evade = deco.evade && deco.line != STRIKETHROUGH; let offset = deco.offset.unwrap_or(-metrics.position.at(text.size)); - - let stroke = Stroke { - paint: deco.stroke.unwrap_or(text.fill), - thickness: deco.thickness.unwrap_or(metrics.thickness.at(text.size)), - }; + let stroke = deco.stroke.unwrap_or(Stroke { + paint: text.fill, + thickness: metrics.thickness.at(text.size), + }); let gap_padding = 0.08 * text.size; let min_width = 0.162 * text.size; @@ -120,7 +115,7 @@ pub fn decorate( let target = Point::new(to - from, Length::zero()); if target.x >= min_width || !evade { - let shape = Shape::stroked(Geometry::Line(target), stroke); + let shape = Geometry::Line(target).stroked(stroke); frame.push(origin, Element::Shape(shape)); } }; |
