diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-10-12 17:29:01 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-10-12 17:29:01 +0200 |
| commit | 5243878d810d4817c81acc9ae346d46757fcf602 (patch) | |
| tree | 4a8be00ab7262030a6ba8c6638b969a03ac1d9b5 /src/layout | |
| parent | 38157b0e0cbab22dc3f5fa5cc66d9b673a18a55b (diff) | |
Less vecs in layouting ⚡
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/document.rs | 2 | ||||
| -rw-r--r-- | src/layout/fixed.rs | 2 | ||||
| -rw-r--r-- | src/layout/mod.rs | 11 | ||||
| -rw-r--r-- | src/layout/node.rs | 2 | ||||
| -rw-r--r-- | src/layout/pad.rs | 51 | ||||
| -rw-r--r-- | src/layout/par.rs | 21 | ||||
| -rw-r--r-- | src/layout/spacing.rs | 4 | ||||
| -rw-r--r-- | src/layout/stack.rs | 21 | ||||
| -rw-r--r-- | src/layout/text.rs | 6 |
9 files changed, 71 insertions, 49 deletions
diff --git a/src/layout/document.rs b/src/layout/document.rs index b233ffd8..407dcda4 100644 --- a/src/layout/document.rs +++ b/src/layout/document.rs @@ -34,6 +34,6 @@ impl Pages { pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<BoxLayout> { let areas = Areas::repeat(self.size); let layouted = self.child.layout(ctx, &areas); - layouted.into_iter().filter_map(Layouted::into_boxed).collect() + layouted.into_boxes() } } diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs index df099731..8a42a9d3 100644 --- a/src/layout/fixed.rs +++ b/src/layout/fixed.rs @@ -13,7 +13,7 @@ pub struct Fixed { } impl Layout for Fixed { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted> { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { let Area { rem, full } = areas.current; let size = Size::new( self.width.map(|w| w.eval(full.width)).unwrap_or(rem.width), diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 643f1a43..de112083 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -38,7 +38,7 @@ pub struct LayoutContext { /// Layout a node. pub trait Layout { /// Layout the node in the given layout context. - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted>; + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted; } /// A sequence of areas to layout into. @@ -129,14 +129,17 @@ pub enum Layouted { Spacing(Length), /// A box that should be added to and aligned in the parent. Boxed(BoxLayout, Gen<Align>), + /// Multiple boxes. + Boxes(Vec<(BoxLayout, Gen<Align>)>), } impl Layouted { /// Return the box if this if its a box variant. - pub fn into_boxed(self) -> Option<BoxLayout> { + pub fn into_boxes(self) -> Vec<BoxLayout> { match self { - Self::Spacing(_) => None, - Self::Boxed(boxed, _) => Some(boxed), + Self::Spacing(_) => vec![], + Self::Boxed(boxed, _) => vec![boxed], + Self::Boxes(boxes) => boxes.into_iter().map(|p| p.0).collect(), } } } diff --git a/src/layout/node.rs b/src/layout/node.rs index 4cba3d4f..aa4b990f 100644 --- a/src/layout/node.rs +++ b/src/layout/node.rs @@ -25,7 +25,7 @@ impl LayoutNode { } impl Layout for LayoutNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted> { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { match self { Self::Spacing(spacing) => spacing.layout(ctx, areas), Self::Text(text) => text.layout(ctx, areas), diff --git a/src/layout/pad.rs b/src/layout/pad.rs index 2994dd59..b26bea71 100644 --- a/src/layout/pad.rs +++ b/src/layout/pad.rs @@ -11,27 +11,16 @@ pub struct Pad { } impl Layout for Pad { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted> { - let shrink = |size| size - self.padding.eval(size).size(); - let areas = Areas { - current: Area { - rem: shrink(areas.current.rem), - full: shrink(areas.current.full), - }, - backlog: areas.backlog.iter().copied().map(shrink).collect(), - last: areas.last.map(shrink), - }; + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { + let areas = shrink_areas(areas, self.padding); let mut layouted = self.child.layout(ctx, &areas); - - for item in &mut layouted { - if let Layouted::Boxed(boxed, _) = item { - let padding = self.padding.eval(boxed.size); - let origin = Point::new(padding.left, padding.top); - - boxed.size += padding.size(); - for (point, _) in &mut boxed.elements { - *point += origin; + match &mut layouted { + Layouted::Spacing(_) => {} + Layouted::Boxed(boxed, _) => pad_box(boxed, self.padding), + Layouted::Boxes(boxes) => { + for (boxed, _) in boxes { + pad_box(boxed, self.padding); } } } @@ -40,6 +29,30 @@ impl Layout for Pad { } } +/// Shrink all areas by the padding. +fn shrink_areas(areas: &Areas, padding: Sides<Linear>) -> Areas { + let shrink = |size| size - padding.eval(size).size(); + Areas { + current: Area { + rem: shrink(areas.current.rem), + full: shrink(areas.current.full), + }, + backlog: areas.backlog.iter().copied().map(shrink).collect(), + last: areas.last.map(shrink), + } +} + +/// Enlarge the box and move all elements inwards. +fn pad_box(boxed: &mut BoxLayout, padding: Sides<Linear>) { + let padding = padding.eval(boxed.size); + let origin = Point::new(padding.left, padding.top); + + boxed.size += padding.size(); + for (point, _) in &mut boxed.elements { + *point += origin; + } +} + impl From<Pad> for LayoutNode { fn from(pad: Pad) -> Self { Self::dynamic(pad) diff --git a/src/layout/par.rs b/src/layout/par.rs index e77bb4e7..ad71cffc 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -19,17 +19,20 @@ pub struct Par { } impl Layout for Par { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted> { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { let mut layouter = ParLayouter::new(self, areas.clone()); for child in &self.children { - for layouted in child.layout(ctx, &layouter.areas) { - match layouted { - Layouted::Spacing(spacing) => layouter.spacing(spacing), - Layouted::Boxed(boxed, aligns) => layouter.boxed(boxed, aligns.cross), + match child.layout(ctx, &layouter.areas) { + Layouted::Spacing(spacing) => layouter.spacing(spacing), + Layouted::Boxed(boxed, aligns) => layouter.boxed(boxed, aligns.cross), + Layouted::Boxes(boxes) => { + for (boxed, aligns) in boxes { + layouter.boxed(boxed, aligns.cross); + } } } } - layouter.finish() + Layouted::Boxes(layouter.finish()) } } @@ -45,7 +48,7 @@ struct ParLayouter<'a> { cross: SpecAxis, dirs: Gen<Dir>, areas: Areas, - layouted: Vec<Layouted>, + layouted: Vec<(BoxLayout, Gen<Align>)>, lines: Vec<(Length, BoxLayout, Align)>, lines_size: Gen<Length>, run: Vec<(Length, BoxLayout, Align)>, @@ -169,13 +172,13 @@ impl<'a> ParLayouter<'a> { output.push_layout(pos, run); } - self.layouted.push(Layouted::Boxed(output, self.par.aligns)); + self.layouted.push((output, self.par.aligns)); self.areas.next(); self.lines_size = Gen::ZERO; } - fn finish(mut self) -> Vec<Layouted> { + fn finish(mut self) -> Vec<(BoxLayout, Gen<Align>)> { self.finish_run(); self.finish_area(); self.layouted diff --git a/src/layout/spacing.rs b/src/layout/spacing.rs index f64c7968..c44f92e4 100644 --- a/src/layout/spacing.rs +++ b/src/layout/spacing.rs @@ -15,8 +15,8 @@ pub struct Spacing { } impl Layout for Spacing { - fn layout(&self, _: &mut LayoutContext, _: &Areas) -> Vec<Layouted> { - vec![Layouted::Spacing(self.amount)] + fn layout(&self, _: &mut LayoutContext, _: &Areas) -> Layouted { + Layouted::Spacing(self.amount) } } diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 9aeb80aa..228293bc 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -17,17 +17,20 @@ pub struct Stack { } impl Layout for Stack { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Layouted> { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted { let mut layouter = StackLayouter::new(self, areas.clone()); for child in &self.children { - for layouted in child.layout(ctx, &layouter.areas) { - match layouted { - Layouted::Spacing(spacing) => layouter.spacing(spacing), - Layouted::Boxed(boxed, aligns) => layouter.boxed(boxed, aligns), + match child.layout(ctx, &layouter.areas) { + Layouted::Spacing(spacing) => layouter.spacing(spacing), + Layouted::Boxed(boxed, aligns) => layouter.boxed(boxed, aligns), + Layouted::Boxes(boxes) => { + for (boxed, aligns) in boxes { + layouter.boxed(boxed, aligns); + } } } } - layouter.finish() + Layouted::Boxes(layouter.finish()) } } @@ -42,7 +45,7 @@ struct StackLayouter<'a> { main: SpecAxis, dirs: Gen<Dir>, areas: Areas, - layouted: Vec<Layouted>, + layouted: Vec<(BoxLayout, Gen<Align>)>, boxes: Vec<(Length, BoxLayout, Gen<Align>)>, used: Gen<Length>, ruler: Align, @@ -134,14 +137,14 @@ impl<'a> StackLayouter<'a> { output.push_layout(pos, layout); } - self.layouted.push(Layouted::Boxed(output, self.stack.aligns)); + self.layouted.push((output, self.stack.aligns)); self.areas.next(); self.used = Gen::ZERO; self.ruler = Align::Start; } - fn finish(mut self) -> Vec<Layouted> { + fn finish(mut self) -> Vec<(BoxLayout, Gen<Align>)> { self.finish_area(); self.layouted } diff --git a/src/layout/text.rs b/src/layout/text.rs index 5e047069..31ae19cd 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -24,9 +24,9 @@ pub struct Text { } impl Layout for Text { - fn layout(&self, ctx: &mut LayoutContext, _: &Areas) -> Vec<Layouted> { + fn layout(&self, ctx: &mut LayoutContext, _: &Areas) -> Layouted { let mut loader = ctx.loader.borrow_mut(); - vec![Layouted::Boxed( + Layouted::Boxed( shaping::shape( &mut loader, &self.text, @@ -36,7 +36,7 @@ impl Layout for Text { self.variant, ), self.aligns, - )] + ) } } |
