diff --git a/src/layout/incremental.rs b/src/layout/incremental.rs index 427df079..7857f33c 100644 --- a/src/layout/incremental.rs +++ b/src/layout/incremental.rs @@ -20,6 +20,19 @@ impl LayoutCache { pub fn clear(&mut self) { self.frames.clear(); } + + /// Retains all elements for which the closure on the level returns `true`. + pub fn retain(&mut self, mut f: F) + where + F: FnMut(usize) -> bool, + { + self.frames.retain(|_, b| f(b.level)); + } + + /// Amount of items in the cache. + pub fn len(&self) -> usize { + self.frames.len() + } } #[derive(Debug, Clone)] @@ -27,6 +40,8 @@ impl LayoutCache { pub struct FramesEntry { /// The cached frames for a node. pub frames: Vec>, + /// How nested the frame was in the context is was originally appearing in. + pub level: usize, } impl FramesEntry { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 15c80017..28e83da9 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -32,7 +32,7 @@ use crate::loading::Loader; /// Layout a tree into a collection of frames. pub fn layout(loader: &mut dyn Loader, cache: &mut Cache, tree: &Tree) -> Vec { - tree.layout(&mut LayoutContext { loader, cache }) + tree.layout(&mut LayoutContext { loader, cache, level: 0 }) } /// A tree of layout nodes. @@ -98,19 +98,23 @@ impl Layout for AnyNode { ctx: &mut LayoutContext, regions: &Regions, ) -> Vec> { - ctx.cache + ctx.level += 1; + let frames = ctx + .cache .layout .frames .get(&self.hash) .and_then(|x| x.check(regions.clone())) .unwrap_or_else(|| { let frames = self.node.layout(ctx, regions); - ctx.cache - .layout - .frames - .insert(self.hash, FramesEntry { frames: frames.clone() }); + ctx.cache.layout.frames.insert(self.hash, FramesEntry { + frames: frames.clone(), + level: ctx.level - 1, + }); frames - }) + }); + ctx.level -= 1; + frames } } @@ -184,6 +188,8 @@ pub struct LayoutContext<'a> { pub loader: &'a mut dyn Loader, /// A cache for loaded fonts and artifacts from past layouting. pub cache: &'a mut Cache, + /// How deeply nested is the current layout tree position. + pub level: usize, } /// A sequence of regions to layout into. diff --git a/src/library/image.rs b/src/library/image.rs index bd7f2f67..f8c04cbe 100644 --- a/src/library/image.rs +++ b/src/library/image.rs @@ -2,7 +2,9 @@ use ::image::GenericImageView; use super::*; use crate::image::ImageId; -use crate::layout::{AnyNode, Constrained, Constraints, Element, Frame, Layout, LayoutContext, Regions}; +use crate::layout::{ + AnyNode, Constrained, Constraints, Element, Frame, Layout, LayoutContext, Regions, +}; /// `image`: An image. /// @@ -52,7 +54,11 @@ struct ImageNode { } impl Layout for ImageNode { - fn layout(&self, _: &mut LayoutContext, regions: &Regions) -> Vec> { + fn layout( + &self, + _: &mut LayoutContext, + regions: &Regions, + ) -> Vec> { let Regions { current, base, .. } = regions; let mut constraints = Constraints::new(regions.expand); constraints.set_base_using_linears(Spec::new(self.width, self.height), regions); diff --git a/tests/typeset.rs b/tests/typeset.rs index f4e74bc1..c6d3e8f1 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -225,6 +225,7 @@ fn test_part( state.page.margins = Sides::splat(Some(Length::pt(10.0).into())); let mut pass = typst::typeset(loader, cache, Some(src_path), &src, &scope, state); + if !compare_ref { pass.output.clear(); }