summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/constraints.rs8
-rw-r--r--src/layout/fixed.rs16
-rw-r--r--src/layout/grid.rs137
-rw-r--r--src/layout/image.rs16
-rw-r--r--src/layout/pad.rs24
-rw-r--r--src/layout/par.rs76
-rw-r--r--src/layout/stack.rs104
-rw-r--r--src/layout/tree.rs3
8 files changed, 187 insertions, 197 deletions
diff --git a/src/layout/constraints.rs b/src/layout/constraints.rs
index d808abd9..f88b2add 100644
--- a/src/layout/constraints.rs
+++ b/src/layout/constraints.rs
@@ -52,11 +52,11 @@ impl Constraints {
/// Set the appropriate base constraints for linear width and height sizing.
pub fn set_base_if_linear(&mut self, base: Size, sizing: Spec<Option<Linear>>) {
// The full sizes need to be equal if there is a relative component in the sizes.
- if sizing.horizontal.map_or(false, |l| l.is_relative()) {
- self.base.horizontal = Some(base.width);
+ if sizing.x.map_or(false, |l| l.is_relative()) {
+ self.base.x = Some(base.w);
}
- if sizing.vertical.map_or(false, |l| l.is_relative()) {
- self.base.vertical = Some(base.height);
+ if sizing.y.map_or(false, |l| l.is_relative()) {
+ self.base.y = Some(base.h);
}
}
}
diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs
index 02660d1d..5b103f9a 100644
--- a/src/layout/fixed.rs
+++ b/src/layout/fixed.rs
@@ -35,24 +35,24 @@ impl Layout for FixedNode {
// If the size for one axis isn't specified, the `current` size along
// that axis needs to remain the same for the result to be reusable.
if width.is_none() {
- constraints.exact.horizontal = Some(current.width);
+ constraints.exact.x = Some(current.w);
}
if height.is_none() {
- constraints.exact.vertical = Some(current.height);
+ constraints.exact.y = Some(current.h);
}
// Resolve the linears based on the current width and height.
let mut size = Size::new(
- width.map_or(current.width, |w| w.resolve(base.width)),
- height.map_or(current.height, |h| h.resolve(base.height)),
+ width.map_or(current.w, |w| w.resolve(base.w)),
+ height.map_or(current.h, |h| h.resolve(base.h)),
);
// If width or height aren't set for an axis, the base should be
// inherited from the parent for that axis.
let base = Size::new(
- width.map_or(base.width, |_| size.width),
- height.map_or(base.height, |_| size.height),
+ width.map_or(base.w, |_| size.w),
+ height.map_or(base.h, |_| size.h),
);
// Handle the aspect ratio.
@@ -61,7 +61,7 @@ impl Layout for FixedNode {
constraints.min = Spec::splat(None);
constraints.max = Spec::splat(None);
- let width = size.width.min(aspect * size.height);
+ let width = size.w.min(aspect * size.h);
size = Size::new(width, width / aspect);
}
@@ -78,7 +78,7 @@ impl Layout for FixedNode {
if let Some(aspect) = aspect {
if width.is_none() && height.is_none() {
let needed = frames[0].item.size.cap(size);
- let width = needed.width.max(aspect * needed.height);
+ let width = needed.w.max(aspect * needed.h);
regions.current = Size::new(width, width / aspect);
regions.expand = Spec::splat(true);
frames = self.child.layout(ctx, &regions);
diff --git a/src/layout/grid.rs b/src/layout/grid.rs
index b4a1fe79..88a6a4ac 100644
--- a/src/layout/grid.rs
+++ b/src/layout/grid.rs
@@ -3,10 +3,7 @@ use super::*;
/// A node that arranges its children in a grid.
#[cfg_attr(feature = "layout-cache", derive(Hash))]
pub struct GridNode {
- /// The `main` and `cross` directions of this grid.
- ///
- /// The rows go along the `main` direction and the columns along the `cross`
- /// direction.
+ /// The inline (columns) and block (rows) directions of this grid.
pub dirs: Gen<Dir>,
/// Defines sizing for content rows and columns.
pub tracks: Gen<Vec<TrackSizing>>,
@@ -52,10 +49,10 @@ impl From<GridNode> for LayoutNode {
/// Performs grid layout.
struct GridLayouter<'a> {
- /// The axis of the cross direction.
- cross: SpecAxis,
- /// The axis of the main direction.
- main: SpecAxis,
+ /// The axis of the inline direction.
+ inline: SpecAxis,
+ /// The axis of the block direction.
+ block: SpecAxis,
/// The original expand state of the target region.
expand: Spec<bool>,
/// The column tracks including gutter tracks.
@@ -68,9 +65,9 @@ struct GridLayouter<'a> {
regions: Regions,
/// Resolved column sizes.
rcols: Vec<Length>,
- /// The full main size of the current region.
+ /// The full block size of the current region.
full: Length,
- /// The used-up size of the current region. The cross size is determined
+ /// The used-up size of the current region. The inline size is determined
/// once after columns are resolved and not touched again.
used: Gen<Length>,
/// The sum of fractional ratios in the current region.
@@ -99,13 +96,13 @@ impl<'a> GridLayouter<'a> {
let mut rows = vec![];
// Number of content columns: Always at least one.
- let c = grid.tracks.cross.len().max(1);
+ let c = grid.tracks.inline.len().max(1);
// Number of content rows: At least as many as given, but also at least
// as many as needed to place each item.
let r = {
let len = grid.children.len();
- let given = grid.tracks.main.len();
+ let given = grid.tracks.block.len();
let needed = len / c + (len % c).clamp(0, 1);
given.max(needed)
};
@@ -118,32 +115,32 @@ impl<'a> GridLayouter<'a> {
// Collect content and gutter columns.
for x in 0 .. c {
- cols.push(get_or(&grid.tracks.cross, x, auto));
- cols.push(get_or(&grid.gutter.cross, x, zero));
+ cols.push(get_or(&grid.tracks.inline, x, auto));
+ cols.push(get_or(&grid.gutter.inline, x, zero));
}
// Collect content and gutter rows.
for y in 0 .. r {
- rows.push(get_or(&grid.tracks.main, y, auto));
- rows.push(get_or(&grid.gutter.main, y, zero));
+ rows.push(get_or(&grid.tracks.block, y, auto));
+ rows.push(get_or(&grid.gutter.block, y, zero));
}
// Remove superfluous gutter tracks.
cols.pop();
rows.pop();
- let cross = grid.dirs.cross.axis();
- let main = grid.dirs.main.axis();
- let full = regions.current.get(main);
+ let inline = grid.dirs.inline.axis();
+ let block = grid.dirs.block.axis();
+ let full = regions.current.get(block);
let rcols = vec![Length::zero(); cols.len()];
// We use the regions only for auto row measurement and constraints.
let expand = regions.expand;
- regions.expand = Gen::new(true, false).to_spec(main);
+ regions.expand = Gen::new(true, false).to_spec(block);
Self {
- cross,
- main,
+ inline,
+ block,
cols,
rows,
children: &grid.children,
@@ -169,8 +166,8 @@ impl<'a> GridLayouter<'a> {
}
// Generic version of current and base size.
- let current = self.regions.current.to_gen(self.main);
- let base = self.regions.base.to_gen(self.main);
+ let current = self.regions.current.to_gen(self.block);
+ let base = self.regions.base.to_gen(self.block);
// The different cases affecting constraints.
let mut case = Case::PurelyLinear;
@@ -189,8 +186,8 @@ impl<'a> GridLayouter<'a> {
case = Case::Fitting;
}
TrackSizing::Linear(v) => {
- self.constraints.base.set(self.cross, Some(base.cross));
- let resolved = v.resolve(base.cross);
+ self.constraints.base.set(self.inline, Some(base.inline));
+ let resolved = v.resolve(base.inline);
*rcol = resolved;
linear += resolved;
}
@@ -202,7 +199,7 @@ impl<'a> GridLayouter<'a> {
}
// Size that is not used by fixed-size columns.
- let available = current.cross - linear;
+ let available = current.inline - linear;
if available >= Length::zero() {
// Determine size of auto columns.
let (auto, count) = self.measure_auto_columns(ctx, available);
@@ -226,13 +223,19 @@ impl<'a> GridLayouter<'a> {
// Set constraints depending on the case we hit.
match case {
Case::PurelyLinear => {}
- Case::Fitting => self.constraints.min.set(self.cross, Some(self.used.cross)),
- Case::Exact => self.constraints.exact.set(self.cross, Some(current.cross)),
- Case::Overflowing => self.constraints.max.set(self.cross, Some(linear)),
+ Case::Fitting => {
+ self.constraints.min.set(self.inline, Some(self.used.inline));
+ }
+ Case::Exact => {
+ self.constraints.exact.set(self.inline, Some(current.inline));
+ }
+ Case::Overflowing => {
+ self.constraints.max.set(self.inline, Some(linear));
+ }
}
// Sum up the resolved column sizes once here.
- self.used.cross = self.rcols.iter().sum();
+ self.used.inline = self.rcols.iter().sum();
}
/// Measure the size that is available to auto columns.
@@ -253,10 +256,10 @@ impl<'a> GridLayouter<'a> {
let mut resolved = Length::zero();
for node in (0 .. self.rows.len()).filter_map(|y| self.cell(x, y)) {
- let size = Gen::new(available, Length::inf()).to_size(self.main);
+ let size = Gen::new(available, Length::inf()).to_size(self.block);
let regions = Regions::one(size, size, Spec::splat(false));
let frame = node.layout(ctx, &regions).remove(0).item;
- resolved.set_max(frame.size.get(self.cross));
+ resolved.set_max(frame.size.get(self.inline));
}
self.rcols[x] = resolved;
@@ -317,9 +320,9 @@ impl<'a> GridLayouter<'a> {
self.layout_auto_row(ctx, y);
}
TrackSizing::Linear(v) => {
- let base = self.regions.base.get(self.main);
+ let base = self.regions.base.get(self.block);
if v.is_relative() {
- self.constraints.base.set(self.main, Some(base));
+ self.constraints.base.set(self.block, Some(base));
}
let resolved = v.resolve(base);
let frame = self.layout_single_row(ctx, resolved, y);
@@ -327,7 +330,7 @@ impl<'a> GridLayouter<'a> {
}
TrackSizing::Fractional(v) => {
self.fr += v;
- self.constraints.exact.set(self.main, Some(self.full));
+ self.constraints.exact.set(self.block, Some(self.full));
self.lrows.push(Row::Fr(v, y));
}
}
@@ -337,7 +340,7 @@ impl<'a> GridLayouter<'a> {
self.finished
}
- /// Layout a row with automatic size along the main axis. Such a row may
+ /// Layout a row with automatic size along the block axis. Such a row may
/// break across multiple regions.
fn layout_auto_row(&mut self, ctx: &mut LayoutContext, y: usize) {
let mut first = Length::zero();
@@ -346,13 +349,13 @@ impl<'a> GridLayouter<'a> {
// Determine the size for each region of the row.
for (x, &rcol) in self.rcols.iter().enumerate() {
if let Some(node) = self.cell(x, y) {
- let cross = self.cross;
- self.regions.mutate(|size| size.set(cross, rcol));
+ let inline = self.inline;
+ self.regions.mutate(|size| size.set(inline, rcol));
let mut sizes = node
.layout(ctx, &self.regions)
.into_iter()
- .map(|frame| frame.item.size.get(self.main));
+ .map(|frame| frame.item.size.get(self.block));
if let Some(size) = sizes.next() {
first.set_max(size);
@@ -375,14 +378,14 @@ impl<'a> GridLayouter<'a> {
let len = frames.len();
for (i, frame) in frames.into_iter().enumerate() {
if i + 1 < len {
- self.constraints.exact.set(self.main, Some(self.full));
+ self.constraints.exact.set(self.block, Some(self.full));
}
self.push_row(ctx, frame);
}
}
}
- /// Layout a row with a fixed size along the main axis.
+ /// Layout a row with a fixed size along the block axis.
fn layout_single_row(
&self,
ctx: &mut LayoutContext,
@@ -390,18 +393,18 @@ impl<'a> GridLayouter<'a> {
y: usize,
) -> Frame {
let size = self.to_size(length);
- let mut output = Frame::new(size, size.height);
+ let mut output = Frame::new(size, size.h);
let mut pos = Gen::zero();
for (x, &rcol) in self.rcols.iter().enumerate() {
if let Some(node) = self.cell(x, y) {
- let size = Gen::new(rcol, length).to_size(self.main);
+ let size = Gen::new(rcol, length).to_size(self.block);
let regions = Regions::one(size, size, Spec::splat(true));
let frame = node.layout(ctx, &regions).remove(0);
- output.push_frame(pos.to_point(self.main), frame.item);
+ output.push_frame(pos.to_point(self.block), frame.item);
}
- pos.cross += rcol;
+ pos.inline += rcol;
}
output
@@ -419,7 +422,7 @@ impl<'a> GridLayouter<'a> {
let mut outputs: Vec<_> = std::iter::once(first)
.chain(rest.iter().copied())
.map(|v| self.to_size(v))
- .map(|size| Frame::new(size, size.height))
+ .map(|size| Frame::new(size, size.h))
.collect();
// Prepare regions.
@@ -432,16 +435,16 @@ impl<'a> GridLayouter<'a> {
let mut pos = Gen::zero();
for (x, &rcol) in self.rcols.iter().enumerate() {
if let Some(node) = self.cell(x, y) {
- regions.mutate(|size| size.set(self.cross, rcol));
+ regions.mutate(|size| size.set(self.inline, rcol));
// Push the layouted frames into the individual output frames.
let frames = node.layout(ctx, &regions);
for (output, frame) in outputs.iter_mut().zip(frames) {
- output.push_frame(pos.to_point(self.main), frame.item);
+ output.push_frame(pos.to_point(self.block), frame.item);
}
}
- pos.cross += rcol;
+ pos.inline += rcol;
}
outputs
@@ -450,34 +453,34 @@ impl<'a> GridLayouter<'a> {
/// Push a row frame into the current or next fitting region, finishing
/// regions (including layouting fractional rows) if necessary.
fn push_row(&mut self, ctx: &mut LayoutContext, frame: Frame) {
- let length = frame.size.get(self.main);
+ let length = frame.size.get(self.block);
// Skip to fitting region.
- while !self.regions.current.get(self.main).fits(length)
+ while !self.regions.current.get(self.block).fits(length)
&& !self.regions.in_full_last()
{
- self.constraints.max.set(self.main, Some(self.used.main + length));
+ self.constraints.max.set(self.block, Some(self.used.block + length));
self.finish_region(ctx);
}
- *self.regions.current.get_mut(self.main) -= length;
- self.used.main += length;
+ *self.regions.current.get_mut(self.block) -= length;
+ self.used.block += length;
self.lrows.push(Row::Frame(frame));
}
/// Finish rows for one region.
fn finish_region(&mut self, ctx: &mut LayoutContext) {
// Determine the size of the region.
- let length = if self.fr.is_zero() { self.used.main } else { self.full };
+ let length = if self.fr.is_zero() { self.used.block } else { self.full };
let size = self.to_size(length);
- self.constraints.min.set(self.main, Some(length));
+ self.constraints.min.set(self.block, Some(length));
// The frame for the region.
- let mut output = Frame::new(size, size.height);
+ let mut output = Frame::new(size, size.h);
let mut pos = Gen::zero();
// Determine the remaining size for fractional rows.
- let remaining = self.full - self.used.main;
+ let remaining = self.full - self.used.block;
// Place finished rows and layout fractional rows.
for row in std::mem::take(&mut self.lrows) {
@@ -494,14 +497,14 @@ impl<'a> GridLayouter<'a> {
}
};
- let main = frame.size.get(self.main);
- output.merge_frame(pos.to_point(self.main), frame);
- pos.main += main;
+ let point = pos.to_point(self.block);
+ pos.block += frame.size.get(self.block);
+ output.merge_frame(point, frame);
}
self.regions.next();
- self.full = self.regions.current.get(self.main);
- self.used.main = Length::zero();
+ self.full = self.regions.current.get(self.block);
+ self.used.block = Length::zero();
self.fr = Fractional::zero();
self.finished.push(output.constrain(self.constraints));
self.constraints = Constraints::new(self.expand);
@@ -523,9 +526,9 @@ impl<'a> GridLayouter<'a> {
}
}
- /// Return a size where the cross axis spans the whole grid and the main
+ /// Return a size where the inline axis spans the whole grid and the block
/// axis the given length.
- fn to_size(&self, main_size: Length) -> Size {
- Gen::new(self.used.cross, main_size).to_size(self.main)
+ fn to_size(&self, block: Length) -> Size {
+ Gen::new(self.used.inline, block).to_size(self.block)
}
}
diff --git a/src/layout/image.rs b/src/layout/image.rs
index e3e5e741..0220da3e 100644
--- a/src/layout/image.rs
+++ b/src/layout/image.rs
@@ -23,8 +23,8 @@ impl Layout for ImageNode {
let mut constraints = Constraints::new(expand);
constraints.set_base_if_linear(base, Spec::new(self.width, self.height));
- let width = self.width.map(|w| w.resolve(base.width));
- let height = self.height.map(|w| w.resolve(base.height));
+ let width = self.width.map(|w| w.resolve(base.w));
+ let height = self.height.map(|w| w.resolve(base.h));
let dimensions = ctx.images.get(self.id).buf.dimensions();
let pixel_width = dimensions.0 as f64;
@@ -38,12 +38,12 @@ impl Layout for ImageNode {
(None, None) => {
constraints.exact = current.to_spec().map(Some);
- let ratio = current.width / current.height;
- if ratio < pixel_ratio && current.width.is_finite() {
- Size::new(current.width, current.width / pixel_ratio)
- } else if current.height.is_finite() {
+ let ratio = current.w / current.h;
+ if ratio < pixel_ratio && current.w.is_finite() {
+ Size::new(current.w, current.w / pixel_ratio)
+ } else if current.h.is_finite() {
// TODO: Fix issue with line spacing.
- Size::new(current.height * pixel_ratio, current.height)
+ Size::new(current.h * pixel_ratio, current.h)
} else {
// Totally unbounded region, we have to make up something.
Size::new(Length::pt(pixel_width), Length::pt(pixel_height))
@@ -51,7 +51,7 @@ impl Layout for ImageNode {
}
};
- let mut frame = Frame::new(size, size.height);
+ let mut frame = Frame::new(size, size.h);
frame.push(Point::zero(), Element::Image(self.id, size));
vec![frame.constrain(constraints)]
}
diff --git a/src/layout/pad.rs b/src/layout/pad.rs
index 3075472b..506cb110 100644
--- a/src/layout/pad.rs
+++ b/src/layout/pad.rs
@@ -30,8 +30,8 @@ impl Layout for PadNode {
// Solve for the size `padded` that satisfies (approximately):
// `padded - padding.resolve(padded).size() == size`
let padded = Size::new(
- solve_axis(frame.size.width, self.padding.left + self.padding.right),
- solve_axis(frame.size.height, self.padding.top + self.padding.bottom),
+ solve_axis(frame.size.w, self.padding.left + self.padding.right),
+ solve_axis(frame.size.h, self.padding.top + self.padding.bottom),
);
let padding = self.padding.resolve(padded);
@@ -39,27 +39,27 @@ impl Layout for PadNode {
// Inflate min and max contraints by the padding.
for spec in [&mut constraints.min, &mut constraints.max] {
- if let Some(horizontal) = spec.horizontal.as_mut() {
- *horizontal += padding.size().width;
+ if let Some(x) = spec.x.as_mut() {
+ *x += padding.size().w;
}
- if let Some(vertical) = spec.vertical.as_mut() {
- *vertical += padding.size().height;
+ if let Some(y) = spec.y.as_mut() {
+ *y += padding.size().h;
}
}
// Set exact and base constraints if the child had them.
- constraints.exact.horizontal.and_set(Some(current.width));
- constraints.exact.vertical.and_set(Some(current.height));
- constraints.base.horizontal.and_set(Some(base.width));
- constraints.base.vertical.and_set(Some(base.height));
+ constraints.exact.x.and_set(Some(current.w));
+ constraints.exact.y.and_set(Some(current.h));
+ constraints.base.x.and_set(Some(base.w));
+ constraints.base.y.and_set(Some(base.h));
// Also set base constraints if the padding is relative.
if self.padding.left.is_relative() || self.padding.right.is_relative() {
- constraints.base.horizontal = Some(base.width);
+ constraints.base.x = Some(base.w);
}
if self.padding.top.is_relative() || self.padding.bottom.is_relative() {
- constraints.base.vertical = Some(base.height);
+ constraints.base.y = Some(base.h);
}
// Create a new larger frame and place the child's frame inside it.
diff --git a/src/layout/par.rs b/src/layout/par.rs
index 84d784b0..3df742a7 100644
--- a/src/layout/par.rs
+++ b/src/layout/par.rs
@@ -122,7 +122,7 @@ impl<'a> ParLayouter<'a> {
for (range, child) in par.ranges().zip(&par.children) {
match *child {
ParChild::Spacing(amount) => {
- let resolved = amount.resolve(regions.current.width);
+ let resolved = amount.resolve(regions.current.w);
items.push(ParItem::Spacing(resolved));
ranges.push(range);
}
@@ -179,81 +179,69 @@ impl<'a> ParLayouter<'a> {
if !stack.regions.current.fits(line.size) {
if let Some((last_line, last_end)) = last.take() {
// The region must not fit this line for the result to be valid.
- if !stack.regions.current.width.fits(line.size.width) {
- stack.constraints.max.horizontal.set_min(line.size.width);
+ if !stack.regions.current.w.fits(line.size.w) {
+ stack.constraints.max.x.set_min(line.size.w);
}
- if !stack.regions.current.height.fits(line.size.height) {
- stack
- .constraints
- .max
- .vertical
- .set_min(stack.size.height + line.size.height);
+ if !stack.regions.current.h.fits(line.size.h) {
+ stack.constraints.max.y.set_min(stack.size.h + line.size.h);
}
stack.push(last_line);
- stack.constraints.min.vertical = Some(stack.size.height);
+ stack.constraints.min.y = Some(stack.size.h);
start = last_end;
line = LineLayout::new(ctx, &self, start .. end);
}
}
// If the line does not fit vertically, we start a new region.
- while !stack.regions.current.height.fits(line.size.height)
+ while !stack.regions.current.h.fits(line.size.h)
&& !stack.regions.in_full_last()
{
// Again, the line must not fit. It would if the space taken up
// plus the line height would fit, therefore the constraint
// below.
- stack
- .constraints
- .max
- .vertical
- .set_min(stack.size.height + line.size.height);
+ stack.constraints.max.y.set_min(stack.size.h + line.size.h);
stack.finish_region(ctx);
}
// If the line does not fit vertically, we start a new region.
- while !stack.regions.current.height.fits(line.size.height) {
+ while !stack.regions.current.h.fits(line.size.h) {
if stack.regions.in_full_last() {
stack.overflowing = true;
break;
}
- stack
- .constraints
- .max
- .vertical
- .set_min(stack.size.height + line.size.height);
+ stack.constraints.max.y.set_min(stack.size.h + line.size.h);
stack.finish_region(ctx);
}
// If the line does not fit horizontally or we have a mandatory
// line break (i.e. due to "\n"), we push the line into the
// stack.
- if mandatory || !stack.regions.current.width.fits(line.size.width) {
+ if mandatory || !stack.regions.current.w.fits(line.size.w) {
stack.push(line);
start = end;
last = None;
- stack.constraints.min.vertical = Some(stack.size.height);
+ stack.constraints.min.y = Some(stack.size.h);
// If there is a trailing line break at the end of the
// paragraph, we want to force an empty line.
if mandatory && end == self.bidi.text.len() {
stack.push(LineLayout::new(ctx, &self, end .. end));
- stack.constraints.min.vertical = Some(stack.size.height);
+ stack.constraints.min.y = Some(stack.size.h);
}
} else {
// Otherwise, the line fits both horizontally and vertically
// and we remember it.
- stack.constraints.min.horizontal.set_max(line.size.width);
+ stack.constraints.min.x.set_max(line.size.w);
last = Some((line, end));
}
}
if let Some((line, _)) = last {
stack.push(line);
- stack.constraints.min.vertical = Some(stack.size.height);
+ stack.constraints.min.y = Some(stack.size.h);
}
stack.finish(ctx)
@@ -339,12 +327,12 @@ impl<'a> LineStack<'a> {
/// Push a new line into the stack.
fn push(&mut self, line: LineLayout<'a>) {
- self.regions.current.height -= line.size.height + self.line_spacing;
+ self.regions.current.h -= line.size.h + self.line_spacing;
- self.size.width.set_max(line.size.width);
- self.size.height += line.size.height;
+ self.size.w.set_max(line.size.w);
+ self.size.h += line.size.h;
if !self.lines.is_empty() {
- self.size.height += self.line_spacing;
+ self.size.h += self.line_spacing;
}
self.lines.push(line);
@@ -352,23 +340,23 @@ impl<'a> LineStack<'a> {
/// Finish the frame for one region.
fn finish_region(&mut self, ctx: &LayoutContext) {
- if self.regions.expand.horizontal {
- self.size.width = self.regions.current.width;
- self.constraints.exact.horizontal = Some(self.regions.current.width);
+ if self.regions.expand.x {
+ self.size.w = self.regions.current.w;
+ self.constraints.exact.x = Some(self.regions.current.w);
}
if self.overflowing {
- self.constraints.min.vertical = None;
- self.constraints.max.vertical = None;
+ self.constraints.min.y = None;
+ self.constraints.max.y = None;
self.constraints.exact = self.full.to_spec().map(Some);
}
- let mut output = Frame::new(self.size, self.size.height);
+ let mut output = Frame::new(self.size, self.size.h);
let mut offset = Length::zero();
let mut first = true;
for line in self.lines.drain(..) {
- let frame = line.build(ctx, self.size.width);
+ let frame = line.build(ctx, self.size.w);
let pos = Point::new(Length::zero(), offset);
if first {
@@ -376,7 +364,7 @@ impl<'a> LineStack<'a> {
first = false;
}
- offset += frame.size.height + self.line_spacing;
+ offset += frame.size.h + self.line_spacing;
output.merge_frame(pos, frame);
}
@@ -490,9 +478,9 @@ impl<'a> LineLayout<'a> {
for item in first.iter().chain(items).chain(&last) {
let size = item.size();
let baseline = item.baseline();
- width += size.width;
+ width += size.w;
top.set_max(baseline);
- bottom.set_max(size.height - baseline);
+ bottom.set_max(size.h - baseline);
}
Self {
@@ -510,8 +498,8 @@ impl<'a> LineLayout<'a> {
/// Build the line's frame.
fn build(&self, ctx: &LayoutContext, width: Length) -> Frame {
- let size = Size::new(self.size.width.max(width), self.size.height);
- let free = size.width - self.size.width;
+ let size = Size::new(self.size.w.max(width), self.size.h);
+ let free = size.w - self.size.w;
let mut output = Frame::new(size, self.baseline);
let mut offset = Length::zero();
@@ -539,7 +527,7 @@ impl<'a> LineLayout<'a> {
self.baseline - frame.baseline,
);
- offset += frame.size.width;
+ offset += frame.size.w;
output.push_frame(pos, frame);
});
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index d07f68d7..d31012f0 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -3,10 +3,10 @@ use super::*;
/// A node that stacks its children.
#[cfg_attr(feature = "layout-cache", derive(Hash))]
pub struct StackNode {
- /// The `main` and `cross` directions of this stack.
+ /// The inline and block directions of this stack.
///
- /// The children are stacked along the `main` direction. The `cross`
- /// direction is required for aligning the children.
+ /// The children are stacked along the block direction. The inline direction
+ /// is required for aligning the children.
pub dirs: Gen<Dir>,
/// The nodes to be stacked.
pub children: Vec<StackChild>,
@@ -41,8 +41,8 @@ impl From<StackNode> for LayoutNode {
struct StackLayouter<'a> {
/// The stack node to layout.
stack: &'a StackNode,
- /// The axis of the main direction.
- main: SpecAxis,
+ /// The axis of the block direction.
+ block: SpecAxis,
/// Whether the stack should expand to fill the region.
expand: Spec<bool>,
/// The region to layout into.
@@ -68,16 +68,16 @@ struct StackLayouter<'a> {
impl<'a> StackLayouter<'a> {
/// Create a new stack layouter.
fn new(stack: &'a StackNode, mut regions: Regions) -> Self {
- let main = stack.dirs.main.axis();
+ let block = stack.dirs.block.axis();
let full = regions.current;
let expand = regions.expand;
- // Disable expansion on the main axis for children.
- regions.expand.set(main, false);
+ // Disable expansion along the block axis for children.
+ regions.expand.set(block, false);
Self {
stack,
- main,
+ block,
expand,
regions,
full,
@@ -112,34 +112,34 @@ impl<'a> StackLayouter<'a> {
self.finished
}
- /// Add main-axis spacing into the current region.
+ /// Add block-axis spacing into the current region.
fn space(&mut self, amount: Linear) {
// Resolve the linear.
- let full = self.full.get(self.main);
+ let full = self.full.get(self.block);
let resolved = amount.resolve(full);
// Cap the spacing to the remaining available space. This action does
// not directly affect the constraints because of the cap.
- let remaining = self.regions.current.get_mut(self.main);
+ let remaining = self.regions.current.get_mut(self.block);
let capped = resolved.min(*remaining);
// Grow our size and shrink the available space in the region.
- self.used.main += capped;
+ self.used.block += capped;
*remaining -= capped;
}
/// Push a frame into the current or next fitting region, finishing regions
/// if necessary.
fn push_frame(&mut self, frame: Rc<Frame>, aligns: Gen<Align>) {
- let size = frame.size.to_gen(self.main);
+ let size = frame.size.to_gen(self.block);
// Don't allow `Start` after `End` in the same region.
- if aligns.main < self.ruler {
+ if aligns.block < self.ruler {
self.finish_region();
}
// Find a fitting region.
- while !self.regions.current.get(self.main).fits(size.main) {
+ while !self.regions.current.get(self.block).fits(size.block) {
if self.regions.in_full_last() {
self.overflowing = true;
break;
@@ -147,20 +147,20 @@ impl<'a> StackLayouter<'a> {
self.constraints
.max
- .get_mut(self.main)
- .set_min(self.used.main + size.main);
+ .get_mut(self.block)
+ .set_min(self.used.block + size.block);
self.finish_region();
}
// Shrink available space in the region.
- *self.regions.current.get_mut(self.main) -= size.main;
+ *self.regions.current.get_mut(self.block) -= size.block;
// Grow our size.
- let offset = self.used.main;
- self.used.main += size.main;
- self.used.cross.set_max(size.cross);
- self.ruler = aligns.main;
+ let offset = self.used.block;
+ self.used.block += size.block;
+ self.used.inline.set_max(size.inline);
+ self.ruler = aligns.block;
// Remember the frame with offset and alignment.
self.frames.push((offset, aligns, frame));
@@ -169,60 +169,60 @@ impl<'a> StackLayouter<'a> {
/// Finish the frame for one region.
fn finish_region(&mut self) {
let expand = self.expand;
- let used = self.used.to_size(self.main);
+ let used = self.used.to_size(self.block);
// Determine the stack's size dependening on whether the region is
// fixed.
let size = Size::new(
- if expand.horizontal {
- self.constraints.exact.horizontal = Some(self.full.width);
- self.full.width
+ if expand.x {
+ self.constraints.exact.x = Some(self.full.w);
+ self.full.w
} else {
- self.constraints.min.horizontal = Some(used.width);
- used.width
+ self.constraints.min.x = Some(used.w);
+ used.w
},
- if expand.vertical {
- self.constraints.exact.vertical = Some(self.full.height);
- self.full.height
+ if expand.y {
+ self.constraints.exact.y = Some(self.full.h);
+ self.full.h
} else {
- self.constraints.min.vertical = Some(used.height);
- used.height
+ self.constraints.min.y = Some(used.h);
+ used.h
},
);
if self.overflowing {
- self.constraints.min.vertical = None;
- self.constraints.max.vertical = None;
+ self.constraints.min.y = None;
+ self.constraints.max.y = None;
self.constraints.exact = self.full.to_spec().map(Some);
}
- let mut output = Frame::new(size, size.height);
+ let mut output = Frame::new(size, size.h);
let mut first = true;
// Place all frames.
for (offset, aligns, frame) in self.frames.drain(..) {
- let stack_size = size.to_gen(self.main);
- let child_size = frame.size.to_gen(self.main);
+ let stack_size = size.to_gen(self.block);
+ let child_size = frame.size.to_gen(self.block);
- // Align along the cross axis.
- let cross = aligns.cross.resolve(
- self.stack.dirs.cross,
- Length::zero() .. stack_size.cross - child_size.cross,
+ // Align along the inline axis.
+ let inline = aligns.inline.resolve(
+ self.stack.dirs.inline,
+ Length::zero() .. stack_size.inline - child_size.inline,
);
- // Align along the main axis.
- let main = aligns.main.resolve(
- self.stack.dirs.main,
- if self.stack.dirs.main.is_positive() {
- offset .. stack_size.main - self.used.main + offset
+ // Align along the block axis.
+ let block = aligns.block.resolve(
+ self.stack.dirs.block,
+ if self.stack.dirs.block.is_positive() {
+ offset .. stack_size.block - self.used.block + offset
} else {
- let offset_with_self = offset + child_size.main;
- self.used.main - offset_with_self
- .. stack_size.main - offset_with_self
+ let offset_with_self = offset + child_size.block;
+ self.used.block - offset_with_self
+ .. stack_size.block - offset_with_self
},
);
- let pos = Gen::new(cross, main).to_point(self.main);
+ let pos = Gen::new(inline, block).to_point(self.block);
// The baseline of the stack is that of the first frame.
if first {
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index 05f94c38..224313f6 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -35,8 +35,7 @@ impl PageRun {
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> {
// When one of the lengths is infinite the page fits its content along
// that axis.
- let Size { width, height } = self.size;
- let expand = Spec::new(width.is_finite(), height.is_finite());
+ let expand = self.size.to_spec().map(Length::is_finite);
let regions = Regions::repeat(self.size, self.size, expand);
self.child.layout(ctx, &regions).into_iter().map(|c| c.item).collect()
}