summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPgBiel <9021226+PgBiel@users.noreply.github.com>2024-03-11 07:32:44 -0300
committerGitHub <noreply@github.com>2024-03-11 10:32:44 +0000
commit443cf60ae21d7d638a3279b64e22f6beb3a5f1b0 (patch)
tree3f6fb7d51f5f7162e39244f3ae61fd576cb8c76a
parent3310dda0085aea6bca9ed574410b65f2b93de94b (diff)
Ensure hline/vline positioning respects colspan/rowspan (#3610)
-rw-r--r--crates/typst/src/layout/grid/layout.rs22
-rw-r--r--tests/ref/layout/grid-stroke.pngbin55633 -> 57339 bytes
-rw-r--r--tests/typ/layout/grid-stroke.typ13
3 files changed, 32 insertions, 3 deletions
diff --git a/crates/typst/src/layout/grid/layout.rs b/crates/typst/src/layout/grid/layout.rs
index 772c107e..20b2ddc8 100644
--- a/crates/typst/src/layout/grid/layout.rs
+++ b/crates/typst/src/layout/grid/layout.rs
@@ -646,6 +646,8 @@ impl CellGrid {
ResolvableGridItem::Cell(cell) => cell,
};
let cell_span = cell.span();
+ let colspan = cell.colspan(styles).get();
+ let rowspan = cell.rowspan(styles).get();
// Let's calculate the cell's final position based on its
// requested position.
let resolved_index = {
@@ -654,6 +656,8 @@ impl CellGrid {
resolve_cell_position(
cell_x,
cell_y,
+ colspan,
+ rowspan,
&resolved_cells,
&mut auto_index,
min_auto_index,
@@ -663,8 +667,6 @@ impl CellGrid {
};
let x = resolved_index % c;
let y = resolved_index / c;
- let colspan = cell.colspan(styles).get();
- let rowspan = cell.rowspan(styles).get();
if colspan > c - x {
bail!(
@@ -1284,9 +1286,12 @@ impl CellGrid {
/// positioning. Useful with headers: if a cell in a header has automatic
/// positioning, it should start at the header's first row, and not at the end
/// of the previous row.
+#[allow(clippy::too_many_arguments)]
fn resolve_cell_position(
cell_x: Smart<usize>,
cell_y: Smart<usize>,
+ colspan: usize,
+ rowspan: usize,
resolved_cells: &[Option<Entry>],
auto_index: &mut usize,
min_auto_index: usize,
@@ -1316,7 +1321,18 @@ fn resolve_cell_position(
// Ensure the next cell with automatic position will be
// placed after this one (maybe not immediately after).
- *auto_index = resolved_index + 1;
+ //
+ // The calculation below also affects the position of the upcoming
+ // automatically-positioned lines.
+ *auto_index = if colspan == columns {
+ // The cell occupies all columns, so no cells can be placed
+ // after it until all of its rows have been spanned.
+ resolved_index + colspan * rowspan
+ } else {
+ // The next cell will have to be placed at least after its
+ // spanned columns.
+ resolved_index + colspan
+ };
Ok(resolved_index)
}
diff --git a/tests/ref/layout/grid-stroke.png b/tests/ref/layout/grid-stroke.png
index 409d10f1..e9f9b061 100644
--- a/tests/ref/layout/grid-stroke.png
+++ b/tests/ref/layout/grid-stroke.png
Binary files differ
diff --git a/tests/typ/layout/grid-stroke.typ b/tests/typ/layout/grid-stroke.typ
index 9d01e1cd..7a01b52d 100644
--- a/tests/typ/layout/grid-stroke.typ
+++ b/tests/typ/layout/grid-stroke.typ
@@ -289,6 +289,19 @@
)
---
+// - Vline should be placed after the colspan.
+// - Hline should be placed under the full-width rowspan.
+#table(
+ columns: 3,
+ rows: 1.25em,
+ inset: 1pt,
+ stroke: none,
+ table.cell(colspan: 2)[a], table.vline(stroke: red), table.hline(stroke: blue), [b],
+ [c], [d], [e],
+ table.cell(colspan: 3, rowspan: 2)[a], table.vline(stroke: blue), table.hline(stroke: red)
+)
+
+---
// Error: 8:3-8:32 cannot place horizontal line at the 'bottom' position of the bottom border (y = 2)
// Hint: 8:3-8:32 set the line's position to 'top' or place it at a smaller 'y' index
#table(