Ensure hline/vline positioning respects colspan/rowspan (#3610)

This commit is contained in:
PgBiel 2024-03-11 07:32:44 -03:00 committed by GitHub
parent 3310dda008
commit 443cf60ae2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 3 deletions

View File

@ -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)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -288,6 +288,19 @@
table.hline(stroke: blue, start: 1, end: 2),
)
---
// - 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