From ebff8eb038706404cb4601cf6853675319663e3f Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 21 Nov 2019 17:23:44 +0100 Subject: [PATCH] =?UTF-8?q?Fix=20spacing=20bugs=20=F0=9F=9A=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/flex.rs | 23 +++++++++++------------ src/layout/mod.rs | 13 +++++++++++++ src/layout/stacked.rs | 25 +++++++++++++------------ src/layout/tree.rs | 9 ++------- src/library/axes.rs | 5 +++++ tests/layouts/align.typ | 2 +- tests/layouts/coma.typ | 6 +++--- tests/render.py | 2 +- 8 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/layout/flex.rs b/src/layout/flex.rs index 1d9f044d6..c3d88e1b6 100644 --- a/src/layout/flex.rs +++ b/src/layout/flex.rs @@ -41,8 +41,7 @@ struct PartialLine { usable: Size, content: Vec<(Size, Layout)>, dimensions: Size2D, - space: Option, - last_was_space: bool, + space: SpaceState, } impl PartialLine { @@ -51,8 +50,7 @@ impl PartialLine { usable, content: vec![], dimensions: Size2D::zero(), - space: None, - last_was_space: false, + space: SpaceState::Forbidden, } } } @@ -198,7 +196,7 @@ impl FlexLayouter { let remaining = self.axes.specialize(Size2D { x: self.part.usable - self.part.dimensions.x - - self.part.space.unwrap_or(Size::zero()), + - self.part.space.soft_or_zero(), y: self.line.combined_dimensions.y, }); @@ -235,9 +233,9 @@ impl FlexLayouter { fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> { let size = self.axes.generalize(boxed.dimensions); - let new_dimension = self.part.dimensions.x - + self.part.space.unwrap_or(Size::zero()); + + size.x + + self.part.space.soft_or_zero(); if new_dimension > self.part.usable { self.finish_line()?; @@ -251,7 +249,7 @@ impl FlexLayouter { } } - if let Some(space) = self.part.space.take() { + if let SpaceState::Soft(space) = self.part.space { self.layout_space(space, false); } @@ -260,15 +258,15 @@ impl FlexLayouter { self.part.dimensions.x += size.x; self.part.dimensions.y.max_eq(size.y); - self.part.last_was_space = false; + self.part.space = SpaceState::Allowed; Ok(()) } fn layout_space(&mut self, space: Size, soft: bool) { if soft { - if !self.part.last_was_space { - self.part.space = Some(space); + if self.part.space != SpaceState::Forbidden { + self.part.space = SpaceState::Soft(space); } } else { if self.part.dimensions.x + space > self.part.usable { @@ -276,7 +274,8 @@ impl FlexLayouter { } else { self.part.dimensions.x += space; } - self.part.last_was_space = true; + + self.part.space = SpaceState::Forbidden; } } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 2c725e1d8..04039d07f 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -307,6 +307,19 @@ pub enum Alignment { End, } +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum SpaceState { + Soft(Size), + Forbidden, + Allowed, +} + +impl SpaceState { + fn soft_or_zero(&self) -> Size { + if let SpaceState::Soft(space) = self { *space } else { Size::zero() } + } +} + /// The error type for layouting. pub enum LayoutError { /// An action is unallowed in the active context. diff --git a/src/layout/stacked.rs b/src/layout/stacked.rs index a7473b6f0..55e1b2b8a 100644 --- a/src/layout/stacked.rs +++ b/src/layout/stacked.rs @@ -36,8 +36,7 @@ struct Subspace { anchor: Size2D, factor: i32, dimensions: Size2D, - space: Option, - last_was_space: bool, + space: SpaceState, } impl Subspace { @@ -48,8 +47,7 @@ impl Subspace { anchor: axes.anchor(usable), factor: axes.secondary.axis.factor(), dimensions: Size2D::zero(), - space: None, - last_was_space: false, + space: SpaceState::Forbidden, } } } @@ -79,7 +77,7 @@ impl StackLayouter { } pub fn add(&mut self, layout: Layout) -> LayoutResult<()> { - if let Some(space) = self.sub.space.take() { + if let SpaceState::Soft(space) = self.sub.space { self.add_space(space, false); } @@ -92,6 +90,9 @@ impl StackLayouter { while !self.sub.usable.fits(new_dimensions) { if self.space_is_last() && self.space_is_empty() { + println!("usable: {}", self.sub.usable); + println!("dims: {}", new_dimensions); + println!("size: {}", size); Err(LayoutError::NotEnoughSpace("failed to add box to stack"))?; } @@ -109,7 +110,7 @@ impl StackLayouter { self.space.actions.add_layout(pos, layout); self.sub.dimensions = new_dimensions; - self.sub.last_was_space = false; + self.sub.space = SpaceState::Allowed; Ok(()) } @@ -123,17 +124,17 @@ impl StackLayouter { pub fn add_space(&mut self, space: Size, soft: bool) { if soft { - if !self.sub.last_was_space { - self.sub.space = Some(space); + if self.sub.space != SpaceState::Forbidden { + self.sub.space = SpaceState::Soft(space); } } else { if self.sub.dimensions.y + space > self.sub.usable.y { self.sub.dimensions.y = self.sub.usable.y; - self.finish_space(false); } else { self.sub.dimensions.y += space; } - self.sub.last_was_space = true; + + self.sub.space = SpaceState::Forbidden; } } @@ -197,8 +198,8 @@ impl StackLayouter { self.layouts.add(Layout { dimensions: match self.ctx.expand { - true => self.space.combined_dimensions.padded(space.padding), - false => space.dimensions, + true => space.dimensions, + false => self.space.combined_dimensions.padded(space.padding), }, actions: self.space.actions.to_vec(), debug_render: true, diff --git a/src/layout/tree.rs b/src/layout/tree.rs index 2edec6316..f6a8f4087 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -58,16 +58,11 @@ impl<'a, 'p> TreeLayouter<'a, 'p> { } fn layout_space(&mut self) { - if !self.flex.run_is_empty() { - self.flex.add_primary_space(word_spacing(&self.style), true); - } + self.flex.add_primary_space(word_spacing(&self.style), true); } fn layout_paragraph(&mut self) -> LayoutResult<()> { - if !self.flex.run_is_empty() { - self.flex.add_secondary_space(paragraph_spacing(&self.style), true)?; - } - Ok(()) + self.flex.add_secondary_space(paragraph_spacing(&self.style), true) } fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> { diff --git a/src/library/axes.rs b/src/library/axes.rs index 1f3525f67..65dfa800f 100644 --- a/src/library/axes.rs +++ b/src/library/axes.rs @@ -31,6 +31,11 @@ function! { let mut axes = ctx.axes; axes.primary.alignment = this.alignment; + if ctx.axes.primary.alignment == Alignment::End + && this.alignment == Alignment::Origin { + axes.primary.expand = true; + } + Ok(match &this.body { Some(body) => commands![AddMultiple( layout_tree(body, LayoutContext { diff --git a/tests/layouts/align.typ b/tests/layouts/align.typ index 34c2f16fe..9d6ab0033 100644 --- a/tests/layouts/align.typ +++ b/tests/layouts/align.typ @@ -20,7 +20,7 @@ Context Right: {lorem:10} -[align: left][In-between Left: {lorem:10}] +[align: left][In-between Left] Right Again: {lorem:10} diff --git a/tests/layouts/coma.typ b/tests/layouts/coma.typ index 237b24f45..d0a02b74b 100644 --- a/tests/layouts/coma.typ +++ b/tests/layouts/coma.typ @@ -10,11 +10,11 @@ ] [align: right][*WiSe 2019/2020* [n] Week 1] -[v: 3mm] +[v: 6mm] [align: center][ - *3. Ubungsblatt Computerorientierte Mathematik II* [n] - *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) [n] + *3. Ubungsblatt Computerorientierte Mathematik II* [v: 0.3mm] + *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) [v: 0.3mm] *Alle Antworten sind zu beweisen.* ] diff --git a/tests/render.py b/tests/render.py index 15467836a..19f06f2b3 100644 --- a/tests/render.py +++ b/tests/render.py @@ -43,7 +43,7 @@ class MultiboxRenderer: images = [] layout_count = int(self.content[0]) - horizontal = math.ceil(math.sqrt(layout_count)) + horizontal = math.floor(math.sqrt(layout_count)) start = 1 for _ in range(layout_count):