summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPgBiel <9021226+PgBiel@users.noreply.github.com>2025-06-21 23:36:31 -0300
committerPgBiel <9021226+PgBiel@users.noreply.github.com>2025-06-28 22:39:35 -0300
commitd13617ed9b9dd95376b8d068b85513cba8b1b702 (patch)
treee738662b7c985fc2f4119ac1becb0d80ec45e8e1
parent315612b1f7be637c0c1a6a123f8802e09bee332a (diff)
skip layout of redundant gutter at the top of footertable-subfooters
-rw-r--r--crates/typst-layout/src/grid/layouter.rs2
-rw-r--r--crates/typst-layout/src/grid/repeated.rs20
-rw-r--r--tests/ref/grid-footer-gutter-short-lived.pngbin0 -> 321 bytes
-rw-r--r--tests/suite/layout/grid/footers.typ14
4 files changed, 32 insertions, 4 deletions
diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs
index fd846b6e..8e810e32 100644
--- a/crates/typst-layout/src/grid/layouter.rs
+++ b/crates/typst-layout/src/grid/layouter.rs
@@ -232,7 +232,7 @@ pub(super) enum Row {
impl Row {
/// Returns the `y` index of this row.
- fn index(&self) -> usize {
+ pub(super) fn index(&self) -> usize {
match self {
Self::Frame(_, y, _) => *y,
Self::Fr(_, y, _) => *y,
diff --git a/crates/typst-layout/src/grid/repeated.rs b/crates/typst-layout/src/grid/repeated.rs
index 86506df7..6a76cb71 100644
--- a/crates/typst-layout/src/grid/repeated.rs
+++ b/crates/typst-layout/src/grid/repeated.rs
@@ -679,9 +679,23 @@ impl<'a> GridLayouter<'a> {
let footer_len = footer.range.end - footer.range.start;
self.unbreakable_rows_left += footer_len;
- // TODO(subfooters): also consider omitted gutter before the footer
- // when there is a header right before it taking it.
- for y in footer.range.clone() {
+ let footer_start = if self.grid.is_gutter_track(footer.range.start)
+ && self
+ .current
+ .lrows
+ .last()
+ .is_none_or(|r| self.grid.is_gutter_track(r.index()))
+ {
+ // Skip gutter at the top of footer if there's already a gutter
+ // from a repeated header right before it in the current region.
+ // Normally, that shouldn't happen as it indicates we have a widow,
+ // but we can't fully prevent widows anyway.
+ footer.range.start + 1
+ } else {
+ footer.range.start
+ };
+
+ for y in footer_start..footer.range.end {
self.layout_row_with_state(
y,
engine,
diff --git a/tests/ref/grid-footer-gutter-short-lived.png b/tests/ref/grid-footer-gutter-short-lived.png
new file mode 100644
index 00000000..2eb74a86
--- /dev/null
+++ b/tests/ref/grid-footer-gutter-short-lived.png
Binary files differ
diff --git a/tests/suite/layout/grid/footers.typ b/tests/suite/layout/grid/footers.typ
index 286928b8..b7984121 100644
--- a/tests/suite/layout/grid/footers.typ
+++ b/tests/suite/layout/grid/footers.typ
@@ -41,6 +41,20 @@
)
)
+--- grid-footer-gutter-short-lived ---
+// Gutter, no repetition, short-lived
+#set page(height: 6em)
+#set text(6pt)
+#set table(inset: 2pt, stroke: 0.5pt)
+#table(
+ gutter: 2pt,
+ align: center + horizon,
+ table.header([a]),
+ table.footer([b]),
+ table.footer([c]),
+ [d],
+)
+
--- grid-cell-override-in-header-and-footer ---
#table(
table.header(table.cell(stroke: red)[Hello]),