diff options
| author | PgBiel <9021226+PgBiel@users.noreply.github.com> | 2025-05-20 21:45:43 -0300 |
|---|---|---|
| committer | PgBiel <9021226+PgBiel@users.noreply.github.com> | 2025-06-28 22:39:35 -0300 |
| commit | 5f663a8da43bc8529737e62c5a6828b588a44daf (patch) | |
| tree | 9b10829f892394c2bc2fc9029c477c68ff6a7e2f | |
| parent | 3bf0f2b48c1561efe7b180674df348600dc64648 (diff) | |
initial footer properties and bumping
| -rw-r--r-- | crates/typst-layout/src/grid/layouter.rs | 15 | ||||
| -rw-r--r-- | crates/typst-layout/src/grid/repeated.rs | 28 |
2 files changed, 43 insertions, 0 deletions
diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index 42fe38db..9f714ac8 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -6,6 +6,7 @@ use typst_library::foundations::{Resolve, StyleChain}; use typst_library::layout::grid::resolve::{ Cell, CellGrid, Header, LinePosition, Repeatable, }; +use typst_library::layout::resolve::Footer; use typst_library::layout::{ Abs, Axes, Dir, Fr, Fragment, Frame, FrameItem, Length, Point, Region, Regions, Rel, Size, Sizing, @@ -60,6 +61,16 @@ pub struct GridLayouter<'a> { pub(super) pending_headers: &'a [Repeatable<Header>], /// Next headers to be processed. pub(super) upcoming_headers: &'a [Repeatable<Header>], + /// Currently repeating footers, one per level. Sorted by increasing + /// levels. + /// + /// Note that some levels may be absent, in particular level 0, which does + /// not exist (so all levels are >= 1). + pub(super) repeating_footers: Vec<&'a Footer>, + /// Next footers to be processed. + pub(super) upcoming_footers: &'a [Repeatable<Footer>], + /// Next footers sorted by when they start repeating. + pub(super) upcoming_sorted_footers: &'a [Repeatable<Footer>], /// State of the row being currently laid out. /// /// This is kept as a field to avoid passing down too many parameters from @@ -253,6 +264,10 @@ impl<'a> GridLayouter<'a> { repeating_headers: vec![], upcoming_headers: &grid.headers, pending_headers: Default::default(), + // This is calculated on layout + repeating_footers: vec![], + upcoming_footers: &grid.footers, + upcoming_sorted_footers: &grid.sorted_footers, row_state: RowState::default(), current: Current { initial: regions.size, diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index 8db33df5..7ca937e7 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -463,6 +463,34 @@ impl<'a> GridLayouter<'a> { ) } + pub fn bump_repeating_footers(&mut self) -> &'a [Repeatable<Footer>] { + let [next_footer, other_footers @ ..] = self.upcoming_sorted_footers else { + return &[]; + }; + + if !next_footer.repeated { + // TODO(subfooters): grouping and laying them out together? + self.upcoming_sorted_footers = other_footers; + return &[]; + } + + if other_footers.is_empty() { + return std::mem::replace(&mut self.upcoming_sorted_footers, &[]); + } + + let first_conflicting_index = other_footers + .iter() + .take_while(|f| f.level > next_footer.level) + .count() + + 1; + + let (next_repeating_footers, new_upcoming_footers) = + self.upcoming_sorted_footers.split_at(first_conflicting_index); + + self.upcoming_sorted_footers = new_upcoming_footers; + return next_repeating_footers; + } + /// Updates `self.footer_height` by simulating the footer, and skips to fitting region. pub fn prepare_footer( &mut self, |
