diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-12-05 12:54:03 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-12-05 12:54:03 +0100 |
| commit | 26bdc1f0f6fe8113d7fcfb4d5aca46aa5238ccd8 (patch) | |
| tree | 4c12a187032501735d858648a64fe66603f106a6 /src/library | |
| parent | 738ff7e1f573bef678932b313be9969a17af8d22 (diff) | |
Set Rules Episode I: The Phantom Style
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/align.rs | 11 | ||||
| -rw-r--r-- | src/library/deco.rs | 11 | ||||
| -rw-r--r-- | src/library/document.rs | 7 | ||||
| -rw-r--r-- | src/library/flow.rs | 39 | ||||
| -rw-r--r-- | src/library/grid.rs | 11 | ||||
| -rw-r--r-- | src/library/image.rs | 6 | ||||
| -rw-r--r-- | src/library/mod.rs | 2 | ||||
| -rw-r--r-- | src/library/pad.rs | 6 | ||||
| -rw-r--r-- | src/library/page.rs | 99 | ||||
| -rw-r--r-- | src/library/par.rs | 66 | ||||
| -rw-r--r-- | src/library/placed.rs | 10 | ||||
| -rw-r--r-- | src/library/shape.rs | 12 | ||||
| -rw-r--r-- | src/library/sized.rs | 14 | ||||
| -rw-r--r-- | src/library/spacing.rs | 14 | ||||
| -rw-r--r-- | src/library/stack.rs | 44 | ||||
| -rw-r--r-- | src/library/text.rs | 70 | ||||
| -rw-r--r-- | src/library/transform.rs | 9 |
17 files changed, 185 insertions, 246 deletions
diff --git a/src/library/align.rs b/src/library/align.rs index 18920369..e2e7addb 100644 --- a/src/library/align.rs +++ b/src/library/align.rs @@ -15,15 +15,10 @@ pub fn align(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { } let aligns = args.expect::<Spec<_>>("alignment")?; - let body = args.expect::<Template>("body")?; - Ok(Value::Template(Template::from_block(move |style| { - let mut style = style.clone(); - if let Some(x) = aligns.x { - style.par_mut().align = x; - } + let body = args.expect::<Node>("body")?; - body.pack(&style).aligned(aligns) - }))) + // TODO(set): Style paragraphs with x alignment. + Ok(Value::block(body.into_block().aligned(aligns))) } /// A node that aligns its child. diff --git a/src/library/deco.rs b/src/library/deco.rs index cb065689..3576e8fe 100644 --- a/src/library/deco.rs +++ b/src/library/deco.rs @@ -21,8 +21,8 @@ fn line_impl(args: &mut Args, kind: LineKind) -> TypResult<Value> { let thickness = args.named::<Linear>("thickness")?.or_else(|| args.find()); let offset = args.named("offset")?; let extent = args.named("extent")?.unwrap_or_default(); - let body: Template = args.expect("body")?; - Ok(Value::Template(body.decorate(Decoration::Line( + let body: Node = args.expect("body")?; + Ok(Value::Node(body.decorate(Decoration::Line( LineDecoration { kind, stroke, thickness, offset, extent }, )))) } @@ -31,12 +31,9 @@ fn line_impl(args: &mut Args, kind: LineKind) -> TypResult<Value> { pub fn link(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let url = args.expect::<EcoString>("url")?; let body = args.find().unwrap_or_else(|| { - let mut template = Template::new(); - template.text(url.trim_start_matches("mailto:").trim_start_matches("tel:")); - template + Node::Text(url.trim_start_matches("mailto:").trim_start_matches("tel:").into()) }); - - Ok(Value::Template(body.decorate(Decoration::Link(url)))) + Ok(Value::Node(body.decorate(Decoration::Link(url)))) } /// A decoration for a frame. diff --git a/src/library/document.rs b/src/library/document.rs index fe01d2df..b9a00f9b 100644 --- a/src/library/document.rs +++ b/src/library/document.rs @@ -3,14 +3,11 @@ use super::PageNode; /// The root layout node, a document consisting of top-level page runs. #[derive(Debug, Hash)] -pub struct DocumentNode { - /// The page runs. - pub pages: Vec<PageNode>, -} +pub struct DocumentNode(pub Vec<PageNode>); impl DocumentNode { /// Layout the document into a sequence of frames, one per page. pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> { - self.pages.iter().flat_map(|node| node.layout(ctx)).collect() + self.0.iter().flat_map(|node| node.layout(ctx)).collect() } } diff --git a/src/library/flow.rs b/src/library/flow.rs index 98b518b7..dddd38a4 100644 --- a/src/library/flow.rs +++ b/src/library/flow.rs @@ -1,13 +1,13 @@ use std::fmt::{self, Debug, Formatter}; use super::prelude::*; -use super::{AlignNode, ParNode, PlacedNode, Spacing}; +use super::{AlignNode, PlacedNode, Spacing}; /// `flow`: A vertical flow of paragraphs and other layout nodes. pub fn flow(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { enum Child { Spacing(Spacing), - Any(Template), + Any(Node), } castable! { @@ -17,22 +17,18 @@ pub fn flow(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { Value::Relative(v) => Self::Spacing(Spacing::Linear(v.into())), Value::Linear(v) => Self::Spacing(Spacing::Linear(v)), Value::Fractional(v) => Self::Spacing(Spacing::Fractional(v)), - Value::Template(v) => Self::Any(v), + Value::Node(v) => Self::Any(v), } - let children: Vec<Child> = args.all().collect(); + let children = args + .all() + .map(|child| match child { + Child::Spacing(spacing) => FlowChild::Spacing(spacing), + Child::Any(node) => FlowChild::Node(node.into_block()), + }) + .collect(); - Ok(Value::Template(Template::from_block(move |style| { - let children = children - .iter() - .map(|child| match child { - Child::Spacing(spacing) => FlowChild::Spacing(*spacing), - Child::Any(node) => FlowChild::Node(node.pack(style)), - }) - .collect(); - - FlowNode { children } - }))) + Ok(Value::block(FlowNode(children))) } /// A vertical flow of content consisting of paragraphs and other layout nodes. @@ -40,11 +36,7 @@ pub fn flow(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { /// This node is reponsible for layouting both the top-level content flow and /// the contents of boxes. #[derive(Debug, Hash)] -pub struct FlowNode { - /// The children that compose the flow. There are different kinds of - /// children for different purposes. - pub children: Vec<FlowChild>, -} +pub struct FlowNode(pub Vec<FlowChild>); impl Layout for FlowNode { fn layout( @@ -118,7 +110,7 @@ impl<'a> FlowLayouter<'a> { regions.expand.y = false; Self { - children: &flow.children, + children: &flow.0, expand, full, regions, @@ -175,9 +167,8 @@ impl<'a> FlowLayouter<'a> { } let aligns = Spec::new( - // For non-expanding paragraphs it is crucial that we align the - // whole paragraph according to its internal alignment. - node.downcast::<ParNode>().map_or(Align::Left, |par| par.align), + // TODO(set): Align paragraph according to its internal alignment. + Align::Left, // Vertical align node alignment is respected by the flow node. node.downcast::<AlignNode>() .and_then(|aligned| aligned.aligns.y) diff --git a/src/library/grid.rs b/src/library/grid.rs index 7a9d88c3..ba4ce11f 100644 --- a/src/library/grid.rs +++ b/src/library/grid.rs @@ -39,15 +39,8 @@ pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { row_gutter.unwrap_or(base_gutter), ); - let children: Vec<Template> = args.all().collect(); - - Ok(Value::Template(Template::from_block(move |style| { - GridNode { - tracks: tracks.clone(), - gutter: gutter.clone(), - children: children.iter().map(|child| child.pack(style)).collect(), - } - }))) + let children = args.all().map(Node::into_block).collect(); + Ok(Value::block(GridNode { tracks, gutter, children })) } /// A node that arranges its children in a grid. diff --git a/src/library/image.rs b/src/library/image.rs index 08ed5069..562574f9 100644 --- a/src/library/image.rs +++ b/src/library/image.rs @@ -20,9 +20,9 @@ pub fn image(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { }) })?; - Ok(Value::Template(Template::from_inline(move |_| { - ImageNode { id, fit }.pack().sized(Spec::new(width, height)) - }))) + Ok(Value::inline( + ImageNode { id, fit }.pack().sized(Spec::new(width, height)), + )) } /// An image node. diff --git a/src/library/mod.rs b/src/library/mod.rs index d60a13ea..e1988635 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -26,7 +26,7 @@ mod prelude { pub use std::rc::Rc; pub use crate::diag::{At, TypResult}; - pub use crate::eval::{Args, EvalContext, Smart, Template, Value}; + pub use crate::eval::{Args, EvalContext, Node, Smart, Value}; pub use crate::frame::*; pub use crate::geom::*; pub use crate::layout::*; diff --git a/src/library/pad.rs b/src/library/pad.rs index 681da73e..75fea2e5 100644 --- a/src/library/pad.rs +++ b/src/library/pad.rs @@ -7,7 +7,7 @@ pub fn pad(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let top = args.named("top")?; let right = args.named("right")?; let bottom = args.named("bottom")?; - let body: Template = args.expect("body")?; + let body: Node = args.expect("body")?; let padding = Sides::new( left.or(all).unwrap_or_default(), top.or(all).unwrap_or_default(), @@ -15,9 +15,7 @@ pub fn pad(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { bottom.or(all).unwrap_or_default(), ); - Ok(Value::Template(Template::from_block(move |style| { - body.pack(style).padded(padding) - }))) + Ok(Value::block(body.into_block().padded(padding))) } /// A node that adds padding to its child. diff --git a/src/library/page.rs b/src/library/page.rs index 0d29ddb6..9def5400 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -1,4 +1,5 @@ use super::prelude::*; +use super::PadNode; use crate::style::{Paper, PaperClass}; /// `page`: Configure pages. @@ -20,90 +21,82 @@ pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let bottom = args.named("bottom")?; let fill = args.named("fill")?; - ctx.template.modify(move |style| { - let page = style.page_mut(); + let page = ctx.style.page_mut(); - if let Some(paper) = paper { - page.class = paper.class(); - page.size = paper.size(); - } - - if let Some(width) = width { - page.class = PaperClass::Custom; - page.size.x = width.unwrap_or(Length::inf()); - } + if let Some(paper) = paper { + page.class = paper.class(); + page.size = paper.size(); + } - if let Some(height) = height { - page.class = PaperClass::Custom; - page.size.y = height.unwrap_or(Length::inf()); - } + if let Some(width) = width { + page.class = PaperClass::Custom; + page.size.x = width.unwrap_or(Length::inf()); + } - if flip.unwrap_or(false) { - std::mem::swap(&mut page.size.x, &mut page.size.y); - } + if let Some(height) = height { + page.class = PaperClass::Custom; + page.size.y = height.unwrap_or(Length::inf()); + } - if let Some(margins) = margins { - page.margins = Sides::splat(margins); - } + if flip.unwrap_or(false) { + std::mem::swap(&mut page.size.x, &mut page.size.y); + } - if let Some(left) = left { - page.margins.left = left; - } + if let Some(margins) = margins { + page.margins = Sides::splat(margins); + } - if let Some(top) = top { - page.margins.top = top; - } + if let Some(left) = left { + page.margins.left = left; + } - if let Some(right) = right { - page.margins.right = right; - } + if let Some(top) = top { + page.margins.top = top; + } - if let Some(bottom) = bottom { - page.margins.bottom = bottom; - } + if let Some(right) = right { + page.margins.right = right; + } - if let Some(fill) = fill { - page.fill = fill; - } - }); + if let Some(bottom) = bottom { + page.margins.bottom = bottom; + } - ctx.template.pagebreak(false); + if let Some(fill) = fill { + page.fill = fill; + } Ok(Value::None) } /// `pagebreak`: Start a new page. pub fn pagebreak(_: &mut EvalContext, _: &mut Args) -> TypResult<Value> { - let mut template = Template::new(); - template.pagebreak(true); - Ok(Value::Template(template)) + Ok(Value::Node(Node::Pagebreak)) } /// Layouts its children onto one or multiple pages. #[derive(Debug, Hash)] -pub struct PageNode { - /// The size of the page. - pub size: Size, - /// The background fill. - pub fill: Option<Paint>, - /// The node that produces the actual pages. - pub child: PackedNode, -} +pub struct PageNode(pub PackedNode); impl PageNode { /// Layout the page run into a sequence of frames, one per page. pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> { + // TODO(set): Get style from styles. + let style = crate::style::PageStyle::default(); + // When one of the lengths is infinite the page fits its content along // that axis. - let expand = self.size.map(Length::is_finite); - let regions = Regions::repeat(self.size, self.size, expand); + let expand = style.size.map(Length::is_finite); + let regions = Regions::repeat(style.size, style.size, expand); // Layout the child. + let padding = style.margins(); + let padded = PadNode { child: self.0.clone(), padding }.pack(); let mut frames: Vec<_> = - self.child.layout(ctx, ®ions).into_iter().map(|c| c.item).collect(); + padded.layout(ctx, ®ions).into_iter().map(|c| c.item).collect(); // Add background fill if requested. - if let Some(fill) = self.fill { + if let Some(fill) = style.fill { for frame in &mut frames { let shape = Shape::filled(Geometry::Rect(frame.size), fill); Rc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape)); diff --git a/src/library/par.rs b/src/library/par.rs index 6abfa7af..6da1ee95 100644 --- a/src/library/par.rs +++ b/src/library/par.rs @@ -38,44 +38,31 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { align = Some(v); } - ctx.template.modify(move |style| { - let par = style.par_mut(); + let par = ctx.style.par_mut(); - if let Some(dir) = dir { - par.dir = dir; - par.align = if dir == Dir::LTR { Align::Left } else { Align::Right }; - } - - if let Some(align) = align { - par.align = align; - } + if let Some(dir) = dir { + par.dir = dir; + par.align = if dir == Dir::LTR { Align::Left } else { Align::Right }; + } - if let Some(leading) = leading { - par.leading = leading; - } + if let Some(align) = align { + par.align = align; + } - if let Some(spacing) = spacing { - par.spacing = spacing; - } - }); + if let Some(leading) = leading { + par.leading = leading; + } - ctx.template.parbreak(); + if let Some(spacing) = spacing { + par.spacing = spacing; + } Ok(Value::None) } /// A node that arranges its children into a paragraph. #[derive(Debug, Hash)] -pub struct ParNode { - /// The text direction (either LTR or RTL). - pub dir: Dir, - /// How to align text in its line. - pub align: Align, - /// The spacing to insert between each line. - pub leading: Length, - /// The children to be arranged in a paragraph. - pub children: Vec<ParChild>, -} +pub struct ParNode(pub Vec<ParChild>); impl Layout for ParNode { fn layout( @@ -87,11 +74,14 @@ impl Layout for ParNode { let text = self.collect_text(); // Find out the BiDi embedding levels. - let bidi = BidiInfo::new(&text, Level::from_dir(self.dir)); + // TODO(set): Get dir from styles. + let bidi = BidiInfo::new(&text, Level::from_dir(Dir::LTR)); // Prepare paragraph layout by building a representation on which we can // do line breaking without layouting each and every line from scratch. - let layouter = ParLayouter::new(self, ctx, regions, bidi); + // TODO(set): Get text style from styles. + let style = crate::style::TextStyle::default(); + let layouter = ParLayouter::new(self, ctx, regions, bidi, &style); // Find suitable linebreaks. layouter.layout(ctx, regions.clone()) @@ -123,7 +113,7 @@ impl ParNode { /// The string representation of each child. fn strings(&self) -> impl Iterator<Item = &str> { - self.children.iter().map(|child| match child { + self.0.iter().map(|child| match child { ParChild::Spacing(_) => " ", ParChild::Text(ref piece, ..) => piece, ParChild::Node(..) => "\u{FFFC}", @@ -138,7 +128,7 @@ pub enum ParChild { /// Spacing between other nodes. Spacing(Spacing), /// A run of text and how to align it in its line. - Text(EcoString, Rc<TextStyle>), + Text(EcoString), /// Any child node and how to align it in its line. Node(PackedNode), /// A decoration that applies until a matching `Undecorate`. @@ -151,7 +141,7 @@ impl Debug for ParChild { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Spacing(v) => write!(f, "Spacing({:?})", v), - Self::Text(text, _) => write!(f, "Text({:?})", text), + Self::Text(text) => write!(f, "Text({:?})", text), Self::Node(node) => node.fmt(f), Self::Decorate(deco) => write!(f, "Decorate({:?})", deco), Self::Undecorate => write!(f, "Undecorate"), @@ -198,6 +188,7 @@ impl<'a> ParLayouter<'a> { ctx: &mut LayoutContext, regions: &Regions, bidi: BidiInfo<'a>, + style: &'a TextStyle, ) -> Self { let mut items = vec![]; let mut ranges = vec![]; @@ -205,7 +196,7 @@ impl<'a> ParLayouter<'a> { let mut decos = vec![]; // Layout the children and collect them into items. - for (range, child) in par.ranges().zip(&par.children) { + for (range, child) in par.ranges().zip(&par.0) { match *child { ParChild::Spacing(Spacing::Linear(v)) => { let resolved = v.resolve(regions.current.x); @@ -216,7 +207,7 @@ impl<'a> ParLayouter<'a> { items.push(ParItem::Fractional(v)); ranges.push(range); } - ParChild::Text(_, ref style) => { + ParChild::Text(_) => { // TODO: Also split by language and script. let mut cursor = range.start; for (level, group) in bidi.levels[range].group_by_key(|&lvl| lvl) { @@ -252,8 +243,9 @@ impl<'a> ParLayouter<'a> { } Self { - align: par.align, - leading: par.leading, + // TODO(set): Get alignment and leading from styles. + align: Align::Left, + leading: Length::pt(6.0), bidi, items, ranges, diff --git a/src/library/placed.rs b/src/library/placed.rs index 722e0035..ce76a969 100644 --- a/src/library/placed.rs +++ b/src/library/placed.rs @@ -6,12 +6,10 @@ pub fn place(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let aligns = args.find().unwrap_or(Spec::new(Some(Align::Left), None)); let tx = args.named("dx")?.unwrap_or_default(); let ty = args.named("dy")?.unwrap_or_default(); - let body: Template = args.expect("body")?; - Ok(Value::Template(Template::from_block(move |style| { - PlacedNode { - child: body.pack(style).moved(Point::new(tx, ty)).aligned(aligns), - } - }))) + let body: Node = args.expect("body")?; + Ok(Value::block(PlacedNode { + child: body.into_block().moved(Point::new(tx, ty)).aligned(aligns), + })) } /// A node that places its child absolutely. diff --git a/src/library/shape.rs b/src/library/shape.rs index 61c0d6e3..c83a1c49 100644 --- a/src/library/shape.rs +++ b/src/library/shape.rs @@ -76,20 +76,18 @@ fn shape_impl( } // The shape's contents. - let body = args.find::<Template>(); + let body = args.find::<Node>(); - Ok(Value::Template(Template::from_inline(move |style| { + Ok(Value::inline( ShapeNode { kind, fill, stroke, - child: body - .as_ref() - .map(|body| body.pack(style).padded(Sides::splat(padding))), + child: body.map(|body| body.into_block().padded(Sides::splat(padding))), } .pack() - .sized(Spec::new(width, height)) - }))) + .sized(Spec::new(width, height)), + )) } /// Places its child into a sizable and fillable shape. diff --git a/src/library/sized.rs b/src/library/sized.rs index dfdc721d..6d677ca8 100644 --- a/src/library/sized.rs +++ b/src/library/sized.rs @@ -4,18 +4,16 @@ use super::prelude::*; pub fn box_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let width = args.named("width")?; let height = args.named("height")?; - let body: Template = args.find().unwrap_or_default(); - Ok(Value::Template(Template::from_inline(move |style| { - body.pack(style).sized(Spec::new(width, height)) - }))) + let body: Node = args.find().unwrap_or_default(); + Ok(Value::inline( + body.into_block().sized(Spec::new(width, height)), + )) } /// `block`: Place content into the flow. pub fn block(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { - let body: Template = args.find().unwrap_or_default(); - Ok(Value::Template(Template::from_block(move |style| { - body.pack(style) - }))) + let body: Node = args.find().unwrap_or_default(); + Ok(Value::block(body.into_block())) } /// A node that sizes its child. diff --git a/src/library/spacing.rs b/src/library/spacing.rs index 59911dc7..f5de8359 100644 --- a/src/library/spacing.rs +++ b/src/library/spacing.rs @@ -2,16 +2,18 @@ use super::prelude::*; /// `h`: Horizontal spacing. pub fn h(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { - let mut template = Template::new(); - template.spacing(SpecAxis::Horizontal, args.expect("spacing")?); - Ok(Value::Template(template)) + Ok(Value::Node(Node::Spacing( + SpecAxis::Horizontal, + args.expect("spacing")?, + ))) } /// `v`: Vertical spacing. pub fn v(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { - let mut template = Template::new(); - template.spacing(SpecAxis::Vertical, args.expect("spacing")?); - Ok(Value::Template(template)) + Ok(Value::Node(Node::Spacing( + SpecAxis::Vertical, + args.expect("spacing")?, + ))) } /// Kinds of spacing. diff --git a/src/library/stack.rs b/src/library/stack.rs index 2b1371ab..606632af 100644 --- a/src/library/stack.rs +++ b/src/library/stack.rs @@ -7,7 +7,7 @@ use super::{AlignNode, Spacing}; pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { enum Child { Spacing(Spacing), - Any(Template), + Any(Node), } castable! { @@ -17,38 +17,34 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { Value::Relative(v) => Self::Spacing(Spacing::Linear(v.into())), Value::Linear(v) => Self::Spacing(Spacing::Linear(v)), Value::Fractional(v) => Self::Spacing(Spacing::Fractional(v)), - Value::Template(v) => Self::Any(v), + Value::Node(v) => Self::Any(v), } let dir = args.named("dir")?.unwrap_or(Dir::TTB); let spacing = args.named("spacing")?; - let list: Vec<Child> = args.all().collect(); - - Ok(Value::Template(Template::from_block(move |style| { - let mut children = vec![]; - let mut delayed = None; - - // Build the list of stack children. - for child in &list { - match child { - Child::Spacing(v) => { - children.push(StackChild::Spacing(*v)); - delayed = None; - } - Child::Any(child) => { - if let Some(v) = delayed { - children.push(StackChild::Spacing(v)); - } - let node = child.pack(style); - children.push(StackChild::Node(node)); - delayed = spacing; + let mut children = vec![]; + let mut delayed = None; + + // Build the list of stack children. + for child in args.all() { + match child { + Child::Spacing(v) => { + children.push(StackChild::Spacing(v)); + delayed = None; + } + Child::Any(child) => { + if let Some(v) = delayed { + children.push(StackChild::Spacing(v)); } + + children.push(StackChild::Node(child.into_block())); + delayed = spacing; } } + } - StackNode { dir, children } - }))) + Ok(Value::block(StackNode { dir, children })) } /// A node that stacks its children. diff --git a/src/library/text.rs b/src/library/text.rs index 0790196d..d96f7666 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -12,8 +12,8 @@ use crate::font::{ }; use crate::geom::{Dir, Em, Length, Point, Size}; use crate::style::{ - FontFamily, FontFeatures, NumberPosition, NumberType, NumberWidth, Style, - StylisticSet, TextStyle, + FontFamily, FontFeatures, NumberPosition, NumberType, NumberWidth, StylisticSet, + TextStyle, }; use crate::util::{EcoString, SliceExt}; @@ -179,7 +179,6 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let slashed_zero = args.named("slashed-zero")?; let fractions = args.named("fractions")?; let features = args.named("features")?; - let body = args.find::<Template>(); macro_rules! set { ($target:expr => $source:expr) => { @@ -189,42 +188,35 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { }; } - let f = move |style_: &mut Style| { - let text = style_.text_mut(); - set!(text.families_mut().list => list.clone()); - set!(text.families_mut().serif => serif.clone()); - set!(text.families_mut().sans_serif => sans_serif.clone()); - set!(text.families_mut().monospace => monospace.clone()); - set!(text.fallback => fallback); - set!(text.variant.style => style); - set!(text.variant.weight => weight); - set!(text.variant.stretch => stretch); - set!(text.size => size.map(|v| v.resolve(text.size))); - set!(text.tracking => tracking); - set!(text.top_edge => top_edge); - set!(text.bottom_edge => bottom_edge); - set!(text.fill => fill); - set!(text.features_mut().kerning => kerning); - set!(text.features_mut().smallcaps => smallcaps); - set!(text.features_mut().alternates => alternates); - set!(text.features_mut().stylistic_set => stylistic_set); - set!(text.features_mut().ligatures.standard => ligatures); - set!(text.features_mut().ligatures.discretionary => discretionary_ligatures); - set!(text.features_mut().ligatures.historical => historical_ligatures); - set!(text.features_mut().numbers.type_ => number_type); - set!(text.features_mut().numbers.width => number_width); - set!(text.features_mut().numbers.position => number_position); - set!(text.features_mut().numbers.slashed_zero => slashed_zero); - set!(text.features_mut().numbers.fractions => fractions); - set!(text.features_mut().raw => features.clone()); - }; - - Ok(if let Some(body) = body { - Value::Template(body.modified(f)) - } else { - ctx.template.modify(f); - Value::None - }) + let text = ctx.style.text_mut(); + set!(text.families_mut().list => list.clone()); + set!(text.families_mut().serif => serif.clone()); + set!(text.families_mut().sans_serif => sans_serif.clone()); + set!(text.families_mut().monospace => monospace.clone()); + set!(text.fallback => fallback); + set!(text.variant.style => style); + set!(text.variant.weight => weight); + set!(text.variant.stretch => stretch); + set!(text.size => size.map(|v| v.resolve(text.size))); + set!(text.tracking => tracking); + set!(text.top_edge => top_edge); + set!(text.bottom_edge => bottom_edge); + set!(text.fill => fill); + set!(text.features_mut().kerning => kerning); + set!(text.features_mut().smallcaps => smallcaps); + set!(text.features_mut().alternates => alternates); + set!(text.features_mut().stylistic_set => stylistic_set); + set!(text.features_mut().ligatures.standard => ligatures); + set!(text.features_mut().ligatures.discretionary => discretionary_ligatures); + set!(text.features_mut().ligatures.historical => historical_ligatures); + set!(text.features_mut().numbers.type_ => number_type); + set!(text.features_mut().numbers.width => number_width); + set!(text.features_mut().numbers.position => number_position); + set!(text.features_mut().numbers.slashed_zero => slashed_zero); + set!(text.features_mut().numbers.fractions => fractions); + set!(text.features_mut().raw => features.clone()); + + Ok(Value::None) } /// Shape text into [`ShapedText`]. diff --git a/src/library/transform.rs b/src/library/transform.rs index 9ba71ecf..1b30c5b0 100644 --- a/src/library/transform.rs +++ b/src/library/transform.rs @@ -26,15 +26,14 @@ pub fn rotate(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> { } fn transform_impl(args: &mut Args, transform: Transform) -> TypResult<Value> { - let body: Template = args.expect("body")?; + let body: Node = args.expect("body")?; let origin = args .named("origin")? .unwrap_or(Spec::splat(None)) .unwrap_or(Align::CENTER_HORIZON); - - Ok(Value::Template(Template::from_inline(move |style| { - body.pack(style).transformed(transform, origin) - }))) + Ok(Value::inline( + body.into_block().transformed(transform, origin), + )) } /// A node that transforms its child without affecting layout. |
