diff options
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/graphics/transform.rs | 5 | ||||
| -rw-r--r-- | src/library/layout/align.rs | 28 | ||||
| -rw-r--r-- | src/library/layout/flow.rs | 5 | ||||
| -rw-r--r-- | src/library/layout/place.rs | 2 | ||||
| -rw-r--r-- | src/library/layout/stack.rs | 3 | ||||
| -rw-r--r-- | src/library/mod.rs | 33 | ||||
| -rw-r--r-- | src/library/prelude.rs | 3 | ||||
| -rw-r--r-- | src/library/text/par.rs | 21 |
8 files changed, 54 insertions, 46 deletions
diff --git a/src/library/graphics/transform.rs b/src/library/graphics/transform.rs index eb419a7e..67f9cad9 100644 --- a/src/library/graphics/transform.rs +++ b/src/library/graphics/transform.rs @@ -22,7 +22,8 @@ pub type ScaleNode = TransformNode<SCALE>; #[node] impl<const T: TransformKind> TransformNode<T> { /// The origin of the transformation. - pub const ORIGIN: Spec<Option<Align>> = Spec::default(); + #[property(resolve)] + pub const ORIGIN: Spec<Option<RawAlign>> = Spec::default(); fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { let transform = match T { @@ -61,7 +62,7 @@ impl<const T: TransformKind> Layout for TransformNode<T> { let mut frames = self.child.layout(ctx, regions, styles)?; for frame in &mut frames { - let Spec { x, y } = origin.zip(frame.size).map(|(o, s)| o.resolve(s)); + let Spec { x, y } = origin.zip(frame.size).map(|(o, s)| o.position(s)); let transform = Transform::translate(x, y) .pre_concat(self.transform) .pre_concat(Transform::translate(-x, -y)); diff --git a/src/library/layout/align.rs b/src/library/layout/align.rs index b08e5fce..699a908c 100644 --- a/src/library/layout/align.rs +++ b/src/library/layout/align.rs @@ -5,7 +5,7 @@ use crate::library::text::ParNode; #[derive(Debug, Hash)] pub struct AlignNode { /// How to align the node horizontally and vertically. - pub aligns: Spec<Option<Align>>, + pub aligns: Spec<Option<RawAlign>>, /// The node to be aligned. pub child: LayoutNode, } @@ -42,30 +42,14 @@ impl Layout for AlignNode { // Align in the target size. The target size depends on whether we // should expand. let target = regions.expand.select(region, frame.size); - let default = Spec::new(Align::Left, Align::Top); - let aligns = self.aligns.unwrap_or(default); + let aligns = self + .aligns + .map(|align| align.resolve(styles)) + .unwrap_or(Spec::new(Align::Left, Align::Top)); + Arc::make_mut(frame).resize(target, aligns); } Ok(frames) } } - -dynamic! { - Align: "alignment", -} - -dynamic! { - Spec<Align>: "2d alignment", -} - -castable! { - Spec<Option<Align>>, - Expected: "1d or 2d alignment", - @align: Align => { - let mut aligns = Spec::default(); - aligns.set(align.axis(), Some(*align)); - aligns - }, - @aligns: Spec<Align> => aligns.map(Some), -} diff --git a/src/library/layout/flow.rs b/src/library/layout/flow.rs index ffda6925..a53b0304 100644 --- a/src/library/layout/flow.rs +++ b/src/library/layout/flow.rs @@ -189,6 +189,7 @@ impl FlowLayouter { // Vertical align node alignment is respected by the flow node. node.downcast::<AlignNode>() .and_then(|aligned| aligned.aligns.y) + .map(|align| align.resolve(styles)) .unwrap_or(Align::Top), ); @@ -238,8 +239,8 @@ impl FlowLayouter { } FlowItem::Frame(frame, aligns) => { ruler = ruler.max(aligns.y); - let x = aligns.x.resolve(size.x - frame.size.x); - let y = offset + ruler.resolve(size.y - self.used.y); + let x = aligns.x.position(size.x - frame.size.x); + let y = offset + ruler.position(size.y - self.used.y); let pos = Point::new(x, y); offset += frame.size.y; output.push_frame(pos, frame); diff --git a/src/library/layout/place.rs b/src/library/layout/place.rs index 2d4ebc4d..eefa6a9b 100644 --- a/src/library/layout/place.rs +++ b/src/library/layout/place.rs @@ -8,9 +8,9 @@ pub struct PlaceNode(pub LayoutNode); #[node] impl PlaceNode { fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { - let aligns = args.find()?.unwrap_or(Spec::with_x(Some(Align::Left))); let tx = args.named("dx")?.unwrap_or_default(); let ty = args.named("dy")?.unwrap_or_default(); + let aligns = args.find()?.unwrap_or(Spec::with_x(Some(RawAlign::Start))); let body: LayoutNode = args.expect("body")?; Ok(Content::block(Self( body.moved(Point::new(tx, ty)).aligned(aligns), diff --git a/src/library/layout/stack.rs b/src/library/layout/stack.rs index b0e2e160..312757f3 100644 --- a/src/library/layout/stack.rs +++ b/src/library/layout/stack.rs @@ -175,6 +175,7 @@ impl StackLayouter { let align = node .downcast::<AlignNode>() .and_then(|node| node.aligns.get(self.axis)) + .map(|align| align.resolve(styles)) .unwrap_or(self.dir.start().into()); let frames = node.layout(ctx, &self.regions, styles)?; @@ -229,7 +230,7 @@ impl StackLayouter { // Align along the block axis. let parent = size.get(self.axis); let child = frame.size.get(self.axis); - let block = ruler.resolve(parent - self.used.main) + let block = ruler.position(parent - self.used.main) + if self.dir.is_positive() { cursor } else { diff --git a/src/library/mod.rs b/src/library/mod.rs index 7c5a519f..358c2204 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -113,12 +113,14 @@ pub fn new() -> Scope { std.def_const("rtl", Dir::RTL); std.def_const("ttb", Dir::TTB); std.def_const("btt", Dir::BTT); - std.def_const("left", Align::Left); - std.def_const("center", Align::Center); - std.def_const("right", Align::Right); - std.def_const("top", Align::Top); - std.def_const("horizon", Align::Horizon); - std.def_const("bottom", Align::Bottom); + std.def_const("start", RawAlign::Start); + std.def_const("end", RawAlign::End); + std.def_const("left", RawAlign::Specific(Align::Left)); + std.def_const("center", RawAlign::Specific(Align::Center)); + std.def_const("right", RawAlign::Specific(Align::Right)); + std.def_const("top", RawAlign::Specific(Align::Top)); + std.def_const("horizon", RawAlign::Specific(Align::Horizon)); + std.def_const("bottom", RawAlign::Specific(Align::Bottom)); std } @@ -127,6 +129,25 @@ 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", diff --git a/src/library/prelude.rs b/src/library/prelude.rs index a2e296fa..f052a43a 100644 --- a/src/library/prelude.rs +++ b/src/library/prelude.rs @@ -10,7 +10,8 @@ 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, Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value, + Node, RawAlign, Regions, Resolve, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, + StyleVec, Value, }; pub use crate::frame::*; pub use crate::geom::*; diff --git a/src/library/text/par.rs b/src/library/text/par.rs index 2d31cd11..dc7c9dcf 100644 --- a/src/library/text/par.rs +++ b/src/library/text/par.rs @@ -33,7 +33,8 @@ impl ParNode { /// The direction for text and inline objects. pub const DIR: Dir = Dir::LTR; /// How to align text and inline objects in their line. - pub const ALIGN: Align = Align::Left; + #[property(resolve)] + pub const ALIGN: RawAlign = RawAlign::Start; /// Whether to justify text in its line. pub const JUSTIFY: bool = false; /// How to determine line breaks. @@ -74,15 +75,13 @@ impl ParNode { dir = Some(v); } - let align = - if let Some(Spanned { v, span }) = args.named::<Spanned<Align>>("align")? { - if v.axis() != SpecAxis::Horizontal { - bail!(span, "must be horizontal"); - } - Some(v) - } else { - dir.map(|dir| dir.start().into()) - }; + let mut align = None; + if let Some(Spanned { v, span }) = args.named::<Spanned<RawAlign>>("align")? { + if v.axis() != SpecAxis::Horizontal { + bail!(span, "must be horizontal"); + } + align = Some(v); + }; styles.set_opt(Self::LANG, lang); styles.set_opt(Self::DIR, dir); @@ -880,7 +879,7 @@ fn commit( // Construct the line's frame from left to right. for item in reordered { let mut position = |frame: Frame| { - let x = offset + align.resolve(remaining); + let x = offset + align.position(remaining); let y = line.baseline - frame.baseline(); offset += frame.size.x; output.merge_frame(Point::new(x, y), frame); |
