diff --git a/library/src/layout/columns.rs b/library/src/layout/columns.rs index 7da9c4a06..4cf840cd4 100644 --- a/library/src/layout/columns.rs +++ b/library/src/layout/columns.rs @@ -83,16 +83,16 @@ impl Layout for ColumnsNode { ) -> SourceResult { // Separating the infinite space into infinite columns does not make // much sense. - if !regions.first.x.is_finite() { + if !regions.size.x.is_finite() { return self.body.layout(vt, styles, regions); } // Determine the width of the gutter and each column. let columns = self.count.get(); - let gutter = styles.get(Self::GUTTER).relative_to(regions.base.x); - let width = (regions.first.x - gutter * (columns - 1) as f64) / columns as f64; + let gutter = styles.get(Self::GUTTER).relative_to(regions.base().x); + let width = (regions.size.x - gutter * (columns - 1) as f64) / columns as f64; - let backlog: Vec<_> = std::iter::once(®ions.first.y) + let backlog: Vec<_> = std::iter::once(®ions.size.y) .chain(regions.backlog) .flat_map(|&height| std::iter::repeat(height).take(columns)) .skip(1) @@ -100,8 +100,8 @@ impl Layout for ColumnsNode { // Create the pod regions. let pod = Regions { - first: Size::new(width, regions.first.y), - base: Size::new(width, regions.base.y), + size: Size::new(width, regions.size.y), + full: regions.full, backlog: &backlog, last: regions.last, expand: Axes::new(true, regions.expand.y), @@ -121,7 +121,7 @@ impl Layout for ColumnsNode { // case, the frame is first created with zero height and then // resized. let height = if regions.expand.y { region.y } else { Abs::zero() }; - let mut output = Frame::new(Size::new(regions.first.x, height)); + let mut output = Frame::new(Size::new(regions.size.x, height)); let mut cursor = Abs::zero(); for _ in 0..columns { @@ -134,7 +134,7 @@ impl Layout for ColumnsNode { let x = if dir == Dir::LTR { cursor } else { - regions.first.x - cursor - width + regions.size.x - cursor - width }; output.push_frame(Point::with_x(x), frame); diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs index 094ed05a3..b7e7aa181 100644 --- a/library/src/layout/container.rs +++ b/library/src/layout/container.rs @@ -77,24 +77,22 @@ impl Layout for BoxNode { let size = self .sizing .resolve(styles) - .zip(regions.base) + .zip(regions.base()) .map(|(s, b)| s.map(|v| v.relative_to(b))) - .unwrap_or(regions.first); + .unwrap_or(regions.size); // Select the appropriate base and expansion for the child depending // on whether it is automatically or relatively sized. let is_auto = self.sizing.as_ref().map(Option::is_none); - let base = is_auto.select(regions.base, size); let expand = regions.expand | !is_auto; - - Regions::one(size, base, expand) + Regions::one(size, expand) }; // Layout the child. let mut frame = self.body.layout(vt, styles, pod)?.into_frame(); // Ensure frame size matches regions size if expansion is on. - let target = regions.expand.select(regions.first, frame.size()); + let target = regions.expand.select(regions.size, frame.size()); frame.resize(target, Align::LEFT_TOP); Ok(Fragment::frame(frame)) diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index 61188f9ca..e21dcd2af 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -85,7 +85,7 @@ impl<'a> FlowLayouter<'a> { /// Create a new flow layouter. fn new(mut regions: Regions<'a>) -> Self { let expand = regions.expand; - let full = regions.first; + let full = regions.size; // Disable vertical expansion for children. regions.expand.y = false; @@ -122,14 +122,7 @@ impl<'a> FlowLayouter<'a> { let leading = styles.get(ParNode::LEADING); let consecutive = self.last_was_par; let frames = par - .layout( - vt, - styles, - consecutive, - self.regions.first.x, - self.regions.base, - self.regions.expand.x, - )? + .layout(vt, styles, consecutive, self.regions.base(), self.regions.expand.x)? .into_frames(); let mut sticky = self.items.len(); @@ -142,7 +135,7 @@ impl<'a> FlowLayouter<'a> { } if let [first, ..] = frames.as_slice() { - if !self.regions.first.y.fits(first.height()) && !self.regions.in_last() { + if !self.regions.size.y.fits(first.height()) && !self.regions.in_last() { let carry: Vec<_> = self.items.drain(sticky..).collect(); self.finish_region(); for item in carry { @@ -199,15 +192,15 @@ impl<'a> FlowLayouter<'a> { /// Layout a finished frame. fn layout_item(&mut self, item: FlowItem) { match item { - FlowItem::Absolute(v, _) => self.regions.first.y -= v, + FlowItem::Absolute(v, _) => self.regions.size.y -= v, FlowItem::Fractional(_) => {} FlowItem::Frame(ref frame, ..) => { let size = frame.size(); - if !self.regions.first.y.fits(size.y) && !self.regions.in_last() { + if !self.regions.size.y.fits(size.y) && !self.regions.in_last() { self.finish_region(); } - self.regions.first.y -= size.y; + self.regions.size.y -= size.y; } FlowItem::Placed(_) => {} } @@ -284,7 +277,7 @@ impl<'a> FlowLayouter<'a> { // Advance to the next region. self.finished.push(output); self.regions.next(); - self.full = self.regions.first; + self.full = self.regions.size; } /// Finish layouting and return the resulting fragment. diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index da8c4fcad..95e4ac8fe 100644 --- a/library/src/layout/grid.rs +++ b/library/src/layout/grid.rs @@ -235,8 +235,6 @@ struct GridLayouter<'a, 'v> { rcols: Vec, /// Rows in the current region. lrows: Vec, - /// The full height of the current region. - full: Abs, /// The used-up size of the current region. The horizontal size is /// determined once after columns are resolved and not touched again. used: Size, @@ -317,7 +315,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> { cols.reverse(); } - let full = regions.first.y; let rcols = vec![Abs::zero(); cols.len()]; let lrows = vec![]; @@ -337,7 +334,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> { styles, rcols, lrows, - full, used: Size::zero(), fr: Fr::zero(), finished: vec![], @@ -384,7 +380,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { TrackSizing::Auto => {} TrackSizing::Relative(v) => { let resolved = - v.resolve(self.styles).relative_to(self.regions.base.x); + v.resolve(self.styles).relative_to(self.regions.base().x); *rcol = resolved; rel += resolved; } @@ -393,7 +389,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { } // Size that is not used by fixed-size columns. - let available = self.regions.first.x - rel; + let available = self.regions.size.x - rel; if available >= Abs::zero() { // Determine size of auto columns. let (auto, count) = self.measure_auto_columns(available)?; @@ -429,16 +425,17 @@ impl<'a, 'v> GridLayouter<'a, 'v> { let mut resolved = Abs::zero(); for y in 0..self.rows.len() { if let Some(cell) = self.cell(x, y) { - let size = Size::new(available, self.regions.base.y); - let mut pod = Regions::one(size, size, Axes::splat(false)); - // For relative rows, we can already resolve the correct // base and for auto and fr we could only guess anyway. - if let TrackSizing::Relative(v) = self.rows[y] { - pod.base.y = - v.resolve(self.styles).relative_to(self.regions.base.y); - } + let height = match self.rows[y] { + TrackSizing::Relative(v) => { + v.resolve(self.styles).relative_to(self.regions.base().y) + } + _ => self.regions.base().y, + }; + let size = Size::new(available, height); + let pod = Regions::one(size, Axes::splat(false)); let frame = cell.layout(self.vt, self.styles, pod)?.into_frame(); resolved.set_max(frame.width()); } @@ -508,8 +505,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { for (x, &rcol) in self.rcols.iter().enumerate() { if let Some(cell) = self.cell(x, y) { let mut pod = self.regions; - pod.first.x = rcol; - pod.base.x = rcol; + pod.size.x = rcol; let frames = cell.layout(self.vt, self.styles, pod)?.into_frames(); if let [first, rest @ ..] = frames.as_slice() { @@ -573,12 +569,12 @@ impl<'a, 'v> GridLayouter<'a, 'v> { /// Layout a row with relative height. Such a row cannot break across /// multiple regions, but it may force a region break. fn layout_relative_row(&mut self, v: Rel, y: usize) -> SourceResult<()> { - let resolved = v.resolve(self.styles).relative_to(self.regions.base.y); + let resolved = v.resolve(self.styles).relative_to(self.regions.base().y); let frame = self.layout_single_row(resolved, y)?; // Skip to fitting region. let height = frame.height(); - while !self.regions.first.y.fits(height) && !self.regions.in_last() { + while !self.regions.size.y.fits(height) && !self.regions.in_last() { self.finish_region()?; // Don't skip multiple regions for gutter and don't push a row. @@ -600,14 +596,10 @@ impl<'a, 'v> GridLayouter<'a, 'v> { for (x, &rcol) in self.rcols.iter().enumerate() { if let Some(cell) = self.cell(x, y) { let size = Size::new(rcol, height); - let base = Size::new( - rcol, - match self.rows[y] { - TrackSizing::Auto => self.regions.base.y, - _ => height, - }, - ); - let pod = Regions::one(size, base, Axes::splat(true)); + let mut pod = Regions::one(size, Axes::splat(true)); + if self.rows[y] == TrackSizing::Auto { + pod.full = self.regions.full; + } let frame = cell.layout(self.vt, self.styles, pod)?.into_frame(); output.push_frame(pos, frame); } @@ -628,15 +620,15 @@ impl<'a, 'v> GridLayouter<'a, 'v> { // Prepare regions. let size = Size::new(self.used.x, heights[0]); - let mut pod = Regions::one(size, self.regions.base, Axes::splat(true)); + let mut pod = Regions::one(size, Axes::splat(true)); + pod.full = self.regions.full; pod.backlog = &heights[1..]; // Layout the row. let mut pos = Point::zero(); for (x, &rcol) in self.rcols.iter().enumerate() { if let Some(cell) = self.cell(x, y) { - pod.first.x = rcol; - pod.base.x = rcol; + pod.size.x = rcol; // Push the layouted frames into the individual output frames. let fragment = cell.layout(self.vt, self.styles, pod)?; @@ -653,7 +645,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { /// Push a row frame into the current region. fn push_row(&mut self, frame: Frame) { - self.regions.first.y -= frame.height(); + self.regions.size.y -= frame.height(); self.used.y += frame.height(); self.lrows.push(Row::Frame(frame)); } @@ -663,8 +655,8 @@ impl<'a, 'v> GridLayouter<'a, 'v> { // Determine the size of the grid in this region, expanding fully if // there are fr rows. let mut size = self.used; - if self.fr.get() > 0.0 && self.full.is_finite() { - size.y = self.full; + if self.fr.get() > 0.0 && self.regions.full.is_finite() { + size.y = self.regions.full; } // The frame for the region. @@ -676,7 +668,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { let frame = match row { Row::Frame(frame) => frame, Row::Fr(v, y) => { - let remaining = self.full - self.used.y; + let remaining = self.regions.full - self.used.y; let height = v.share(self.fr, remaining); self.layout_single_row(height, y)? } @@ -689,7 +681,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> { self.finished.push(output); self.regions.next(); - self.full = self.regions.first.y; self.used.y = Abs::zero(); self.fr = Fr::zero(); diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index 3de126341..6a0c07b0b 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -293,7 +293,7 @@ impl PageNode { } // Layout the child. - let regions = Regions::repeat(size, size, size.map(Abs::is_finite)); + let regions = Regions::repeat(size, size.map(Abs::is_finite)); let mut fragment = child.layout(vt, styles, regions)?; let header = styles.get(Self::HEADER); @@ -316,7 +316,7 @@ impl PageNode { let in_background = std::ptr::eq(marginal, background); let Some(marginal) = marginal else { continue }; let content = marginal.resolve(vt, page)?; - let pod = Regions::one(area, area, Axes::splat(true)); + let pod = Regions::one(area, Axes::splat(true)); let sub = content.layout(vt, styles, pod)?.into_frame(); if in_background { frame.prepend_frame(pos, sub); diff --git a/library/src/layout/par.rs b/library/src/layout/par.rs index dbf2c936d..21551268e 100644 --- a/library/src/layout/par.rs +++ b/library/src/layout/par.rs @@ -120,8 +120,7 @@ impl ParNode { vt: &mut Vt, styles: StyleChain, consecutive: bool, - width: Abs, - base: Size, + region: Size, expand: bool, ) -> SourceResult { #[comemo::memoize] @@ -132,8 +131,7 @@ impl ParNode { introspector: Tracked, styles: StyleChain, consecutive: bool, - width: Abs, - base: Size, + region: Size, expand: bool, ) -> SourceResult { let mut vt = Vt { world, provider, introspector }; @@ -144,13 +142,13 @@ impl ParNode { // Perform BiDi analysis and then prepare paragraph layout by building a // representation on which we can do line breaking without layouting // each and every line from scratch. - let p = prepare(&mut vt, par, &text, segments, styles, width, base)?; + let p = prepare(&mut vt, par, &text, segments, styles, region)?; // Break the paragraph into lines. - let lines = linebreak(&vt, &p, width); + let lines = linebreak(&vt, &p, region.x); // Stack the lines into one frame per region. - finalize(&mut vt, &p, &lines, width, base, expand) + finalize(&mut vt, &p, &lines, region, expand) } cached( @@ -160,8 +158,7 @@ impl ParNode { vt.introspector, styles, consecutive, - width, - base, + region, expand, ) } @@ -595,8 +592,7 @@ fn prepare<'a>( text: &'a str, segments: Vec<(Segment<'a>, StyleChain<'a>)>, styles: StyleChain<'a>, - width: Abs, - base: Size, + region: Size, ) -> SourceResult> { let bidi = BidiInfo::new( text, @@ -619,7 +615,7 @@ fn prepare<'a>( } Segment::Spacing(spacing) => match spacing { Spacing::Relative(v) => { - let resolved = v.resolve(styles).relative_to(base.x); + let resolved = v.resolve(styles).relative_to(region.x); items.push(Item::Absolute(resolved)); } Spacing::Fractional(v) => { @@ -630,8 +626,7 @@ fn prepare<'a>( if let Some(repeat) = inline.to::() { items.push(Item::Repeat(repeat, styles)); } else { - let size = Size::new(width, base.y); - let pod = Regions::one(size, base, Axes::splat(false)); + let pod = Regions::one(region, Axes::splat(false)); let mut frame = inline.layout(vt, styles, pod)?.into_frame(); frame.translate(Point::with_y(styles.get(TextNode::BASELINE))); items.push(Item::Frame(frame)); @@ -1116,20 +1111,20 @@ fn finalize( vt: &mut Vt, p: &Preparation, lines: &[Line], - mut width: Abs, - base: Size, + mut region: Size, expand: bool, ) -> SourceResult { // Determine the paragraph's width: Full width of the region if we // should expand or there's fractional spacing, fit-to-width otherwise. - if !width.is_finite() || (!expand && lines.iter().all(|line| line.fr().is_zero())) { - width = lines.iter().map(|line| line.width).max().unwrap_or_default(); + if !region.x.is_finite() || (!expand && lines.iter().all(|line| line.fr().is_zero())) + { + region.x = lines.iter().map(|line| line.width).max().unwrap_or_default(); } // Stack the lines into one frame per region. let mut frames: Vec = lines .iter() - .map(|line| commit(vt, p, line, base, width)) + .map(|line| commit(vt, p, line, region)) .collect::>()?; // Prevent orphans. @@ -1164,10 +1159,9 @@ fn commit( vt: &mut Vt, p: &Preparation, line: &Line, - base: Size, - width: Abs, + region: Size, ) -> SourceResult { - let mut remaining = width - line.width; + let mut remaining = region.x - line.width; let mut offset = Abs::zero(); // Reorder the line from logical to visual order. @@ -1242,8 +1236,8 @@ fn commit( Item::Repeat(repeat, styles) => { let before = offset; let fill = Fr::one().share(fr, remaining); - let size = Size::new(fill, base.y); - let pod = Regions::one(size, base, Axes::new(false, false)); + let size = Size::new(fill, region.y); + let pod = Regions::one(size, Axes::new(false, false)); let frame = repeat.layout(vt, *styles, pod)?.into_frame(); let width = frame.width(); let count = (fill / width).floor(); @@ -1268,7 +1262,7 @@ fn commit( remaining = Abs::zero(); } - let size = Size::new(width, top + bottom); + let size = Size::new(region.x, top + bottom); let mut output = Frame::new(size); output.set_baseline(top); diff --git a/library/src/layout/place.rs b/library/src/layout/place.rs index 16b091fee..c6e26b722 100644 --- a/library/src/layout/place.rs +++ b/library/src/layout/place.rs @@ -92,16 +92,16 @@ impl Layout for PlaceNode { // The pod is the base area of the region because for absolute // placement we don't really care about the already used area. let pod = { - let finite = regions.base.map(Abs::is_finite); + let finite = regions.base().map(Abs::is_finite); let expand = finite & (regions.expand | out_of_flow); - Regions::one(regions.base, regions.base, expand) + Regions::one(regions.base(), expand) }; let mut frame = self.0.layout(vt, styles, pod)?.into_frame(); // If expansion is off, zero all sizes so that we don't take up any // space in our parent. Otherwise, respect the expand settings. - let target = regions.expand.select(regions.first, Size::zero()); + let target = regions.expand.select(regions.size, Size::zero()); frame.resize(target, Align::LEFT_TOP); Ok(Fragment::frame(frame)) diff --git a/library/src/layout/regions.rs b/library/src/layout/regions.rs index 2592210b0..94c817043 100644 --- a/library/src/layout/regions.rs +++ b/library/src/layout/regions.rs @@ -5,10 +5,10 @@ use typst::geom::{Abs, Axes, Size}; /// A sequence of regions to layout into. #[derive(Copy, Clone, Hash)] pub struct Regions<'a> { - /// The (remaining) size of the first region. - pub first: Size, - /// The base size for relative sizing. - pub base: Size, + /// The remaining size of the first region. + pub size: Size, + /// The full height of the region for relative sizing. + pub full: Abs, /// The height of followup regions. The width is the same for all regions. pub backlog: &'a [Abs], /// The height of the final region that is repeated once the backlog is @@ -19,12 +19,12 @@ pub struct Regions<'a> { pub expand: Axes, } -impl<'a> Regions<'a> { +impl Regions<'_> { /// Create a new region sequence with exactly one region. - pub fn one(size: Size, base: Size, expand: Axes) -> Self { + pub fn one(size: Size, expand: Axes) -> Self { Self { - first: size, - base, + size, + full: size.y, backlog: &[], last: None, expand, @@ -32,16 +32,24 @@ impl<'a> Regions<'a> { } /// Create a new sequence of same-size regions that repeats indefinitely. - pub fn repeat(size: Size, base: Size, expand: Axes) -> Self { + pub fn repeat(size: Size, expand: Axes) -> Self { Self { - first: size, - base, + size, + full: size.y, backlog: &[], last: Some(size.y), expand, } } + /// The base size, which doesn't take into account that the regions is + /// already partially used up. + /// + /// This is also used for relative sizing. + pub fn base(&self) -> Size { + Size::new(self.size.x, self.full) + } + /// Create new regions where all sizes are mapped with `f`. /// /// Note that since all regions must have the same width, the width returned @@ -50,12 +58,12 @@ impl<'a> Regions<'a> { where F: FnMut(Size) -> Size, { - let x = self.first.x; + let x = self.size.x; backlog.clear(); backlog.extend(self.backlog.iter().map(|&y| f(Size::new(x, y)).y)); Regions { - first: f(self.first), - base: f(self.base), + size: f(self.size), + full: f(Size::new(x, self.full)).y, backlog, last: self.last.map(|y| f(Size::new(x, y)).y), expand: self.expand, @@ -64,14 +72,14 @@ impl<'a> Regions<'a> { /// Whether the first region is full and a region break is called for. pub fn is_full(&self) -> bool { - Abs::zero().fits(self.first.y) && !self.in_last() + Abs::zero().fits(self.size.y) && !self.in_last() } /// Whether the first region is the last usable region. /// /// If this is true, calling `next()` will have no effect. pub fn in_last(&self) -> bool { - self.backlog.is_empty() && self.last.map_or(true, |height| self.first.y == height) + self.backlog.is_empty() && self.last.map_or(true, |height| self.size.y == height) } /// Advance to the next region if there is any. @@ -85,8 +93,8 @@ impl<'a> Regions<'a> { }) .or(self.last) { - self.first.y = height; - self.base.y = height; + self.size.y = height; + self.full = height; } } @@ -95,10 +103,10 @@ impl<'a> Regions<'a> { /// [`next()`](Self::next) repeatedly until all regions are exhausted. /// This iterator may be infinite. pub fn iter(&self) -> impl Iterator + '_ { - let first = std::iter::once(self.first); + let first = std::iter::once(self.size); let backlog = self.backlog.iter(); let last = self.last.iter().cycle(); - first.chain(backlog.chain(last).map(|&h| Size::new(self.first.x, h))) + first.chain(backlog.chain(last).map(|&h| Size::new(self.size.x, h))) } } @@ -106,15 +114,15 @@ impl Debug for Regions<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("Regions ")?; let mut list = f.debug_list(); - let mut prev = self.first.y; - list.entry(&self.first); + let mut prev = self.size.y; + list.entry(&self.size); for &height in self.backlog { - list.entry(&Size::new(self.first.x, height)); + list.entry(&Size::new(self.size.x, height)); prev = height; } if let Some(last) = self.last { if last != prev { - list.entry(&Size::new(self.first.x, last)); + list.entry(&Size::new(self.size.x, last)); } list.entry(&(..)); } diff --git a/library/src/layout/stack.rs b/library/src/layout/stack.rs index 54b03bdc8..5c1a471cf 100644 --- a/library/src/layout/stack.rs +++ b/library/src/layout/stack.rs @@ -177,7 +177,7 @@ impl<'a> StackLayouter<'a> { fn new(dir: Dir, regions: Regions<'a>, styles: StyleChain<'a>) -> Self { let axis = dir.axis(); let expand = regions.expand; - let full = regions.first; + let full = regions.size; // Disable expansion along the block axis for children. let mut regions = regions.clone(); @@ -202,11 +202,14 @@ impl<'a> StackLayouter<'a> { match spacing { Spacing::Relative(v) => { // Resolve the spacing and limit it to the remaining space. - let resolved = - v.resolve(self.styles).relative_to(self.regions.base.get(self.axis)); - let remaining = self.regions.first.get_mut(self.axis); + let resolved = v + .resolve(self.styles) + .relative_to(self.regions.base().get(self.axis)); + let remaining = self.regions.size.get_mut(self.axis); let limited = resolved.min(*remaining); - *remaining -= limited; + if self.dir.axis() == Axis::Y { + *remaining -= limited; + } self.used.main += limited; self.items.push(StackItem::Absolute(resolved)); } @@ -242,14 +245,18 @@ impl<'a> StackLayouter<'a> { for (i, frame) in fragment.into_iter().enumerate() { // Grow our size, shrink the region and save the frame for later. let size = frame.size(); - let size = match self.axis { + if self.dir.axis() == Axis::Y { + self.regions.size.y -= size.y; + } + + let gen = match self.axis { Axis::X => Gen::new(size.y, size.x), Axis::Y => Gen::new(size.x, size.y), }; - self.used.main += size.main; - self.used.cross.set_max(size.cross); - *self.regions.first.get_mut(self.axis) -= size.main; + self.used.main += gen.main; + self.used.cross.set_max(gen.cross); + self.items.push(StackItem::Frame(frame, align)); if i + 1 < len { @@ -310,7 +317,7 @@ impl<'a> StackLayouter<'a> { // Advance to the next region. self.regions.next(); - self.full = self.regions.first; + self.full = self.regions.size; self.used = Gen::zero(); self.fr = Fr::zero(); self.finished.push(output); diff --git a/library/src/layout/transform.rs b/library/src/layout/transform.rs index 25f74e01c..1c9dfce5c 100644 --- a/library/src/layout/transform.rs +++ b/library/src/layout/transform.rs @@ -78,7 +78,7 @@ impl Layout for MoveNode { let mut fragment = self.body.layout(vt, styles, regions)?; for frame in &mut fragment { let delta = self.delta.resolve(styles); - let delta = delta.zip(regions.base).map(|(d, s)| d.relative_to(s)); + let delta = delta.zip(regions.base()).map(|(d, s)| d.relative_to(s)); frame.translate(delta.to_point()); } Ok(fragment) diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs index d43d1b2ae..a3aa40472 100644 --- a/library/src/math/ctx.rs +++ b/library/src/math/ctx.rs @@ -25,7 +25,7 @@ macro_rules! percent { /// The context for math layout. pub struct MathContext<'a, 'b, 'v> { pub vt: &'v mut Vt<'b>, - pub regions: Regions<'a>, + pub regions: Regions<'static>, pub font: &'a Font, pub ttf: &'a ttf_parser::Face<'a>, pub table: ttf_parser::math::Table<'a>, @@ -60,10 +60,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { let variant = variant(styles); Self { vt, - regions: { - let size = Size::new(regions.first.x, regions.base.y); - Regions::one(size, regions.base, Axes::splat(false)) - }, + regions: Regions::one(regions.base(), Axes::splat(false)), font: &font, ttf: font.ttf(), table, diff --git a/library/src/visualize/image.rs b/library/src/visualize/image.rs index 87b672878..330f1d04d 100644 --- a/library/src/visualize/image.rs +++ b/library/src/visualize/image.rs @@ -76,7 +76,7 @@ impl Layout for ImageNode { let px_ratio = pxw / pxh; // Find out whether the image is wider or taller than the target size. - let Regions { first, expand, .. } = regions; + let Regions { size: first, expand, .. } = regions; let region_ratio = first.x / first.y; let wide = px_ratio > region_ratio; diff --git a/library/src/visualize/line.rs b/library/src/visualize/line.rs index a8b0e334a..28910a262 100644 --- a/library/src/visualize/line.rs +++ b/library/src/visualize/line.rs @@ -87,17 +87,17 @@ impl Layout for LineNode { let origin = self .start .resolve(styles) - .zip(regions.base) + .zip(regions.base()) .map(|(l, b)| l.relative_to(b)); let delta = self .delta .resolve(styles) - .zip(regions.base) + .zip(regions.base()) .map(|(l, b)| l.relative_to(b)); let size = origin.max(origin + delta).max(Size::zero()); - let target = regions.expand.select(regions.first, size); + let target = regions.expand.select(regions.size, size); let mut frame = Frame::new(target); let shape = Geometry::Line(delta.to_point()).stroked(stroke); diff --git a/library/src/visualize/shape.rs b/library/src/visualize/shape.rs index c0c81bf5f..6f70b6c14 100644 --- a/library/src/visualize/shape.rs +++ b/library/src/visualize/shape.rs @@ -555,41 +555,40 @@ fn layout( // Pad the child. let child = child.clone().padded(inset.map(|side| side.map(Length::from))); - - let pod = Regions::one(regions.first, regions.base, regions.expand); + let pod = Regions::one(regions.size, regions.expand); frame = child.layout(vt, styles, pod)?.into_frame(); // Relayout with full expansion into square region to make sure // the result is really a square or circle. if kind.is_quadratic() { let length = if regions.expand.x || regions.expand.y { - let target = regions.expand.select(regions.first, Size::zero()); + let target = regions.expand.select(regions.size, Size::zero()); target.x.max(target.y) } else { let size = frame.size(); let desired = size.x.max(size.y); - desired.min(regions.first.x).min(regions.first.y) + desired.min(regions.size.x).min(regions.size.y) }; let size = Size::splat(length); - let pod = Regions::one(size, size, Axes::splat(true)); + let pod = Regions::one(size, Axes::splat(true)); frame = child.layout(vt, styles, pod)?.into_frame(); } } else { // The default size that a shape takes on if it has no child and // enough space. - let mut size = Size::new(Abs::pt(45.0), Abs::pt(30.0)).min(regions.first); + let mut size = Size::new(Abs::pt(45.0), Abs::pt(30.0)).min(regions.size); if kind.is_quadratic() { let length = if regions.expand.x || regions.expand.y { - let target = regions.expand.select(regions.first, Size::zero()); + let target = regions.expand.select(regions.size, Size::zero()); target.x.max(target.y) } else { size.x.min(size.y) }; size = Size::splat(length); } else { - size = regions.expand.select(regions.first, size); + size = regions.expand.select(regions.size, size); } frame = Frame::new(size);