summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/fixed.rs8
-rw-r--r--src/layout/mod.rs15
-rw-r--r--src/layout/pad.rs1
-rw-r--r--src/layout/par.rs21
-rw-r--r--src/layout/stack.rs12
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),