top hlines attach to the top of row groups

This commit is contained in:
PgBiel 2025-03-12 21:12:46 -03:00
parent c7e00f7ab2
commit f1eadf7323
4 changed files with 72 additions and 0 deletions

View File

@ -1101,6 +1101,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// a non-empty row.
let mut first_available_row = 0;
// Indices of hlines at the top of the row group.
//
// These hlines were auto-positioned and appeared before any auto-pos
// cells, so they will appear at the first possible row (above the
// first row spanned by the row group).
let mut top_hlines_start = 0;
let mut top_hlines_end = None;
let (header_footer_items, simple_item) = match child {
ResolvableGridChild::Header { repeat, span, items, .. } => {
if header.is_some() {
@ -1115,6 +1123,15 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
first_available_row =
find_next_empty_row(resolved_cells, local_auto_index, columns);
// No hlines yet, so 'end' starts as 'None'. However, its
// starting bound indicates where any potential top hlines
// would start (they would appear after the latest hline placed
// in previous iterations), so we only extend the end bound as
// necessary once more hlines are added, until we reach the
// first auto-positioned cell. Then, further auto-pos hlines
// will NOT be at the top.
top_hlines_start = pending_hlines.len();
// If any cell in the header is automatically positioned,
// have it skip to the next empty row. This is to avoid
// having a header after a partially filled row just add
@ -1141,6 +1158,8 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
first_available_row =
find_next_empty_row(resolved_cells, local_auto_index, columns);
top_hlines_start = pending_hlines.len();
local_auto_index = first_available_row * columns;
(Some(items), None)
@ -1316,6 +1335,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
)
.at(cell_span)?,
);
if top_hlines_end.is_none()
&& local_auto_index > first_available_row * columns
{
// Auto index was moved, so upcoming auto-pos hlines should
// no longer appear at the top.
top_hlines_end = Some(pending_hlines.len());
}
}
// Let's resolve the cell so it can determine its own fields
@ -1428,6 +1455,19 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
}
};
let top_hlines_end = top_hlines_end.unwrap_or(pending_hlines.len());
for (_, top_hline, has_auto_y) in pending_hlines
.get_mut(top_hlines_start..top_hlines_end)
.unwrap_or(&mut [])
{
if *has_auto_y {
// Move this hline to the top of the child, as it was
// placed before the first automatically positioned cell
// and had an automatic index.
top_hline.index = group_range.start;
}
}
match row_group.kind {
RowGroupKind::Header => {
if group_range.start != 0 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

View File

@ -437,6 +437,38 @@
)
)
--- grid-footer-top-hlines-with-only-row-pos-cell ---
// Top hlines should attach to the top of the footer.
#set page(margin: 2pt)
#set text(6pt)
#table(
columns: 3,
inset: 2.5pt,
table.footer(
table.hline(stroke: red),
table.vline(stroke: blue),
table.cell(x: 2, y: 2)[a],
table.hline(stroke: 3pt),
table.vline(stroke: 3pt),
)
)
--- grid-footer-top-hlines-with-row-and-auto-pos-cell ---
#set page(margin: 2pt)
#set text(6pt)
#table(
columns: 3,
inset: 2.5pt,
table.footer(
table.hline(stroke: red),
table.vline(stroke: blue),
table.cell(x: 2, y: 2)[a],
[b],
table.hline(stroke: 3pt),
table.vline(stroke: 3pt),
)
)
--- grid-footer-below-rowspans ---
// Footer should go below the rowspans.
#set page(margin: 2pt)