diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index 31e17894d..d46040910 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -1600,12 +1600,20 @@ impl<'a> GridLayouter<'a> { // // Use index for iteration to avoid borrow conflict. // + // Note that repeating footers are in reverse order. + // // TODO(subfooters): "pending footers" vector for footers we're // about to place. Needed for widow prevention of non-repeated // footers. let mut i = 0; - while let Some(footer) = self.repeating_footers.get(i) { - self.layout_footer(footer, false, engine, self.finished.len())?; + while let Some(footer_index) = self.repeating_footers.len().checked_sub(1 + i) + { + self.layout_footer( + self.repeating_footers[footer_index], + false, + engine, + self.finished.len(), + )?; i += 1; } } diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index 2f9a5a947..2ebd2d9a7 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -550,9 +550,17 @@ impl<'a> GridLayouter<'a> { return Ok(()); } + // Collect upcoming consecutive footers, they will start repeating with + // this one if compatible + let mut min_level = next_footer.level; let first_conflicting_index = other_footers .iter() - .take_while(|f| f.level > next_footer.level) + .take_while(|f| { + // TODO(subfooters): check for short-lived + let compatible = f.repeated && f.level > min_level; + min_level = f.level; + compatible + }) .count() + 1;