diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index ab416533c..52d42e732 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -1542,12 +1542,6 @@ impl<'a> GridLayouter<'a> { let mut laid_out_footer_start = None; if !footer_would_be_widow { - // Did not trigger automatic header orphan / footer widow check. - // This means pending headers have successfully been placed once - // without hitting orphan prevention, so they may now be moved into - // repeating headers. - self.flush_pending_headers(); - if let Some(Repeatable::Repeated(footer)) = &self.grid.footer { // Don't layout the footer if it would be alone with the header in // the page (hence the widow check), and don't layout it twice. diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index 9800f0204..d638c5afc 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -289,6 +289,12 @@ impl<'a> GridLayouter<'a> { self.current_repeating_header_rows = self.lrows.len(); + if !self.pending_headers.is_empty() { + // Restore snapshot: if pending headers placed again turn out to be + // orphans, remove their rows again. + self.lrows_orphan_snapshot = Some(self.lrows.len()); + } + for header in self.pending_headers { let header_height = self.layout_header_rows(header.unwrap(), engine, disambiguator)?;