diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index 75cf16995..8ebe59123 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -1376,14 +1376,13 @@ impl<'a> GridLayouter<'a> { // endlessly repeated) when subtracting header and footer height. // // See 'check_for_unbreakable_rows' as for why we're using - // 'header_height' to predict header height and not - // 'repeating_header_height'. + // 'repeating_header_height' to predict header height. let height = frame.height(); while self.unbreakable_rows_left == 0 && !self.regions.size.y.fits(height) && may_progress_with_offset( self.regions, - self.current.header_height + self.current.footer_height, + self.current.repeating_header_height + self.current.footer_height, ) { self.finish_region(engine, false)?; @@ -1571,11 +1570,9 @@ impl<'a> GridLayouter<'a> { && self.current.lrows.is_empty() && may_progress_with_offset( self.regions, - // This header height isn't doing much as we just - // confirmed that there are no headers in this region, - // but let's keep it here for correctness. It will add - // zero anyway. - self.current.header_height + self.current.footer_height, + // Don't sum header height as we just confirmed that there + // are no headers in this region. + self.current.footer_height, ); let mut laid_out_footer_start = None; diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs index 54f5cda7c..5b2be228b 100644 --- a/crates/typst-layout/src/grid/repeated.rs +++ b/crates/typst-layout/src/grid/repeated.rs @@ -377,7 +377,7 @@ impl<'a> GridLayouter<'a> { // 'header_height == repeating_header_height' here // (there won't be any pending headers at this point, other // than the ones we are about to place). - self.current.header_height + self.current.footer_height, + self.current.repeating_header_height + self.current.footer_height, ) { // Note that, after the first region skip, the new headers will go @@ -393,7 +393,7 @@ impl<'a> GridLayouter<'a> { && self.current.lrows_orphan_snapshot.is_none() && may_progress_with_offset( self.regions, - self.current.header_height + self.current.footer_height, + self.current.repeating_header_height + self.current.footer_height, ); if should_snapshot { diff --git a/crates/typst-layout/src/grid/rowspans.rs b/crates/typst-layout/src/grid/rowspans.rs index 3ffd71518..9cbae6fe8 100644 --- a/crates/typst-layout/src/grid/rowspans.rs +++ b/crates/typst-layout/src/grid/rowspans.rs @@ -258,12 +258,11 @@ impl GridLayouter<'_> { while !self.regions.size.y.fits(row_group.height) && may_progress_with_offset( self.regions, - // Note that we consider that the exact same headers and footers will be - // added if we skip like this (blocking other rows from being laid out) - // due to orphan/widow prevention, which explains the usage of - // 'header_height' (include non-repeating but pending headers) rather - // than 'repeating_header_height'. - self.current.header_height + self.current.footer_height, + // Use 'repeating_header_height' (ignoring the height of + // non-repeated headers) to allow skipping if the + // non-repeated header is too large. It will become an + // orphan, but when there is no space left, anything goes. + self.current.repeating_header_height + self.current.footer_height, ) { self.finish_region(engine, false)?; diff --git a/tests/ref/grid-subheaders-too-large-non-repeating-orphan-before-relative.png b/tests/ref/grid-subheaders-too-large-non-repeating-orphan-before-relative.png index dfcac8500..324787b25 100644 Binary files a/tests/ref/grid-subheaders-too-large-non-repeating-orphan-before-relative.png and b/tests/ref/grid-subheaders-too-large-non-repeating-orphan-before-relative.png differ