summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-02-02 15:25:43 +0100
committerLaurenz <laurmaedje@gmail.com>2022-02-02 15:25:43 +0100
commit0a1916c1e4259aff1306b26c06d4edcf0f190a3b (patch)
tree8ab81f034dd8b392b368691a2d55349f5c798d85 /src/layout
parentbdb1c008f2cee7c3929b671d9407d2b578182199 (diff)
Remove width from backlog and last region
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/mod.rs9
-rw-r--r--src/layout/regions.rs58
2 files changed, 41 insertions, 26 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 147e8c9d..ebdfba0e 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -200,6 +200,7 @@ impl PackedNode {
}
impl Layout for PackedNode {
+ #[track_caller]
fn layout(
&self,
ctx: &mut LayoutContext,
@@ -219,8 +220,12 @@ impl Layout for PackedNode {
state.finish()
};
+ // This is not written with `unwrap_or_else`, because then the
+ // #[track_caller] annotation doesn't work.
#[cfg(feature = "layout-cache")]
- ctx.layout_cache.get(hash, regions).unwrap_or_else(|| {
+ if let Some(frames) = ctx.layout_cache.get(hash, regions) {
+ frames
+ } else {
ctx.level += 1;
let frames = self.node.layout(ctx, regions, styles);
ctx.level -= 1;
@@ -240,7 +245,7 @@ impl Layout for PackedNode {
ctx.layout_cache.insert(hash, entry);
frames
- })
+ }
}
fn pack(self) -> PackedNode {
diff --git a/src/layout/regions.rs b/src/layout/regions.rs
index 66e6da17..3f8b6d25 100644
--- a/src/layout/regions.rs
+++ b/src/layout/regions.rs
@@ -7,10 +7,11 @@ pub struct Regions {
pub current: Size,
/// The base size for relative sizing.
pub base: Size,
- /// An iterator of followup regions.
- pub backlog: std::vec::IntoIter<Size>,
- /// The final region that is repeated once the backlog is drained.
- pub last: Option<Size>,
+ /// The height of followup regions. The width is the same for all regions.
+ pub backlog: std::vec::IntoIter<Length>,
+ /// The height of the final region that is repeated once the backlog is
+ /// drained. The width is the same for all regions.
+ pub last: Option<Length>,
/// Whether nodes should expand to fill the regions instead of shrinking to
/// fit the content.
pub expand: Spec<bool>,
@@ -34,19 +35,33 @@ impl Regions {
current: size,
base,
backlog: vec![].into_iter(),
- last: Some(size),
+ last: Some(size.y),
expand,
}
}
/// Create new regions where all sizes are mapped with `f`.
+ ///
+ /// Note that since all regions must have the same width, the width returned
+ /// by `f` is ignored for the backlog and the final region.
pub fn map<F>(&self, mut f: F) -> Self
where
F: FnMut(Size) -> Size,
{
- let mut regions = self.clone();
- regions.mutate(|s| *s = f(*s));
- regions
+ let x = self.current.x;
+ Self {
+ current: f(self.current),
+ base: f(self.base),
+ backlog: self
+ .backlog
+ .as_slice()
+ .iter()
+ .map(|&y| f(Size::new(x, y)).y)
+ .collect::<Vec<_>>()
+ .into_iter(),
+ last: self.last.map(|y| f(Size::new(x, y)).y),
+ expand: self.expand,
+ }
}
/// Whether the current region is full and a region break is called for.
@@ -58,14 +73,15 @@ impl Regions {
///
/// If this is true, calling `next()` will have no effect.
pub fn in_last(&self) -> bool {
- self.backlog.len() == 0 && self.last.map_or(true, |size| self.current == size)
+ self.backlog.len() == 0
+ && self.last.map_or(true, |height| self.current.y == height)
}
/// Advance to the next region if there is any.
pub fn next(&mut self) {
- if let Some(size) = self.backlog.next().or(self.last) {
- self.current = size;
- self.base = size;
+ if let Some(height) = self.backlog.next().or(self.last) {
+ self.current.y = height;
+ self.base.y = height;
}
}
@@ -76,17 +92,11 @@ impl Regions {
let first = std::iter::once((self.current, self.base));
let backlog = self.backlog.as_slice().iter();
let last = self.last.iter().cycle();
- first.chain(backlog.chain(last).map(|&s| (s, s)))
- }
-
- /// Mutate all contained sizes in place.
- pub fn mutate<F>(&mut self, mut f: F)
- where
- F: FnMut(&mut Size),
- {
- f(&mut self.current);
- f(&mut self.base);
- self.last.as_mut().map(|x| f(x));
- self.backlog.as_mut_slice().iter_mut().for_each(f);
+ first.chain(backlog.chain(last).map(|&height| {
+ (
+ Size::new(self.current.x, height),
+ Size::new(self.base.x, height),
+ )
+ }))
}
}