diff options
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/align.rs | 13 | ||||
| -rw-r--r-- | src/library/columns.rs | 25 | ||||
| -rw-r--r-- | src/library/flow.rs | 31 | ||||
| -rw-r--r-- | src/library/grid.rs | 91 | ||||
| -rw-r--r-- | src/library/hide.rs | 4 | ||||
| -rw-r--r-- | src/library/image.rs | 20 | ||||
| -rw-r--r-- | src/library/mod.rs | 8 | ||||
| -rw-r--r-- | src/library/pad.rs | 19 | ||||
| -rw-r--r-- | src/library/page.rs | 9 | ||||
| -rw-r--r-- | src/library/par.rs | 24 | ||||
| -rw-r--r-- | src/library/place.rs | 16 | ||||
| -rw-r--r-- | src/library/shape.rs | 23 | ||||
| -rw-r--r-- | src/library/stack.rs | 25 | ||||
| -rw-r--r-- | src/library/transform.rs | 4 |
14 files changed, 105 insertions, 207 deletions
diff --git a/src/library/align.rs b/src/library/align.rs index a7e6d3cb..8ea9ddaf 100644 --- a/src/library/align.rs +++ b/src/library/align.rs @@ -27,7 +27,7 @@ impl Layout for AlignNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { // The child only needs to expand along an axis if there's no alignment. let mut pod = regions.clone(); pod.expand &= self.aligns.map_is_none(); @@ -40,20 +40,13 @@ impl Layout for AlignNode { // Layout the child. let mut frames = self.child.layout(vm, &pod, passed.chain(&styles))?; - for ((current, base), Constrained { item: frame, cts }) in - regions.iter().zip(&mut frames) - { + for (region, frame) in regions.iter().zip(&mut frames) { // Align in the target size. The target size depends on whether we // should expand. - let target = regions.expand.select(current, frame.size); + let target = regions.expand.select(region, frame.size); let default = Spec::new(Align::Left, Align::Top); let aligns = self.aligns.unwrap_or(default); Arc::make_mut(frame).resize(target, aligns); - - // Set constraints. - cts.expand = regions.expand; - cts.base = base.filter(cts.base.map_is_some()); - cts.exact = current.filter(regions.expand | cts.exact.map_is_some()); } Ok(frames) diff --git a/src/library/columns.rs b/src/library/columns.rs index 049fa8b9..bae23dd3 100644 --- a/src/library/columns.rs +++ b/src/library/columns.rs @@ -32,23 +32,23 @@ impl Layout for ColumnsNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { // Separating the infinite space into infinite columns does not make // much sense. - if regions.current.x.is_infinite() { + if regions.first.x.is_infinite() { return self.child.layout(vm, regions, styles); } // Determine the width of the gutter and each column. let columns = self.columns.get(); let gutter = styles.get(Self::GUTTER).resolve(regions.base.x); - let width = (regions.current.x - gutter * (columns - 1) as f64) / columns as f64; + let width = (regions.first.x - gutter * (columns - 1) as f64) / columns as f64; // Create the pod regions. let pod = Regions { - current: Size::new(width, regions.current.y), + first: Size::new(width, regions.first.y), base: Size::new(width, regions.base.y), - backlog: std::iter::once(®ions.current.y) + backlog: std::iter::once(®ions.first.y) .chain(regions.backlog.as_slice()) .flat_map(|&height| std::iter::repeat(height).take(columns)) .skip(1) @@ -66,18 +66,18 @@ impl Layout for ColumnsNode { let mut finished = vec![]; // Stitch together the columns for each region. - for (current, base) in regions.iter().take(total_regions) { + for region in regions.iter().take(total_regions) { // The height should be the parent height if the node shall expand. // Otherwise its the maximum column height for the frame. In that // case, the frame is first created with zero height and then // resized. - let height = if regions.expand.y { current.y } else { Length::zero() }; - let mut output = Frame::new(Size::new(regions.current.x, height)); + let height = if regions.expand.y { region.y } else { Length::zero() }; + let mut output = Frame::new(Size::new(regions.first.x, height)); let mut cursor = Length::zero(); for _ in 0 .. columns { let frame = match frames.next() { - Some(frame) => frame.item, + Some(frame) => frame, None => break, }; @@ -89,17 +89,14 @@ impl Layout for ColumnsNode { let x = if dir.is_positive() { cursor } else { - regions.current.x - cursor - width + regions.first.x - cursor - width }; output.push_frame(Point::with_x(x), frame); cursor += width + gutter; } - let mut cts = Constraints::new(regions.expand); - cts.base = base.map(Some); - cts.exact = current.map(Some); - finished.push(output.constrain(cts)); + finished.push(Arc::new(output)); } Ok(finished) diff --git a/src/library/flow.rs b/src/library/flow.rs index 135fd327..bc3bf0f1 100644 --- a/src/library/flow.rs +++ b/src/library/flow.rs @@ -31,7 +31,7 @@ impl Layout for FlowNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let mut layouter = FlowLayouter::new(regions); for (child, map) in self.0.iter() { @@ -96,7 +96,7 @@ pub struct FlowLayouter { regions: Regions, /// Whether the flow should expand to fill the region. expand: Spec<bool>, - /// The full size of `regions.current` that was available before we started + /// The full size of `regions.size` that was available before we started /// subtracting. full: Size, /// The size used by the frames for the current region. @@ -106,7 +106,7 @@ pub struct FlowLayouter { /// Spacing and layouted nodes. items: Vec<FlowItem>, /// Finished frames for previous regions. - finished: Vec<Constrained<Arc<Frame>>>, + finished: Vec<Arc<Frame>>, } /// A prepared item in a flow layout. @@ -125,7 +125,7 @@ impl FlowLayouter { /// Create a new flow layouter. pub fn new(regions: &Regions) -> Self { let expand = regions.expand; - let full = regions.current; + let full = regions.first; // Disable vertical expansion for children. let mut regions = regions.clone(); @@ -148,8 +148,8 @@ impl FlowLayouter { SpacingKind::Linear(v) => { // Resolve the linear and limit it to the remaining space. let resolved = v.resolve(self.full.y); - let limited = resolved.min(self.regions.current.y); - self.regions.current.y -= limited; + let limited = resolved.min(self.regions.first.y); + self.regions.first.y -= limited; self.used.y += limited; self.items.push(FlowItem::Absolute(resolved)); } @@ -177,7 +177,7 @@ impl FlowLayouter { if let Some(placed) = node.downcast::<PlaceNode>() { if placed.out_of_flow() { let frame = node.layout(vm, &self.regions, styles)?.remove(0); - self.items.push(FlowItem::Placed(frame.item)); + self.items.push(FlowItem::Placed(frame)); return Ok(()); } } @@ -197,11 +197,11 @@ impl FlowLayouter { let len = frames.len(); for (i, frame) in frames.into_iter().enumerate() { // Grow our size, shrink the region and save the frame for later. - let size = frame.item.size; + let size = frame.size; self.used.y += size.y; self.used.x.set_max(size.x); - self.regions.current.y -= size.y; - self.items.push(FlowItem::Frame(frame.item, aligns)); + self.regions.first.y -= size.y; + self.items.push(FlowItem::Frame(frame, aligns)); if i + 1 < len { self.finish_region(); @@ -251,21 +251,16 @@ impl FlowLayouter { } } - // Generate tight constraints for now. - let mut cts = Constraints::new(self.expand); - cts.exact = self.full.map(Some); - cts.base = self.regions.base.map(Some); - // Advance to the next region. self.regions.next(); - self.full = self.regions.current; + self.full = self.regions.first; self.used = Size::zero(); self.fr = Fractional::zero(); - self.finished.push(output.constrain(cts)); + self.finished.push(Arc::new(output)); } /// Finish layouting and return the resulting frames. - pub fn finish(mut self) -> Vec<Constrained<Arc<Frame>>> { + pub fn finish(mut self) -> Vec<Arc<Frame>> { if self.expand.y { while self.regions.backlog.len() > 0 { self.finish_region(); diff --git a/src/library/grid.rs b/src/library/grid.rs index 5f1edb1c..fc62f8eb 100644 --- a/src/library/grid.rs +++ b/src/library/grid.rs @@ -38,7 +38,7 @@ impl Layout for GridNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { // Prepare grid layout by unifying content and gutter tracks. let layouter = GridLayouter::new( self.tracks.as_deref(), @@ -105,8 +105,6 @@ pub struct GridLayouter<'a> { rcols: Vec<Length>, /// Rows in the current region. lrows: Vec<Row>, - /// Whether the grid itself should expand to fill the region. - expand: Spec<bool>, /// The full height of the current region. full: Length, /// The used-up size of the current region. The horizontal size is @@ -114,10 +112,8 @@ pub struct GridLayouter<'a> { used: Size, /// The sum of fractional ratios in the current region. fr: Fractional, - /// Constraints for the active region. - cts: Constraints, /// Frames for finished regions. - finished: Vec<Constrained<Arc<Frame>>>, + finished: Vec<Arc<Frame>>, } /// Produced by initial row layout, auto and linear rows are already finished, @@ -177,8 +173,7 @@ impl<'a> GridLayouter<'a> { cols.pop(); rows.pop(); - let expand = regions.expand; - let full = regions.current.y; + let full = regions.first.y; let rcols = vec![Length::zero(); cols.len()]; let lrows = vec![]; @@ -195,17 +190,15 @@ impl<'a> GridLayouter<'a> { styles, rcols, lrows, - expand, full, used: Size::zero(), fr: Fractional::zero(), - cts: Constraints::new(expand), finished: vec![], } } /// Determines the columns sizes and then layouts the grid row-by-row. - pub fn layout(mut self, vm: &mut Vm) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + pub fn layout(mut self, vm: &mut Vm) -> TypResult<Vec<Arc<Frame>>> { self.measure_columns(vm)?; for y in 0 .. self.rows.len() { @@ -219,7 +212,6 @@ impl<'a> GridLayouter<'a> { TrackSizing::Auto => self.layout_auto_row(vm, y)?, TrackSizing::Linear(v) => self.layout_linear_row(vm, v, y)?, TrackSizing::Fractional(v) => { - self.cts.exact.y = Some(self.full); self.lrows.push(Row::Fr(v, y)); self.fr += v; } @@ -232,22 +224,6 @@ impl<'a> GridLayouter<'a> { /// Determine all column sizes. fn measure_columns(&mut self, vm: &mut Vm) -> TypResult<()> { - enum Case { - /// The column sizing is only determined by specified linear sizes. - PurelyLinear, - /// The column sizing would be affected by the region size if it was - /// smaller. - Fitting, - /// The column sizing is affected by the region size. - Exact, - /// The column sizing would be affected by the region size if it was - /// larger. - Overflowing, - } - - // The different cases affecting constraints. - let mut case = Case::PurelyLinear; - // Sum of sizes of resolved linear tracks. let mut linear = Length::zero(); @@ -258,23 +234,18 @@ impl<'a> GridLayouter<'a> { // fractional tracks. for (&col, rcol) in self.cols.iter().zip(&mut self.rcols) { match col { - TrackSizing::Auto => { - case = Case::Fitting; - } + TrackSizing::Auto => {} TrackSizing::Linear(v) => { let resolved = v.resolve(self.regions.base.x); *rcol = resolved; linear += resolved; } - TrackSizing::Fractional(v) => { - case = Case::Fitting; - fr += v; - } + TrackSizing::Fractional(v) => fr += v, } } // Size that is not used by fixed-size columns. - let available = self.regions.current.x - linear; + let available = self.regions.first.x - linear; if available >= Length::zero() { // Determine size of auto columns. let (auto, count) = self.measure_auto_columns(vm, available)?; @@ -285,25 +256,10 @@ impl<'a> GridLayouter<'a> { if remaining >= Length::zero() { if !fr.is_zero() { self.grow_fractional_columns(remaining, fr); - case = Case::Exact; } } else { self.shrink_auto_columns(available, count); - case = Case::Exact; } - } else if matches!(case, Case::Fitting) { - case = Case::Overflowing; - } - - // Children could depend on base. - self.cts.base = self.regions.base.map(Some); - - // Set constraints depending on the case we hit. - match case { - Case::PurelyLinear => {} - Case::Fitting => self.cts.min.x = Some(self.used.x), - Case::Exact => self.cts.exact.x = Some(self.regions.current.x), - Case::Overflowing => self.cts.max.x = Some(linear), } // Sum up the resolved column sizes once here. @@ -342,7 +298,7 @@ impl<'a> GridLayouter<'a> { pod.base.y = v.resolve(self.regions.base.y); } - let frame = node.layout(vm, &pod, self.styles)?.remove(0).item; + let frame = node.layout(vm, &pod, self.styles)?.remove(0); resolved.set_max(frame.size.x); } } @@ -403,7 +359,7 @@ impl<'a> GridLayouter<'a> { for (x, &rcol) in self.rcols.iter().enumerate() { if let Some(node) = self.cell(x, y) { let mut pod = self.regions.clone(); - pod.current.x = rcol; + pod.first.x = rcol; // All widths should be `rcol` except the base for auto columns. if self.cols[x] == TrackSizing::Auto { @@ -413,7 +369,7 @@ impl<'a> GridLayouter<'a> { let mut sizes = node .layout(vm, &pod, self.styles)? .into_iter() - .map(|frame| frame.item.size.y); + .map(|frame| frame.size.y); // For each region, we want to know the maximum height any // column requires. @@ -443,10 +399,8 @@ impl<'a> GridLayouter<'a> { // eaten up by any fr rows. if self.fr.is_zero() { let len = resolved.len(); - for (target, (current, _)) in - resolved[.. len - 1].iter_mut().zip(self.regions.iter()) - { - target.set_max(current.y); + for (region, target) in self.regions.iter().zip(&mut resolved[.. len - 1]) { + target.set_max(region.y); } } @@ -456,7 +410,6 @@ impl<'a> GridLayouter<'a> { for (i, frame) in frames.into_iter().enumerate() { self.push_row(frame); if i + 1 < len { - self.cts.exact.y = Some(self.full); self.finish_region(vm)?; } } @@ -472,8 +425,7 @@ impl<'a> GridLayouter<'a> { // Skip to fitting region. let height = frame.size.y; - while !self.regions.current.y.fits(height) && !self.regions.in_last() { - self.cts.max.y = Some(self.used.y + height); + while !self.regions.first.y.fits(height) && !self.regions.in_last() { self.finish_region(vm)?; // Don't skip multiple regions for gutter and don't push a row. @@ -509,7 +461,7 @@ impl<'a> GridLayouter<'a> { let pod = Regions::one(size, base, Spec::splat(true)); let frame = node.layout(vm, &pod, self.styles)?.remove(0); - output.push_frame(pos, frame.item); + output.push_frame(pos, frame); } pos.x += rcol; @@ -540,7 +492,7 @@ impl<'a> GridLayouter<'a> { let mut pos = Point::zero(); for (x, &rcol) in self.rcols.iter().enumerate() { if let Some(node) = self.cell(x, y) { - pod.current.x = rcol; + pod.first.x = rcol; // All widths should be `rcol` except the base for auto columns. if self.cols[x] == TrackSizing::Auto { @@ -550,7 +502,7 @@ impl<'a> GridLayouter<'a> { // Push the layouted frames into the individual output frames. let frames = node.layout(vm, &pod, self.styles)?; for (output, frame) in outputs.iter_mut().zip(frames) { - output.push_frame(pos, frame.item); + output.push_frame(pos, frame); } } @@ -562,7 +514,7 @@ impl<'a> GridLayouter<'a> { /// Push a row frame into the current region. fn push_row(&mut self, frame: Frame) { - self.regions.current.y -= frame.size.y; + self.regions.first.y -= frame.size.y; self.used.y += frame.size.y; self.lrows.push(Row::Frame(frame)); } @@ -574,9 +526,6 @@ impl<'a> GridLayouter<'a> { let mut size = self.used; if self.fr.get() > 0.0 && self.full.is_finite() { size.y = self.full; - self.cts.exact.y = Some(self.full); - } else { - self.cts.min.y = Some(size.y.min(self.full)); } // The frame for the region. @@ -599,13 +548,11 @@ impl<'a> GridLayouter<'a> { pos.y += height; } - self.cts.base = self.regions.base.map(Some); - self.finished.push(output.constrain(self.cts)); + self.finished.push(Arc::new(output)); self.regions.next(); - self.full = self.regions.current.y; + self.full = self.regions.first.y; self.used.y = Length::zero(); self.fr = Fractional::zero(); - self.cts = Constraints::new(self.expand); Ok(()) } diff --git a/src/library/hide.rs b/src/library/hide.rs index ea2227f1..dcc73088 100644 --- a/src/library/hide.rs +++ b/src/library/hide.rs @@ -19,11 +19,11 @@ impl Layout for HideNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let mut frames = self.0.layout(vm, regions, styles)?; // Clear the frames. - for Constrained { item: frame, .. } in &mut frames { + for frame in &mut frames { *frame = Arc::new(Frame { elements: vec![], ..**frame }); } diff --git a/src/library/image.rs b/src/library/image.rs index 05877126..000aec73 100644 --- a/src/library/image.rs +++ b/src/library/image.rs @@ -39,24 +39,24 @@ impl Layout for ImageNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let img = vm.images.get(self.0); let pxw = img.width() as f64; let pxh = img.height() as f64; let px_ratio = pxw / pxh; // Find out whether the image is wider or taller than the target size. - let &Regions { current, expand, .. } = regions; - let current_ratio = current.x / current.y; - let wide = px_ratio > current_ratio; + let &Regions { first, expand, .. } = regions; + let region_ratio = first.x / first.y; + let wide = px_ratio > region_ratio; // The space into which the image will be placed according to its fit. let target = if expand.x && expand.y { - current - } else if expand.x || (!expand.y && wide && current.x.is_finite()) { - Size::new(current.x, current.y.min(current.x.safe_div(px_ratio))) - } else if current.y.is_finite() { - Size::new(current.x.min(current.y * px_ratio), current.y) + first + } else if expand.x || (!expand.y && wide && first.x.is_finite()) { + Size::new(first.x, first.y.min(first.x.safe_div(px_ratio))) + } else if first.y.is_finite() { + Size::new(first.x.min(first.y * px_ratio), first.y) } else { Size::new(Length::pt(pxw), Length::pt(pxh)) }; @@ -91,7 +91,7 @@ impl Layout for ImageNode { frame.link(url); } - Ok(vec![frame.constrain(Constraints::tight(regions))]) + Ok(vec![Arc::new(frame)]) } } diff --git a/src/library/mod.rs b/src/library/mod.rs index ad66f2c3..980f45c8 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -66,14 +66,12 @@ pub mod prelude { pub use crate::diag::{with_alternative, At, StrResult, TypResult}; pub use crate::eval::{ - Arg, Args, Cast, Construct, Func, Merge, Property, Scope, Set, Show, ShowNode, - Smart, StyleChain, StyleMap, StyleVec, Template, Value, + Arg, Args, Cast, Construct, Func, Layout, LayoutNode, Merge, Property, Regions, + Scope, Set, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Template, + Value, }; pub use crate::frame::*; pub use crate::geom::*; - pub use crate::layout::{ - Constrain, Constrained, Constraints, Layout, LayoutNode, Regions, - }; pub use crate::syntax::{Span, Spanned}; pub use crate::util::{EcoString, OptionExt}; pub use crate::Vm; diff --git a/src/library/pad.rs b/src/library/pad.rs index ca45a1ca..05b658bd 100644 --- a/src/library/pad.rs +++ b/src/library/pad.rs @@ -33,14 +33,12 @@ impl Layout for PadNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { // Layout child into padded regions. let pod = regions.map(|size| shrink(size, self.padding)); let mut frames = self.child.layout(vm, &pod, styles)?; - for ((current, base), Constrained { item: frame, cts }) in - regions.iter().zip(&mut frames) - { + for frame in &mut frames { // Apply the padding inversely such that the grown size padded // yields the frame's size. let padded = grow(frame.size, self.padding); @@ -51,19 +49,6 @@ impl Layout for PadNode { let frame = Arc::make_mut(frame); frame.size = padded; frame.translate(offset); - - // Set exact and base constraints if the child had them. Also set - // base if our padding is relative. - let is_rel = self.padding.sum_by_axis().map(Linear::is_relative); - cts.exact = current.filter(cts.exact.map_is_some()); - cts.base = base.filter(is_rel | cts.base.map_is_some()); - - // Inflate min and max contraints by the padding. - for spec in [&mut cts.min, &mut cts.max] { - spec.as_mut() - .zip(padding.sum_by_axis()) - .map(|(s, p)| s.as_mut().map(|v| *v += p)); - } } Ok(frames) diff --git a/src/library/page.rs b/src/library/page.rs index 07266ec6..718234c6 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -115,15 +115,12 @@ impl PageNode { // Layout the child. let regions = Regions::repeat(size, size, size.map(Length::is_finite)); - let mut frames: Vec<_> = child - .layout(vm, ®ions, styles)? - .into_iter() - .map(|c| c.item) - .collect(); + let mut frames = child.layout(vm, ®ions, styles)?; let header = styles.get_ref(Self::HEADER); let footer = styles.get_ref(Self::FOOTER); + // Realize header and footer. for frame in &mut frames { let size = frame.size; let padding = padding.resolve(size); @@ -136,7 +133,7 @@ impl PageNode { let w = size.x - padding.left - padding.right; let area = Size::new(w, h); let pod = Regions::one(area, area, area.map(Length::is_finite)); - let sub = template.layout(vm, &pod, styles)?.remove(0).item; + let sub = template.layout(vm, &pod, styles)?.remove(0); Arc::make_mut(frame).push_frame(pos, sub); } } diff --git a/src/library/par.rs b/src/library/par.rs index 857d986f..eab67c53 100644 --- a/src/library/par.rs +++ b/src/library/par.rs @@ -86,7 +86,7 @@ impl Layout for ParNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { // Collect all text into one string used for BiDi analysis. let text = self.collect_text(); let level = Level::from_dir(styles.get(Self::DIR)); @@ -113,7 +113,7 @@ impl Layout for ParNode { // If the line doesn't fit anymore, we push the last fitting attempt // into the stack and rebuild the line from its end. The resulting // line cannot be broken up further. - if !regions.current.x.fits(line.size.x) { + if !regions.first.x.fits(line.size.x) { if let Some((last_line, last_end)) = last.take() { lines.push(last_line); start = last_end; @@ -124,7 +124,7 @@ impl Layout for ParNode { // Finish the current line if there is a mandatory line break (i.e. // due to "\n") or if the line doesn't fit horizontally already // since no shorter line will be possible. - if mandatory || !regions.current.x.fits(line.size.x) { + if mandatory || !regions.first.x.fits(line.size.x) { lines.push(line); start = end; last = None; @@ -139,7 +139,7 @@ impl Layout for ParNode { // Determine the paragraph's width: Fit to width if we shoudn't expand // and there's no fractional spacing. - let mut width = regions.current.x; + let mut width = regions.first.x; if !regions.expand.x && lines.iter().all(|line| line.fr.is_zero()) { width = lines.iter().map(|line| line.size.x).max().unwrap_or_default(); } @@ -149,15 +149,13 @@ impl Layout for ParNode { let mut finished = vec![]; let mut first = true; let mut output = Frame::new(Size::with_x(width)); - let mut cts = Constraints::tight(®ions); // Stack the lines into one frame per region. for line in lines { - while !regions.current.y.fits(line.size.y) && !regions.in_last() { - finished.push(output.constrain(cts)); + while !regions.first.y.fits(line.size.y) && !regions.in_last() { + finished.push(Arc::new(output)); output = Frame::new(Size::with_x(width)); regions.next(); - cts = Constraints::tight(®ions); first = true; } @@ -170,11 +168,11 @@ impl Layout for ParNode { output.size.y += frame.size.y; output.merge_frame(pos, frame); - regions.current.y -= line.size.y + leading; + regions.first.y -= line.size.y + leading; first = false; } - finished.push(output.constrain(cts)); + finished.push(Arc::new(output)); Ok(finished) } } @@ -316,7 +314,7 @@ impl<'a> ParLayout<'a> { } ParChild::Spacing(kind) => match *kind { SpacingKind::Linear(v) => { - let resolved = v.resolve(regions.current.x); + let resolved = v.resolve(regions.first.x); items.push(ParItem::Absolute(resolved)); ranges.push(range); } @@ -326,10 +324,10 @@ impl<'a> ParLayout<'a> { } }, ParChild::Node(node) => { - let size = Size::new(regions.current.x, regions.base.y); + let size = Size::new(regions.first.x, regions.base.y); let pod = Regions::one(size, regions.base, Spec::splat(false)); let frame = node.layout(vm, &pod, styles)?.remove(0); - items.push(ParItem::Frame(Arc::take(frame.item))); + items.push(ParItem::Frame(Arc::take(frame))); ranges.push(range); } } diff --git a/src/library/place.rs b/src/library/place.rs index 9bcd3c37..34746d5b 100644 --- a/src/library/place.rs +++ b/src/library/place.rs @@ -26,11 +26,11 @@ impl Layout for PlaceNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let out_of_flow = self.out_of_flow(); // The pod is the base area of the region because for absolute - // placement we don't really care about the already used area (current). + // placement we don't really care about the already used area. let pod = { let finite = regions.base.map(Length::is_finite); let expand = finite & (regions.expand | out_of_flow); @@ -38,26 +38,20 @@ impl Layout for PlaceNode { }; let mut frames = self.0.layout(vm, &pod, styles)?; - let Constrained { item: frame, cts } = &mut frames[0]; // 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.current, Size::zero()); + let frame = &mut frames[0]; + let target = regions.expand.select(regions.first, Size::zero()); Arc::make_mut(frame).resize(target, Align::LEFT_TOP); - // Set base constraint because our pod size is base and exact - // constraints if we needed to expand or offset. - *cts = Constraints::new(regions.expand); - cts.base = regions.base.map(Some); - cts.exact = regions.current.filter(regions.expand | out_of_flow); - Ok(frames) } } impl PlaceNode { /// Whether this node wants to be placed relative to its its parent's base - /// origin. instead of relative to the parent's current flow/cursor + /// origin. Instead of relative to the parent's current flow/cursor /// position. pub fn out_of_flow(&self) -> bool { self.0 diff --git a/src/library/shape.rs b/src/library/shape.rs index 518254ce..955aef56 100644 --- a/src/library/shape.rs +++ b/src/library/shape.rs @@ -49,7 +49,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let mut frames; if let Some(child) = &self.0 { let mut padding = styles.get(Self::PADDING); @@ -60,48 +60,47 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> { // Pad the child. let child = child.clone().padded(Sides::splat(padding)); - let mut pod = Regions::one(regions.current, regions.base, regions.expand); + let mut pod = Regions::one(regions.first, regions.base, regions.expand); frames = child.layout(vm, &pod, styles)?; // Relayout with full expansion into square region to make sure // the result is really a square or circle. if is_quadratic(S) { let length = if regions.expand.x || regions.expand.y { - let target = regions.expand.select(regions.current, Size::zero()); + let target = regions.expand.select(regions.first, Size::zero()); target.x.max(target.y) } else { - let size = frames[0].item.size; + let size = frames[0].size; let desired = size.x.max(size.y); - desired.min(regions.current.x).min(regions.current.y) + desired.min(regions.first.x).min(regions.first.y) }; - pod.current = Size::splat(length); + pod.first = Size::splat(length); pod.expand = Spec::splat(true); frames = child.layout(vm, &pod, styles)?; - frames[0].cts = Constraints::tight(regions); } } else { // The default size that a shape takes on if it has no child and // enough space. let mut size = - Size::new(Length::pt(45.0), Length::pt(30.0)).min(regions.current); + Size::new(Length::pt(45.0), Length::pt(30.0)).min(regions.first); if is_quadratic(S) { let length = if regions.expand.x || regions.expand.y { - let target = regions.expand.select(regions.current, Size::zero()); + let target = regions.expand.select(regions.first, Size::zero()); target.x.max(target.y) } else { size.x.min(size.y) }; size = Size::splat(length); } else { - size = regions.expand.select(regions.current, size); + size = regions.expand.select(regions.first, size); } - frames = vec![Frame::new(size).constrain(Constraints::tight(regions))]; + frames = vec![Arc::new(Frame::new(size))]; } - let frame = Arc::make_mut(&mut frames[0].item); + let frame = Arc::make_mut(&mut frames[0]); // Add fill and/or stroke. let fill = styles.get(Self::FILL); diff --git a/src/library/stack.rs b/src/library/stack.rs index c7985d87..6768a0a0 100644 --- a/src/library/stack.rs +++ b/src/library/stack.rs @@ -31,7 +31,7 @@ impl Layout for StackNode { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let mut layouter = StackLayouter::new(self.dir, regions); // Spacing to insert before the next node. @@ -106,7 +106,7 @@ pub struct StackLayouter { /// fractional spacing. items: Vec<StackItem>, /// Finished frames for previous regions. - finished: Vec<Constrained<Arc<Frame>>>, + finished: Vec<Arc<Frame>>, } /// A prepared item in a stack layout. @@ -124,7 +124,7 @@ impl StackLayouter { pub fn new(dir: Dir, regions: &Regions) -> Self { let axis = dir.axis(); let expand = regions.expand; - let full = regions.current; + let full = regions.first; // Disable expansion along the block axis for children. let mut regions = regions.clone(); @@ -149,7 +149,7 @@ impl StackLayouter { SpacingKind::Linear(v) => { // Resolve the linear and limit it to the remaining space. let resolved = v.resolve(self.regions.base.get(self.axis)); - let remaining = self.regions.current.get_mut(self.axis); + let remaining = self.regions.first.get_mut(self.axis); let limited = resolved.min(*remaining); *remaining -= limited; self.used.main += limited; @@ -183,11 +183,11 @@ impl StackLayouter { let len = frames.len(); for (i, frame) in frames.into_iter().enumerate() { // Grow our size, shrink the region and save the frame for later. - let size = frame.item.size.to_gen(self.axis); + let size = frame.size.to_gen(self.axis); self.used.main += size.main; self.used.cross.set_max(size.cross); - *self.regions.current.get_mut(self.axis) -= size.main; - self.items.push(StackItem::Frame(frame.item, align)); + *self.regions.first.get_mut(self.axis) -= size.main; + self.items.push(StackItem::Frame(frame, align)); if i + 1 < len { self.finish_region(); @@ -245,21 +245,16 @@ impl StackLayouter { } } - // Generate tight constraints for now. - let mut cts = Constraints::new(self.expand); - cts.exact = self.full.map(Some); - cts.base = self.regions.base.map(Some); - // Advance to the next region. self.regions.next(); - self.full = self.regions.current; + self.full = self.regions.first; self.used = Gen::zero(); self.fr = Fractional::zero(); - self.finished.push(output.constrain(cts)); + self.finished.push(Arc::new(output)); } /// Finish layouting and return the resulting frames. - pub fn finish(mut self) -> Vec<Constrained<Arc<Frame>>> { + pub fn finish(mut self) -> Vec<Arc<Frame>> { self.finish_region(); self.finished } diff --git a/src/library/transform.rs b/src/library/transform.rs index 5cdb2f6f..84553fb5 100644 --- a/src/library/transform.rs +++ b/src/library/transform.rs @@ -49,11 +49,11 @@ impl<const T: TransformKind> Layout for TransformNode<T> { vm: &mut Vm, regions: &Regions, styles: StyleChain, - ) -> TypResult<Vec<Constrained<Arc<Frame>>>> { + ) -> TypResult<Vec<Arc<Frame>>> { let origin = styles.get(Self::ORIGIN).unwrap_or(Align::CENTER_HORIZON); let mut frames = self.child.layout(vm, regions, styles)?; - for Constrained { item: frame, .. } in &mut frames { + for frame in &mut frames { let Spec { x, y } = origin.zip(frame.size).map(|(o, s)| o.resolve(s)); let transform = Transform::translation(x, y) .pre_concat(self.transform) |
