summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPgBiel <9021226+PgBiel@users.noreply.github.com>2025-05-20 21:45:43 -0300
committerPgBiel <9021226+PgBiel@users.noreply.github.com>2025-06-28 22:39:35 -0300
commit5f663a8da43bc8529737e62c5a6828b588a44daf (patch)
tree9b10829f892394c2bc2fc9029c477c68ff6a7e2f
parent3bf0f2b48c1561efe7b180674df348600dc64648 (diff)
initial footer properties and bumping
-rw-r--r--crates/typst-layout/src/grid/layouter.rs15
-rw-r--r--crates/typst-layout/src/grid/repeated.rs28
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,