summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-04-08 17:08:30 +0200
committerLaurenz <laurmaedje@gmail.com>2022-04-09 12:02:35 +0200
commit29eb13ca6214461a4b0deb63d589cd39ad6d41c2 (patch)
treec86797d440cfcc801c87a3c64f479e39f2c068b1 /src/library
parent712c00ecb72b67da2c0788e5d3eb4dcc6366b2a7 (diff)
Sum color and length into stroke
Diffstat (limited to 'src/library')
-rw-r--r--src/library/graphics/line.rs17
-rw-r--r--src/library/graphics/shape.rs15
-rw-r--r--src/library/mod.rs62
-rw-r--r--src/library/prelude.rs2
-rw-r--r--src/library/structure/table.rs10
-rw-r--r--src/library/text/deco.rs27
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));
}
};