diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index 38da78781..b9d7b03d5 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -302,21 +302,22 @@ impl PageElem { // Determine the margins. let default = Rel::from(0.1190 * min); - let padding = self.margin(styles).map(|side| side.unwrap_or(default)); - - let mut child = self.body(); + let margin = self + .margin(styles) + .map(|side| side.unwrap_or(default)) + .resolve(styles) + .relative_to(size); // Realize columns. + let mut child = self.body(); let columns = self.columns(styles); if columns.get() > 1 { child = ColumnsElem::new(child).with_count(columns).pack(); } - // Realize margins. - child = child.padded(padding); - // Layout the child. - let regions = Regions::repeat(size, size.map(Abs::is_finite)); + let area = size - margin.sum_by_axis(); + let regions = Regions::repeat(area, area.map(Abs::is_finite)); let mut fragment = child.layout(vt, styles, regions)?; let fill = self.fill(styles); @@ -342,13 +343,22 @@ impl PageElem { Size::zero(), ); - // Realize overlays. + // Post-process pages. for frame in fragment.iter_mut() { tracing::info!("Layouting page #{number}"); - frame.prepend(Point::zero(), numbering_meta.clone()); + + // The padded width of the page's content without margins. + let pw = frame.width(); + + // Realize margins. + frame.set_size(frame.size() + margin.sum_by_axis()); + frame.translate(Point::new(margin.left, margin.top)); + frame.push(Point::zero(), numbering_meta.clone()); + + // The page size with margins. let size = frame.size(); - let pad = padding.resolve(styles).relative_to(size); - let pw = size.x - pad.left - pad.right; + + // Realize overlays. for (name, marginal) in [ ("header", &header), ("footer", &footer), @@ -361,14 +371,14 @@ impl PageElem { let (pos, area, align); if ptr::eq(marginal, &header) { - let ascent = header_ascent.relative_to(pad.top); - pos = Point::with_x(pad.left); - area = Size::new(pw, pad.top - ascent); + let ascent = header_ascent.relative_to(margin.top); + pos = Point::with_x(margin.left); + area = Size::new(pw, margin.top - ascent); align = Align::Bottom.into(); } else if ptr::eq(marginal, &footer) { - let descent = footer_descent.relative_to(pad.bottom); - pos = Point::new(pad.left, size.y - pad.bottom + descent); - area = Size::new(pw, pad.bottom - descent); + let descent = footer_descent.relative_to(margin.bottom); + pos = Point::new(margin.left, size.y - margin.bottom + descent); + area = Size::new(pw, margin.bottom - descent); align = Align::Top.into(); } else { pos = Point::zero(); @@ -382,6 +392,7 @@ impl PageElem { .styled(AlignElem::set_alignment(align)) .layout(vt, styles, pod)? .into_frame(); + if ptr::eq(marginal, &header) || ptr::eq(marginal, &background) { frame.prepend_frame(pos, sub); } else {