diff --git a/crates/typst-library/src/layout/flow.rs b/crates/typst-library/src/layout/flow.rs index 930857e75..4ce78c94e 100644 --- a/crates/typst-library/src/layout/flow.rs +++ b/crates/typst-library/src/layout/flow.rs @@ -134,6 +134,7 @@ enum FlowItem { frame: Frame, x_align: Align, y_align: Smart>, + delta: Axes>, float: bool, clearance: Abs, }, @@ -276,12 +277,13 @@ impl<'a> FlowLayouter<'a> { let float = placed.float(styles); let clearance = placed.clearance(styles); let alignment = placed.alignment(styles); + let delta = Axes::new(placed.dx(styles), placed.dy(styles)).resolve(styles); let x_align = alignment.map_or(Align::Center, |aligns| { aligns.x.unwrap_or(GenAlign::Start).resolve(styles) }); let y_align = alignment.map(|align| align.y.resolve(styles)); let frame = placed.layout(vt, styles, self.regions)?.into_frame(); - let item = FlowItem::Placed { frame, x_align, y_align, float, clearance }; + let item = FlowItem::Placed { frame, x_align, y_align, delta, float, clearance }; self.layout_item(vt, item) } @@ -508,7 +510,7 @@ impl<'a> FlowLayouter<'a> { offset += frame.height(); output.push_frame(pos, frame); } - FlowItem::Placed { frame, x_align, y_align, float, .. } => { + FlowItem::Placed { frame, x_align, y_align, delta, float, .. } => { let x = x_align.position(size.x - frame.width()); let y = if float { match y_align { @@ -534,7 +536,10 @@ impl<'a> FlowLayouter<'a> { } }; - output.push_frame(Point::new(x, y), frame); + let pos = Point::new(x, y) + + delta.zip(size).map(|(d, s)| d.relative_to(s)).to_point(); + + output.push_frame(pos, frame); } FlowItem::Footnote(frame) => { let y = size.y - footnote_height + footnote_offset; diff --git a/crates/typst-library/src/layout/place.rs b/crates/typst-library/src/layout/place.rs index 115e5107a..95c042ff4 100644 --- a/crates/typst-library/src/layout/place.rs +++ b/crates/typst-library/src/layout/place.rs @@ -115,12 +115,9 @@ impl Layout for PlaceElem { .at(self.span()); } - let child = self - .body() - .moved(Axes::new(self.dx(styles), self.dy(styles))) - .aligned( - alignment.unwrap_or_else(|| Axes::with_x(Some(Align::Center.into()))), - ); + let child = self.body().aligned( + alignment.unwrap_or_else(|| Axes::with_x(Some(Align::Center.into()))), + ); let pod = Regions::one(base, Axes::splat(false)); let frame = child.layout(vt, styles, pod)?.into_frame(); diff --git a/tests/ref/layout/place-nested.png b/tests/ref/layout/place-nested.png index ccd55ee4d..864830d85 100644 Binary files a/tests/ref/layout/place-nested.png and b/tests/ref/layout/place-nested.png differ diff --git a/tests/typ/layout/place-nested.typ b/tests/typ/layout/place-nested.typ index c979176a7..93006ff5e 100644 --- a/tests/typ/layout/place-nested.typ +++ b/tests/typ/layout/place-nested.typ @@ -31,3 +31,10 @@ How are \ you? ] + +--- +#box(fill: aqua)[ + #place(top + left, dx: 50%, dy: 50%)[Hi] + #v(30pt) + #line(length: 50pt) +]