diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-03-25 21:32:33 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-03-25 21:32:33 +0100 |
| commit | 76fc4cca62f5b955200b2c62cc85b69eea491ece (patch) | |
| tree | 5b8492268c996cf23b13e26c7a4356fbd156286d /src/layout | |
| parent | e8057a53856dc09594c9e5861f1cd328531616e0 (diff) | |
Refactor alignments & directions 📐
- Adds lang function
- Refactors execution context
- Adds StackChild and ParChild enums
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/background.rs | 10 | ||||
| -rw-r--r-- | src/layout/fixed.rs | 4 | ||||
| -rw-r--r-- | src/layout/mod.rs | 121 | ||||
| -rw-r--r-- | src/layout/node.rs | 108 | ||||
| -rw-r--r-- | src/layout/pad.rs | 12 | ||||
| -rw-r--r-- | src/layout/par.rs | 127 | ||||
| -rw-r--r-- | src/layout/spacing.rs | 35 | ||||
| -rw-r--r-- | src/layout/stack.rs | 76 | ||||
| -rw-r--r-- | src/layout/text.rs | 36 |
9 files changed, 195 insertions, 334 deletions
diff --git a/src/layout/background.rs b/src/layout/background.rs index 17280a86..d3408182 100644 --- a/src/layout/background.rs +++ b/src/layout/background.rs @@ -8,7 +8,7 @@ pub struct BackgroundNode { /// The background fill. pub fill: Fill, /// The child node to be filled. - pub child: Node, + pub child: AnyNode, } /// The kind of shape to use as a background. @@ -19,10 +19,10 @@ pub enum BackgroundShape { } impl Layout for BackgroundNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { - let mut fragment = self.child.layout(ctx, areas); + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { + let mut frames = self.child.layout(ctx, areas); - for frame in fragment.frames_mut() { + for frame in &mut frames { let (point, shape) = match self.shape { BackgroundShape::Rect => (Point::ZERO, Shape::Rect(frame.size)), BackgroundShape::Ellipse => { @@ -34,7 +34,7 @@ impl Layout for BackgroundNode { frame.elements.insert(0, (point, element)); } - fragment + frames } } diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs index 22c45ef1..04ea5a3a 100644 --- a/src/layout/fixed.rs +++ b/src/layout/fixed.rs @@ -12,11 +12,11 @@ pub struct FixedNode { /// The resulting frame will satisfy `width = aspect * height`. pub aspect: Option<f64>, /// The child node whose size to fix. - pub child: Node, + pub child: AnyNode, } impl Layout for FixedNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { let Areas { current, full, .. } = areas; let full = Size::new( diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 360c9d84..6f28fcb9 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -3,24 +3,21 @@ mod background; mod fixed; mod frame; -mod node; mod pad; mod par; mod shaping; -mod spacing; mod stack; -mod text; pub use background::*; pub use fixed::*; pub use frame::*; -pub use node::*; pub use pad::*; pub use par::*; pub use shaping::*; -pub use spacing::*; pub use stack::*; -pub use text::*; + +use std::any::Any; +use std::fmt::{self, Debug, Formatter}; use crate::env::Env; use crate::geom::*; @@ -51,25 +48,88 @@ pub struct PageRun { pub size: Size, /// The layout node that produces the actual pages (typically a /// [`StackNode`]). - pub child: Node, + pub child: AnyNode, } impl PageRun { /// Layout the page run. pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> { let areas = Areas::repeat(self.size, Spec::uniform(Expand::Fill)); - self.child.layout(ctx, &areas).into_frames() + self.child.layout(ctx, &areas) + } +} + +/// A wrapper around a dynamic layouting node. +pub struct AnyNode(Box<dyn Bounds>); + +impl AnyNode { + /// Create a new instance from any node that satisifies the required bounds. + pub fn new<T>(any: T) -> Self + where + T: Layout + Debug + Clone + PartialEq + 'static, + { + Self(Box::new(any)) + } +} + +impl Layout for AnyNode { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { + self.0.layout(ctx, areas) + } +} + +impl Clone for AnyNode { + fn clone(&self) -> Self { + Self(self.0.dyn_clone()) + } +} + +impl PartialEq for AnyNode { + fn eq(&self, other: &Self) -> bool { + self.0.dyn_eq(other.0.as_ref()) + } +} + +impl Debug for AnyNode { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +trait Bounds: Layout + Debug + 'static { + fn as_any(&self) -> &dyn Any; + fn dyn_eq(&self, other: &dyn Bounds) -> bool; + fn dyn_clone(&self) -> Box<dyn Bounds>; +} + +impl<T> Bounds for T +where + T: Layout + Debug + PartialEq + Clone + 'static, +{ + fn as_any(&self) -> &dyn Any { + self + } + + fn dyn_eq(&self, other: &dyn Bounds) -> bool { + if let Some(other) = other.as_any().downcast_ref::<Self>() { + self == other + } else { + false + } + } + + fn dyn_clone(&self) -> Box<dyn Bounds> { + Box::new(self.clone()) } } /// Layout a node. pub trait Layout { /// Layout the node into the given areas. - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment; + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame>; } /// The context for layouting. -#[derive(Debug)] pub struct LayoutContext<'a> { /// The environment from which fonts are gathered. pub env: &'a mut Env, @@ -183,44 +243,3 @@ impl Expand { } } } - -/// The result of layouting a node. -#[derive(Debug, Clone, PartialEq)] -pub enum Fragment { - /// Spacing that should be added to the parent. - Spacing(Length), - /// A layout that should be added to and aligned in the parent. - Frame(Frame, LayoutAligns), - /// Multiple layouts. - Frames(Vec<Frame>, LayoutAligns), -} - -impl Fragment { - /// Return a reference to all frames contained in this variant (zero, one or - /// arbitrarily many). - pub fn frames(&self) -> &[Frame] { - match self { - Self::Spacing(_) => &[], - Self::Frame(frame, _) => std::slice::from_ref(frame), - Self::Frames(frames, _) => frames, - } - } - - /// Return a mutable reference to all frames contained in this variant. - pub fn frames_mut(&mut self) -> &mut [Frame] { - match self { - Self::Spacing(_) => &mut [], - Self::Frame(frame, _) => std::slice::from_mut(frame), - Self::Frames(frames, _) => frames, - } - } - - /// Return all frames contained in this varian. - pub fn into_frames(self) -> Vec<Frame> { - match self { - Self::Spacing(_) => vec![], - Self::Frame(frame, _) => vec![frame], - Self::Frames(frames, _) => frames, - } - } -} diff --git a/src/layout/node.rs b/src/layout/node.rs deleted file mode 100644 index 443a96ae..00000000 --- a/src/layout/node.rs +++ /dev/null @@ -1,108 +0,0 @@ -use std::any::Any; -use std::fmt::{self, Debug, Formatter}; - -use super::*; - -/// A self-contained layout node. -#[derive(Clone, PartialEq)] -pub enum Node { - /// A text node. - Text(TextNode), - /// A spacing node. - Spacing(SpacingNode), - /// A dynamic node that can implement custom layouting behaviour. - Any(AnyNode), -} - -impl Layout for Node { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { - match self { - Self::Spacing(spacing) => spacing.layout(ctx, areas), - Self::Text(text) => text.layout(ctx, areas), - Self::Any(any) => any.layout(ctx, areas), - } - } -} - -impl Debug for Node { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Spacing(spacing) => spacing.fmt(f), - Self::Text(text) => text.fmt(f), - Self::Any(any) => any.fmt(f), - } - } -} - -/// A wrapper around a dynamic layouting node. -pub struct AnyNode(Box<dyn Bounds>); - -impl AnyNode { - /// Create a new instance from any node that satisifies the required bounds. - pub fn new<T>(any: T) -> Self - where - T: Layout + Debug + Clone + PartialEq + 'static, - { - Self(Box::new(any)) - } -} - -impl Layout for AnyNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { - self.0.layout(ctx, areas) - } -} - -impl Clone for AnyNode { - fn clone(&self) -> Self { - Self(self.0.dyn_clone()) - } -} - -impl PartialEq for AnyNode { - fn eq(&self, other: &Self) -> bool { - self.0.dyn_eq(other.0.as_ref()) - } -} - -impl Debug for AnyNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.0.fmt(f) - } -} - -impl<T> From<T> for Node -where - T: Into<AnyNode>, -{ - fn from(t: T) -> Self { - Self::Any(t.into()) - } -} - -trait Bounds: Layout + Debug + 'static { - fn as_any(&self) -> &dyn Any; - fn dyn_eq(&self, other: &dyn Bounds) -> bool; - fn dyn_clone(&self) -> Box<dyn Bounds>; -} - -impl<T> Bounds for T -where - T: Layout + Debug + PartialEq + Clone + 'static, -{ - fn as_any(&self) -> &dyn Any { - self - } - - fn dyn_eq(&self, other: &dyn Bounds) -> bool { - if let Some(other) = other.as_any().downcast_ref::<Self>() { - self == other - } else { - false - } - } - - fn dyn_clone(&self) -> Box<dyn Bounds> { - Box::new(self.clone()) - } -} diff --git a/src/layout/pad.rs b/src/layout/pad.rs index fb038996..2c8712af 100644 --- a/src/layout/pad.rs +++ b/src/layout/pad.rs @@ -6,19 +6,17 @@ pub struct PadNode { /// The amount of padding. pub padding: Sides<Linear>, /// The child node whose sides to pad. - pub child: Node, + pub child: AnyNode, } impl Layout for PadNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { let areas = shrink(areas, self.padding); - - let mut fragment = self.child.layout(ctx, &areas); - for frame in fragment.frames_mut() { + let mut frames = self.child.layout(ctx, &areas); + for frame in &mut frames { pad(frame, self.padding); } - - fragment + frames } } diff --git a/src/layout/par.rs b/src/layout/par.rs index 0364a03a..02e27cbd 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -1,38 +1,63 @@ +use std::fmt::{self, Debug, Formatter}; + use super::*; +use crate::exec::FontProps; /// A node that arranges its children into a paragraph. #[derive(Debug, Clone, PartialEq)] pub struct ParNode { - /// The `main` and `cross` directions of this paragraph. - /// - /// The children are placed in lines along the `cross` direction. The lines - /// are stacked along the `main` direction. - pub dirs: LayoutDirs, - /// How to align this paragraph in its parent. - pub aligns: LayoutAligns, - /// The spacing to insert after each line. + /// The inline direction of this paragraph. + pub dir: Dir, + /// The spacing to insert between each line. pub line_spacing: Length, /// The nodes to be arranged in a paragraph. - pub children: Vec<Node>, + pub children: Vec<ParChild>, +} + +/// A child of a paragraph node. +#[derive(Debug, Clone, PartialEq)] +pub enum ParChild { + /// Spacing between other nodes. + Spacing(Length), + /// A run of text and how to align it in its line. + Text(TextNode, Align), + /// Any child node and how to align it in its line. + Any(AnyNode, Align), +} + +/// A consecutive, styled run of text. +#[derive(Clone, PartialEq)] +pub struct TextNode { + /// The text. + pub text: String, + /// Properties used for font selection and layout. + pub props: FontProps, +} + +impl Debug for TextNode { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "Text({})", self.text) + } } impl Layout for ParNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { - let mut layouter = ParLayouter::new(self.dirs, self.line_spacing, areas.clone()); + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { + let mut layouter = ParLayouter::new(self.dir, self.line_spacing, areas.clone()); for child in &self.children { - match child.layout(ctx, &layouter.areas) { - Fragment::Spacing(spacing) => layouter.push_spacing(spacing), - Fragment::Frame(frame, aligns) => { - layouter.push_frame(frame, aligns.cross) + match *child { + ParChild::Spacing(amount) => layouter.push_spacing(amount), + ParChild::Text(ref node, align) => { + let frame = shape(&node.text, &mut ctx.env.fonts, &node.props); + layouter.push_frame(frame, align); } - Fragment::Frames(frames, aligns) => { - for frame in frames { - layouter.push_frame(frame, aligns.cross); + ParChild::Any(ref node, align) => { + for frame in node.layout(ctx, &layouter.areas) { + layouter.push_frame(frame, align); } } } } - Fragment::Frames(layouter.finish(), self.aligns) + layouter.finish() } } @@ -43,30 +68,30 @@ impl From<ParNode> for AnyNode { } struct ParLayouter { + dirs: Gen<Dir>, main: SpecAxis, cross: SpecAxis, - dirs: LayoutDirs, line_spacing: Length, areas: Areas, finished: Vec<Frame>, - lines: Vec<(Length, Frame, Align)>, - lines_size: Gen<Length>, + stack: Vec<(Length, Frame, Align)>, + stack_size: Gen<Length>, line: Vec<(Length, Frame, Align)>, line_size: Gen<Length>, line_ruler: Align, } impl ParLayouter { - fn new(dirs: LayoutDirs, line_spacing: Length, areas: Areas) -> Self { + fn new(dir: Dir, line_spacing: Length, areas: Areas) -> Self { Self { - main: dirs.main.axis(), - cross: dirs.cross.axis(), - dirs, + dirs: Gen::new(Dir::TTB, dir), + main: SpecAxis::Vertical, + cross: SpecAxis::Horizontal, line_spacing, areas, finished: vec![], - lines: vec![], - lines_size: Gen::ZERO, + stack: vec![], + stack_size: Gen::ZERO, line: vec![], line_size: Gen::ZERO, line_ruler: Align::Start, @@ -122,12 +147,10 @@ impl ParLayouter { } } - let size = frame.size.switch(self.dirs); - // A line can contain frames with different alignments. They exact // positions are calculated later depending on the alignments. + let size = frame.size.switch(self.main); self.line.push((self.line_size.cross, frame, align)); - self.line_size.cross += size.cross; self.line_size.main = self.line_size.main.max(size.main); self.line_ruler = align; @@ -135,15 +158,15 @@ impl ParLayouter { fn finish_line(&mut self) { let full_size = { - let expand = self.areas.expand.switch(self.dirs); - let full = self.areas.full.switch(self.dirs); + let expand = self.areas.expand.get(self.cross); + let full = self.areas.full.get(self.cross); Gen::new( self.line_size.main, - expand.cross.resolve(self.line_size.cross, full.cross), + expand.resolve(self.line_size.cross, full), ) }; - let mut output = Frame::new(full_size.switch(self.dirs).to_size()); + let mut output = Frame::new(full_size.switch(self.main).to_size()); for (before, frame, align) in std::mem::take(&mut self.line) { let child_cross_size = frame.size.get(self.cross); @@ -158,49 +181,47 @@ impl ParLayouter { full_size.cross - before_with_self .. after }); - let pos = Gen::new(Length::ZERO, cross).switch(self.dirs).to_point(); + let pos = Gen::new(Length::ZERO, cross).switch(self.main).to_point(); output.push_frame(pos, frame); } // Add line spacing, but only between lines. - if !self.lines.is_empty() { - self.lines_size.main += self.line_spacing; + if !self.stack.is_empty() { + self.stack_size.main += self.line_spacing; *self.areas.current.get_mut(self.main) -= self.line_spacing; } - // Update metrics of the whole paragraph. - self.lines.push((self.lines_size.main, output, self.line_ruler)); - self.lines_size.main += full_size.main; - self.lines_size.cross = self.lines_size.cross.max(full_size.cross); + // Update metrics of paragraph and reset for line. + self.stack.push((self.stack_size.main, output, self.line_ruler)); + self.stack_size.main += full_size.main; + self.stack_size.cross = self.stack_size.cross.max(full_size.cross); *self.areas.current.get_mut(self.main) -= full_size.main; - - // Reset metrics for the single line. self.line_size = Gen::ZERO; self.line_ruler = Align::Start; } fn finish_area(&mut self) { - let size = self.lines_size; - let mut output = Frame::new(size.switch(self.dirs).to_size()); + let full_size = self.stack_size; + let mut output = Frame::new(full_size.switch(self.main).to_size()); - for (before, line, cross_align) in std::mem::take(&mut self.lines) { - let child_size = line.size.switch(self.dirs); + for (before, line, cross_align) in std::mem::take(&mut self.stack) { + let child_size = line.size.switch(self.main); // Position along the main axis. let main = if self.dirs.main.is_positive() { before } else { - size.main - (before + child_size.main) + full_size.main - (before + child_size.main) }; // Align along the cross axis. let cross = cross_align.resolve(if self.dirs.cross.is_positive() { - Length::ZERO .. size.cross - child_size.cross + Length::ZERO .. full_size.cross - child_size.cross } else { - size.cross - child_size.cross .. Length::ZERO + full_size.cross - child_size.cross .. Length::ZERO }); - let pos = Gen::new(main, cross).switch(self.dirs).to_point(); + let pos = Gen::new(main, cross).switch(self.main).to_point(); output.push_frame(pos, line); } @@ -208,7 +229,7 @@ impl ParLayouter { self.areas.next(); // Reset metrics for the whole paragraph. - self.lines_size = Gen::ZERO; + self.stack_size = Gen::ZERO; } fn finish(mut self) -> Vec<Frame> { diff --git a/src/layout/spacing.rs b/src/layout/spacing.rs deleted file mode 100644 index 361b03ee..00000000 --- a/src/layout/spacing.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::fmt::{self, Debug, Formatter}; - -use super::*; - -/// A node that adds spacing to its parent. -#[derive(Copy, Clone, PartialEq)] -pub struct SpacingNode { - /// The amount of spacing to insert. - pub amount: Length, - /// Defines how spacing interacts with surrounding spacing. - /// - /// Hard spacing (`softness = 0`) assures that a fixed amount of spacing - /// will always be inserted. Soft spacing (`softness >= 1`) will be consumed - /// by other spacing with lower softness and can be used to insert - /// overridable spacing, e.g. between words or paragraphs. - pub softness: u8, -} - -impl Layout for SpacingNode { - fn layout(&self, _: &mut LayoutContext, _: &Areas) -> Fragment { - Fragment::Spacing(self.amount) - } -} - -impl Debug for SpacingNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Spacing({}, {})", self.amount, self.softness) - } -} - -impl From<SpacingNode> for Node { - fn from(spacing: SpacingNode) -> Self { - Self::Spacing(spacing) - } -} diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 6a87290e..79fde72d 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -7,28 +7,34 @@ pub struct StackNode { /// /// The children are stacked along the `main` direction. The `cross` /// direction is required for aligning the children. - pub dirs: LayoutDirs, - /// How to align this stack in its parent. - pub aligns: LayoutAligns, + pub dirs: Gen<Dir>, /// The nodes to be stacked. - pub children: Vec<Node>, + pub children: Vec<StackChild>, +} + +/// A child of a stack node. +#[derive(Debug, Clone, PartialEq)] +pub enum StackChild { + /// Spacing between other nodes. + Spacing(Length), + /// Any child node and how to align it in the stack. + Any(AnyNode, Gen<Align>), } impl Layout for StackNode { - fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment { + fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> { let mut layouter = StackLayouter::new(self.dirs, areas.clone()); for child in &self.children { - match child.layout(ctx, &layouter.areas) { - Fragment::Spacing(spacing) => layouter.push_spacing(spacing), - Fragment::Frame(frame, aligns) => layouter.push_frame(frame, aligns), - Fragment::Frames(frames, aligns) => { - for frame in frames { + match *child { + StackChild::Spacing(amount) => layouter.push_spacing(amount), + StackChild::Any(ref node, aligns) => { + for frame in node.layout(ctx, &layouter.areas) { layouter.push_frame(frame, aligns); } } } } - Fragment::Frames(layouter.finish(), self.aligns) + layouter.finish() } } @@ -39,24 +45,24 @@ impl From<StackNode> for AnyNode { } struct StackLayouter { + dirs: Gen<Dir>, main: SpecAxis, - dirs: LayoutDirs, areas: Areas, finished: Vec<Frame>, - frames: Vec<(Length, Frame, LayoutAligns)>, - used: Gen<Length>, + frames: Vec<(Length, Frame, Gen<Align>)>, + size: Gen<Length>, ruler: Align, } impl StackLayouter { - fn new(dirs: LayoutDirs, areas: Areas) -> Self { + fn new(dirs: Gen<Dir>, areas: Areas) -> Self { Self { - main: dirs.main.axis(), dirs, + main: dirs.main.axis(), areas, finished: vec![], frames: vec![], - used: Gen::ZERO, + size: Gen::ZERO, ruler: Align::Start, } } @@ -65,10 +71,10 @@ impl StackLayouter { let main_rest = self.areas.current.get_mut(self.main); let capped = amount.min(*main_rest); *main_rest -= capped; - self.used.main += capped; + self.size.main += capped; } - fn push_frame(&mut self, frame: Frame, aligns: LayoutAligns) { + fn push_frame(&mut self, frame: Frame, aligns: Gen<Align>) { if self.ruler > aligns.main { self.finish_area(); } @@ -82,21 +88,18 @@ impl StackLayouter { } } - let size = frame.size.switch(self.dirs); - self.frames.push((self.used.main, frame, aligns)); - - *self.areas.current.get_mut(self.main) -= size.main; - self.used.main += size.main; - self.used.cross = self.used.cross.max(size.cross); + let size = frame.size.switch(self.main); + self.frames.push((self.size.main, frame, aligns)); self.ruler = aligns.main; + self.size.main += size.main; + self.size.cross = self.size.cross.max(size.cross); + *self.areas.current.get_mut(self.main) -= size.main; } fn finish_area(&mut self) { let full_size = { - let expand = self.areas.expand; - let full = self.areas.full; - let current = self.areas.current; - let used = self.used.switch(self.dirs).to_size(); + let Areas { current, full, expand, .. } = self.areas; + let used = self.size.switch(self.main).to_size(); let mut size = Size::new( expand.horizontal.resolve(used.width, full.width), @@ -113,21 +116,21 @@ impl StackLayouter { size = Size::new(width, width / aspect); } - size.switch(self.dirs) + size.switch(self.main) }; - let mut output = Frame::new(full_size.switch(self.dirs).to_size()); + let mut output = Frame::new(full_size.switch(self.main).to_size()); for (before, frame, aligns) in std::mem::take(&mut self.frames) { - let child_size = frame.size.switch(self.dirs); + let child_size = frame.size.switch(self.main); // Align along the main axis. let main = aligns.main.resolve(if self.dirs.main.is_positive() { - let after_with_self = self.used.main - before; + let after_with_self = self.size.main - before; before .. full_size.main - after_with_self } else { let before_with_self = before + child_size.main; - let after = self.used.main - (before + child_size.main); + let after = self.size.main - (before + child_size.main); full_size.main - before_with_self .. after }); @@ -138,15 +141,14 @@ impl StackLayouter { full_size.cross - child_size.cross .. Length::ZERO }); - let pos = Gen::new(main, cross).switch(self.dirs).to_point(); + let pos = Gen::new(main, cross).switch(self.main).to_point(); output.push_frame(pos, frame); } self.finished.push(output); - self.areas.next(); - self.used = Gen::ZERO; self.ruler = Align::Start; + self.size = Gen::ZERO; } fn finish(mut self) -> Vec<Frame> { diff --git a/src/layout/text.rs b/src/layout/text.rs deleted file mode 100644 index 39866907..00000000 --- a/src/layout/text.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fmt::{self, Debug, Formatter}; - -use super::*; -use crate::exec::FontProps; - -/// A consecutive, styled run of text. -#[derive(Clone, PartialEq)] -pub struct TextNode { - /// The text direction. - pub dir: Dir, - /// How to align this text node in its parent. - pub aligns: LayoutAligns, - /// The text. - pub text: String, - /// Properties used for font selection and layout. - pub props: FontProps, -} - -impl Layout for TextNode { - fn layout(&self, ctx: &mut LayoutContext, _: &Areas) -> Fragment { - let frame = shape(&self.text, &mut ctx.env.fonts, &self.props); - Fragment::Frame(frame, self.aligns) - } -} - -impl Debug for TextNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Text({})", self.text) - } -} - -impl From<TextNode> for Node { - fn from(text: TextNode) -> Self { - Self::Text(text) - } -} |
