Rename expand to fixed and switch to bools

This commit is contained in:
Laurenz 2021-05-17 15:00:29 +02:00
parent fbb823964f
commit 1003d320d4
5 changed files with 34 additions and 55 deletions

View File

@ -31,13 +31,8 @@ impl Layout for FixedNode {
size = Size::new(width, width / aspect); size = Size::new(width, width / aspect);
} }
let fill_if = |cond| if cond { Expand::Fill } else { Expand::Fit }; let fixed = Spec::new(self.width.is_some(), self.height.is_some());
let expand = Spec::new( let areas = Areas::once(size, full, fixed).with_aspect(self.aspect);
fill_if(self.width.is_some()),
fill_if(self.height.is_some()),
);
let areas = Areas::once(size, full, expand).with_aspect(self.aspect);
self.child.layout(ctx, &areas) self.child.layout(ctx, &areas)
} }
} }

View File

@ -18,6 +18,7 @@ pub struct Frame {
impl Frame { impl Frame {
/// Create a new, empty frame. /// Create a new, empty frame.
pub fn new(size: Size, baseline: Length) -> Self { pub fn new(size: Size, baseline: Length) -> Self {
assert!(size.is_finite());
Self { size, baseline, elements: vec![] } Self { size, baseline, elements: vec![] }
} }

View File

@ -54,7 +54,11 @@ pub struct PageRun {
impl PageRun { impl PageRun {
/// Layout the page run. /// Layout the page run.
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> { pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> {
let areas = Areas::repeat(self.size, Spec::uniform(Expand::Fill)); // When one of the lengths is infinite the page fits its content along
// that axis.
let Size { width, height } = self.size;
let fixed = Spec::new(width.is_finite(), height.is_finite());
let areas = Areas::repeat(self.size, fixed);
self.child.layout(ctx, &areas) self.child.layout(ctx, &areas)
} }
} }
@ -146,12 +150,11 @@ pub struct Areas {
pub backlog: Vec<Size>, pub backlog: Vec<Size>,
/// The final area that is repeated when the backlog is empty. /// The final area that is repeated when the backlog is empty.
pub last: Option<Size>, pub last: Option<Size>,
/// Whether the frames resulting from layouting into this areas should be /// Whether the frames resulting from layouting into this areas should
/// shrunk to fit their content or expanded to fill the area. /// expand to the fixed size defined by `current`.
/// ///
/// This property is handled partially by the par layouter and fully by the /// If this is false, the frame will shrink to fit its content.
/// stack layouter. pub fixed: Spec<bool>,
pub expand: Spec<Expand>,
/// The aspect ratio the resulting frame should respect. /// The aspect ratio the resulting frame should respect.
/// ///
/// This property is only handled by the stack layouter. /// This property is only handled by the stack layouter.
@ -159,26 +162,26 @@ pub struct Areas {
} }
impl Areas { impl Areas {
/// Create a new sequence of areas that repeats `area` indefinitely.
pub fn repeat(size: Size, expand: Spec<Expand>) -> Self {
Self {
current: size,
full: size,
backlog: vec![],
last: Some(size),
expand,
aspect: None,
}
}
/// Create a new length-1 sequence of areas with just one `area`. /// Create a new length-1 sequence of areas with just one `area`.
pub fn once(size: Size, full: Size, expand: Spec<Expand>) -> Self { pub fn once(size: Size, full: Size, fixed: Spec<bool>) -> Self {
Self { Self {
current: size, current: size,
full, full,
backlog: vec![], backlog: vec![],
last: None, last: None,
expand, fixed,
aspect: None,
}
}
/// Create a new sequence of areas that repeats `area` indefinitely.
pub fn repeat(size: Size, fixed: Spec<bool>) -> Self {
Self {
current: size,
full: size,
backlog: vec![],
last: Some(size),
fixed,
aspect: None, aspect: None,
} }
} }
@ -199,7 +202,7 @@ impl Areas {
full: f(self.full), full: f(self.full),
backlog: self.backlog.iter().copied().map(|s| f(s)).collect(), backlog: self.backlog.iter().copied().map(|s| f(s)).collect(),
last: self.last.map(f), last: self.last.map(f),
expand: self.expand, fixed: self.fixed,
aspect: self.aspect, aspect: self.aspect,
} }
} }
@ -222,24 +225,3 @@ impl Areas {
}) })
} }
} }
/// Whether to expand or shrink a node along an axis.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Expand {
/// Fit the content.
Fit,
/// Fill the available space.
Fill,
}
impl Expand {
/// Resolve the expansion to either the `fit` or `fill` length.
///
/// Prefers `fit` if `fill` is infinite.
pub fn resolve(self, fit: Length, fill: Length) -> Length {
match self {
Self::Fill if fill.is_finite() => fill,
_ => fit,
}
}
}

View File

@ -301,8 +301,9 @@ impl<'a> LineStack<'a> {
} }
fn finish_area(&mut self, ctx: &mut LayoutContext) { fn finish_area(&mut self, ctx: &mut LayoutContext) {
let expand = self.areas.expand.horizontal; if self.areas.fixed.horizontal {
self.size.width = expand.resolve(self.size.width, self.areas.full.width); self.size.width = self.areas.current.width;
}
let mut output = Frame::new(self.size, self.size.height); let mut output = Frame::new(self.size, self.size.height);
let mut first = true; let mut first = true;

View File

@ -104,12 +104,12 @@ impl StackLayouter {
fn finish_area(&mut self) { fn finish_area(&mut self) {
let full_size = { let full_size = {
let Areas { current, full, expand, .. } = self.areas; let Areas { current, full, fixed, .. } = self.areas;
let used = self.size.switch(self.main).to_size();
let used = self.size.switch(self.main).to_size();
let mut size = Size::new( let mut size = Size::new(
expand.horizontal.resolve(used.width, full.width), if fixed.horizontal { full.width } else { used.width },
expand.vertical.resolve(used.height, full.height), if fixed.vertical { full.height } else { used.height },
); );
if let Some(aspect) = self.areas.aspect { if let Some(aspect) = self.areas.aspect {