diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-06-22 12:25:01 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-06-22 12:25:01 +0200 |
| commit | f6fe3b5cdd2805f3975985752f9cb0e04e3daf49 (patch) | |
| tree | daddf46ba6add0b7cead1f9015b8f24364672138 /src/layout/mod.rs | |
| parent | e39a6efccff7ba2b5dd546ddf86f23d2714161e7 (diff) | |
Implement function layouting ✒
Diffstat (limited to 'src/layout/mod.rs')
| -rw-r--r-- | src/layout/mod.rs | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index f8819d0b..40948a13 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -70,6 +70,7 @@ struct Layouter<'a, 'p> { flex_layout: FlexLayout, flex_ctx: FlexContext, text_ctx: TextContext<'a, 'p>, + func_ctx: LayoutContext<'a, 'p>, } impl<'a, 'p> Layouter<'a, 'p> { @@ -85,7 +86,7 @@ impl<'a, 'p> Layouter<'a, 'p> { padding: SizeBox::zero(), shrink_to_fit: true, }, - flex_spacing: ctx.style.line_spacing, + flex_spacing: (ctx.style.line_spacing - 1.0) * Size::points(ctx.style.font_size), }; // The mutable context for layouting single pieces of text. @@ -94,12 +95,24 @@ impl<'a, 'p> Layouter<'a, 'p> { style: ctx.style.clone(), }; + // The mutable context for layouting single functions. + let func_ctx = LayoutContext { + loader: &ctx.loader, + style: ctx.style.clone(), + space: LayoutSpace { + dimensions: ctx.space.usable(), + padding: SizeBox::zero(), + shrink_to_fit: true, + }, + }; + Layouter { tree, box_layouter: BoxLayouter::new(box_ctx), - flex_layout: FlexLayout::new(flex_ctx), + flex_layout: FlexLayout::new(), flex_ctx, text_ctx, + func_ctx, } } @@ -124,28 +137,53 @@ impl<'a, 'p> Layouter<'a, 'p> { // Then start a new flex layouting process. Node::Newline => { // Finish the current paragraph into a box and add it. - self.add_paragraph_spacing()?; - let boxed = self.flex_layout.into_box()?; + let boxed = self.flex_layout.finish(self.flex_ctx)?; self.box_layouter.add_box(boxed)?; // Create a fresh flex layout for the next paragraph. self.flex_ctx.space.dimensions = self.box_layouter.remaining(); - self.flex_layout = FlexLayout::new(self.flex_ctx); + self.flex_layout = FlexLayout::new(); + self.add_paragraph_spacing()?; }, // Toggle the text styles. - Node::ToggleItalics => self.text_ctx.style.italic = !self.text_ctx.style.italic, - Node::ToggleBold => self.text_ctx.style.bold = !self.text_ctx.style.bold, + Node::ToggleItalics => { + self.text_ctx.style.italic = !self.text_ctx.style.italic; + self.func_ctx.style.italic = !self.func_ctx.style.italic; + }, + Node::ToggleBold => { + self.text_ctx.style.bold = !self.text_ctx.style.bold; + self.func_ctx.style.bold = !self.func_ctx.style.bold; + }, // Execute a function. - Node::Func(_) => unimplemented!(), + Node::Func(func) => { + self.func_ctx.space.dimensions = self.box_layouter.remaining(); + let layout = func.body.layout(&self.func_ctx)?; + + // Add the potential layout. + if let Some(layout) = layout { + match layout { + Layout::Boxed(boxed) => { + // Finish the previous flex run before adding the box. + let previous = self.flex_layout.finish(self.flex_ctx)?; + self.box_layouter.add_box(previous)?; + self.box_layouter.add_box(boxed)?; + + // Create a fresh flex layout for the following content. + self.flex_ctx.space.dimensions = self.box_layouter.remaining(); + self.flex_layout = FlexLayout::new(); + }, + Layout::Flex(flex) => self.flex_layout.add_flexible(flex), + } + } + }, } } // If there are remainings, add them to the layout. if !self.flex_layout.is_empty() { - self.add_paragraph_spacing()?; - let boxed = self.flex_layout.into_box()?; + let boxed = self.flex_layout.finish(self.flex_ctx)?; self.box_layouter.add_box(boxed)?; } |
