diff options
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/fixed.rs | 8 | ||||
| -rw-r--r-- | src/layout/mod.rs | 15 | ||||
| -rw-r--r-- | src/layout/pad.rs | 1 | ||||
| -rw-r--r-- | src/layout/par.rs | 21 | ||||
| -rw-r--r-- | src/layout/stack.rs | 12 |
5 files changed, 31 insertions, 26 deletions
diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs index 60dbe4d6..a9554a07 100644 --- a/src/layout/fixed.rs +++ b/src/layout/fixed.rs @@ -20,7 +20,13 @@ impl Layout for NodeFixed { self.height.map(|h| h.resolve(full.height)).unwrap_or(current.height), ); - let areas = Areas::once(size); + let fill_if = |cond| if cond { Expand::Fill } else { Expand::Fit }; + let expand = Spec::new( + fill_if(self.width.is_some()), + fill_if(self.height.is_some()), + ); + + let areas = Areas::once(size, expand); self.child.layout(ctx, &areas) } } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 622b0363..2e6a39ff 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -55,7 +55,7 @@ pub struct NodePages { impl NodePages { /// Layout the page run. pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> { - let areas = Areas::repeat(self.size); + let areas = Areas::repeat(self.size, Spec::uniform(Expand::Fill)); let layouted = self.child.layout(ctx, &areas); layouted.into_frames() } @@ -85,26 +85,31 @@ pub struct Areas { pub backlog: Vec<Size>, /// The final area that is repeated when the backlog is empty. pub last: Option<Size>, + /// Whether the frames resulting from layouting into this areas should be + /// shrunk to fit their content or expanded to fill the area. + pub expand: Spec<Expand>, } impl Areas { /// Create a new length-1 sequence of areas with just one `area`. - pub fn once(size: Size) -> Self { + pub fn once(size: Size, expand: Spec<Expand>) -> Self { Self { current: size, full: size, backlog: vec![], last: None, + expand, } } /// Create a new sequence of areas that repeats `area` indefinitely. - pub fn repeat(size: Size) -> Self { + pub fn repeat(size: Size, expand: Spec<Expand>) -> Self { Self { current: size, full: size, backlog: vec![], last: Some(size), + expand, } } @@ -129,14 +134,14 @@ impl Areas { /// Whether to expand or shrink a node along an axis. #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum Expansion { +pub enum Expand { /// Fit the content. Fit, /// Fill the available space. Fill, } -impl Expansion { +impl Expand { /// Resolve the expansion to either the `fit` or `fill` length. /// /// Prefers `fit` if `fill` is infinite. diff --git a/src/layout/pad.rs b/src/layout/pad.rs index 425fa41b..02adebeb 100644 --- a/src/layout/pad.rs +++ b/src/layout/pad.rs @@ -37,6 +37,7 @@ fn shrink(areas: &Areas, padding: Sides<Linear>) -> Areas { full: shrink(areas.full), backlog: areas.backlog.iter().copied().map(shrink).collect(), last: areas.last.map(shrink), + expand: areas.expand, } } diff --git a/src/layout/par.rs b/src/layout/par.rs index 45494dec..9a5d26dd 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -8,8 +8,6 @@ pub struct NodePar { /// The children are placed in lines along the `cross` direction. The lines /// are stacked along the `main` direction. pub dirs: LayoutDirs, - /// Whether to expand the cross axis to fill the area or to fit the content. - pub cross_expansion: Expansion, /// The spacing to insert after each line. pub line_spacing: Length, /// The nodes to be arranged in a paragraph. @@ -42,11 +40,11 @@ impl From<NodePar> for NodeAny { } } -struct ParLayouter<'a> { - par: &'a NodePar, +struct ParLayouter { main: SpecAxis, cross: SpecAxis, dirs: LayoutDirs, + line_spacing: Length, areas: Areas, finished: Vec<Frame>, lines: Vec<(Length, Frame, Align)>, @@ -56,13 +54,13 @@ struct ParLayouter<'a> { line_ruler: Align, } -impl<'a> ParLayouter<'a> { - fn new(par: &'a NodePar, areas: Areas) -> Self { +impl ParLayouter { + fn new(par: &NodePar, areas: Areas) -> Self { Self { - par, main: par.dirs.main.axis(), cross: par.dirs.cross.axis(), dirs: par.dirs, + line_spacing: par.line_spacing, areas, finished: vec![], lines: vec![], @@ -134,13 +132,12 @@ impl<'a> ParLayouter<'a> { } fn finish_line(&mut self) { + let expand = self.areas.expand.switch(self.dirs); let full_size = { let full = self.areas.full.switch(self.dirs); Gen::new( self.line_size.main, - self.par - .cross_expansion - .resolve(self.line_size.cross.min(full.cross), full.cross), + expand.cross.resolve(self.line_size.cross.min(full.cross), full.cross), ) }; @@ -165,8 +162,8 @@ impl<'a> ParLayouter<'a> { // Add line spacing, but only between lines. if !self.lines.is_empty() { - self.lines_size.main += self.par.line_spacing; - *self.areas.current.get_mut(self.main) -= self.par.line_spacing; + self.lines_size.main += self.line_spacing; + *self.areas.current.get_mut(self.main) -= self.line_spacing; } // Update metrics of the whole paragraph. diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 7d1d7a12..73bd49c1 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -10,8 +10,6 @@ pub struct NodeStack { pub dirs: LayoutDirs, /// How to align this stack in _its_ parent. pub align: ChildAlign, - /// Whether to expand the axes to fill the area or to fit the content. - pub expand: Spec<Expansion>, /// The nodes to be stacked. pub children: Vec<Node>, } @@ -40,8 +38,7 @@ impl From<NodeStack> for NodeAny { } } -struct StackLayouter<'a> { - stack: &'a NodeStack, +struct StackLayouter { main: SpecAxis, dirs: LayoutDirs, areas: Areas, @@ -51,10 +48,9 @@ struct StackLayouter<'a> { ruler: Align, } -impl<'a> StackLayouter<'a> { - fn new(stack: &'a NodeStack, areas: Areas) -> Self { +impl StackLayouter { + fn new(stack: &NodeStack, areas: Areas) -> Self { Self { - stack, main: stack.dirs.main.axis(), dirs: stack.dirs, areas, @@ -97,7 +93,7 @@ impl<'a> StackLayouter<'a> { fn finish_area(&mut self) { let full_size = { - let expand = self.stack.expand.switch(self.dirs); + let expand = self.areas.expand.switch(self.dirs); let full = self.areas.full.switch(self.dirs); Gen::new( expand.main.resolve(self.used.main.min(full.main), full.main), |
