diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-09 18:16:59 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-09 18:20:02 +0100 |
| commit | 010cc2effc2fd0e1c4e52d5c914cb4d74506bc0a (patch) | |
| tree | e50060d271f076b00945e5569e7f8ffef2c28e9f /library/src/layout/flow.rs | |
| parent | 12a59963b08b68cc39dcded4d3d3e6a6631c2732 (diff) | |
New block spacing model
Diffstat (limited to 'library/src/layout/flow.rs')
| -rw-r--r-- | library/src/layout/flow.rs | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index 347c1dd8..cc5dcd50 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; -use super::{AlignNode, PlaceNode, Spacing}; +use super::{AlignNode, PlaceNode, Spacing, VNode}; +use crate::layout::BlockNode; use crate::prelude::*; use crate::text::ParNode; @@ -15,7 +16,7 @@ pub struct FlowNode(pub StyleVec<FlowChild>); #[derive(Hash, PartialEq)] pub enum FlowChild { /// Vertical spacing between other children. - Spacing(Spacing), + Spacing(VNode), /// Arbitrary block-level content. Block(Content), /// A column / region break. @@ -32,13 +33,13 @@ impl LayoutBlock for FlowNode { regions: &Regions, styles: StyleChain, ) -> SourceResult<Vec<Frame>> { - let mut layouter = FlowLayouter::new(regions); + let mut layouter = FlowLayouter::new(regions, styles); for (child, map) in self.0.iter() { let styles = map.chain(&styles); match child { - FlowChild::Spacing(kind) => { - layouter.layout_spacing(*kind, styles); + FlowChild::Spacing(node) => { + layouter.layout_spacing(node, styles); } FlowChild::Block(block) => { layouter.layout_block(world, block, styles)?; @@ -80,9 +81,11 @@ impl PartialOrd for FlowChild { } /// Performs flow layout. -struct FlowLayouter { +struct FlowLayouter<'a> { /// The regions to layout children into. regions: Regions, + /// The shared styles. + shared: StyleChain<'a>, /// Whether the flow should expand to fill the region. expand: Axes<bool>, /// The full size of `regions.size` that was available before we started @@ -92,6 +95,8 @@ struct FlowLayouter { used: Size, /// The sum of fractions in the current region. fr: Fr, + /// The spacing below the last block. + below: Option<VNode>, /// Spacing and layouted blocks. items: Vec<FlowItem>, /// Finished frames for previous regions. @@ -110,9 +115,9 @@ enum FlowItem { Placed(Frame), } -impl FlowLayouter { +impl<'a> FlowLayouter<'a> { /// Create a new flow layouter. - fn new(regions: &Regions) -> Self { + fn new(regions: &Regions, shared: StyleChain<'a>) -> Self { let expand = regions.expand; let full = regions.first; @@ -122,18 +127,20 @@ impl FlowLayouter { Self { regions, + shared, expand, full, used: Size::zero(), fr: Fr::zero(), + below: None, items: vec![], finished: vec![], } } /// Layout spacing. - fn layout_spacing(&mut self, spacing: Spacing, styles: StyleChain) { - match spacing { + fn layout_spacing(&mut self, node: &VNode, styles: StyleChain) { + match node.amount { Spacing::Relative(v) => { // Resolve the spacing and limit it to the remaining space. let resolved = v.resolve(styles).relative_to(self.full.y); @@ -147,6 +154,10 @@ impl FlowLayouter { self.fr += v; } } + + if node.weak || node.amount.is_fractional() { + self.below = None; + } } /// Layout a block. @@ -161,9 +172,19 @@ impl FlowLayouter { self.finish_region(); } + // Add spacing between the last block and this one. + if let Some(below) = self.below.take() { + let above = styles.get(BlockNode::ABOVE); + let pick_below = (above.weak && !below.weak) || (below.amount > above.amount); + let spacing = if pick_below { below } else { above }; + self.layout_spacing(&spacing, self.shared); + } + // Placed nodes that are out of flow produce placed items which aren't // aligned later. + let mut is_placed = false; if let Some(placed) = block.downcast::<PlaceNode>() { + is_placed = true; if placed.out_of_flow() { let frame = block.layout_block(world, &self.regions, styles)?.remove(0); self.items.push(FlowItem::Placed(frame)); @@ -202,6 +223,10 @@ impl FlowLayouter { } } + if !is_placed { + self.below = Some(styles.get(BlockNode::BELOW)); + } + Ok(()) } @@ -250,6 +275,7 @@ impl FlowLayouter { self.full = self.regions.first; self.used = Size::zero(); self.fr = Fr::zero(); + self.below = None; self.finished.push(output); } |
