summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/flex.rs43
-rw-r--r--src/layout/tree.rs11
2 files changed, 32 insertions, 22 deletions
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 39c16aef..a6f2e091 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -73,6 +73,8 @@ enum FlexUnit {
/// is only present if there was no flow break in between the two
/// surrounding boxes.
Glue(Size2D),
+ /// A forced break of the current flex run.
+ Break,
}
#[derive(Debug, Clone)]
@@ -114,6 +116,11 @@ impl FlexLayouter {
self.units.push(FlexUnit::Glue(glue));
}
+ /// Add a forced line break.
+ pub fn add_break(&mut self) {
+ self.units.push(FlexUnit::Break);
+ }
+
/// Compute the justified layout.
///
/// The layouter is not consumed by this to prevent ownership problems
@@ -127,6 +134,7 @@ impl FlexLayouter {
match unit {
FlexUnit::Boxed(boxed) => self.layout_box(boxed)?,
FlexUnit::Glue(glue) => self.layout_glue(glue),
+ FlexUnit::Break => self.layout_break()?,
}
}
@@ -157,14 +165,12 @@ impl FlexLayouter {
}
self.finish_run()?;
- } else {
- // Only add the glue if we did not move to a new line.
- self.flush_glue();
}
+ self.flush_glue();
+
let dimensions = boxed.dimensions;
self.run.content.push((self.run.size.x, boxed));
-
self.grow_run(dimensions);
Ok(())
@@ -174,20 +180,12 @@ impl FlexLayouter {
self.cached_glue = Some(glue);
}
- fn flush_glue(&mut self) {
- if let Some(glue) = self.cached_glue.take() {
- let new_line_width = self.run.size.x + glue.x;
- if !self.overflows_line(new_line_width) {
- self.grow_run(glue);
- }
- }
- }
-
- fn grow_run(&mut self, dimensions: Size2D) {
- self.run.size.x += dimensions.x;
- self.run.size.y = crate::size::max(self.run.size.y, dimensions.y);
+ fn layout_break(&mut self) -> LayoutResult<()> {
+ self.cached_glue = None;
+ self.finish_run()
}
+ /// Finish the current flex run.
fn finish_run(&mut self) -> LayoutResult<()> {
self.run.size.y += self.ctx.flex_spacing;
@@ -208,6 +206,19 @@ impl FlexLayouter {
Ok(())
}
+ fn flush_glue(&mut self) {
+ if let Some(glue) = self.cached_glue.take() {
+ if self.run.size.x > Size::zero() && !self.overflows_line(self.run.size.x + glue.x) {
+ self.grow_run(glue);
+ }
+ }
+ }
+
+ fn grow_run(&mut self, dimensions: Size2D) {
+ self.run.size.x += dimensions.x;
+ self.run.size.y = crate::size::max(self.run.size.y, dimensions.y);
+ }
+
/// Whether this layouter contains any items.
pub fn is_empty(&self) -> bool {
self.units.is_empty()
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index bd4adb8a..2c904369 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -88,6 +88,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> {
// Finish the current flex layout on a copy to find out how
// much space would be remaining if we finished.
+
let mut lookahead_stack = self.stack.clone();
let layouts = self.flex.clone().finish()?;
lookahead_stack.add_many(layouts)?;
@@ -106,9 +107,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
for command in commands {
match command {
- Command::Layout(tree) => {
- self.layout(tree)?;
- }
+ Command::Layout(tree) => self.layout(tree)?,
Command::Add(layout) => {
self.finish_flex()?;
@@ -130,15 +129,15 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
self.start_new_flex();
}
- Command::SetStyle(style) => {
- *self.style.to_mut() = style;
- }
+ Command::SetStyle(style) => *self.style.to_mut() = style,
Command::FinishLayout => {
self.finish_flex()?;
self.stack.finish_layout(true)?;
self.start_new_flex();
}
+
+ Command::FinishFlexRun => self.flex.add_break(),
}
}