mirror of
https://github.com/typst/typst
synced 2025-08-14 23:18:32 +08:00
top hlines attach to the top of row groups
This commit is contained in:
parent
c7e00f7ab2
commit
f1eadf7323
@ -1101,6 +1101,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
|||||||
// a non-empty row.
|
// a non-empty row.
|
||||||
let mut first_available_row = 0;
|
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 {
|
let (header_footer_items, simple_item) = match child {
|
||||||
ResolvableGridChild::Header { repeat, span, items, .. } => {
|
ResolvableGridChild::Header { repeat, span, items, .. } => {
|
||||||
if header.is_some() {
|
if header.is_some() {
|
||||||
@ -1115,6 +1123,15 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
|||||||
first_available_row =
|
first_available_row =
|
||||||
find_next_empty_row(resolved_cells, local_auto_index, columns);
|
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,
|
// If any cell in the header is automatically positioned,
|
||||||
// have it skip to the next empty row. This is to avoid
|
// have it skip to the next empty row. This is to avoid
|
||||||
// having a header after a partially filled row just add
|
// having a header after a partially filled row just add
|
||||||
@ -1141,6 +1158,8 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
|||||||
first_available_row =
|
first_available_row =
|
||||||
find_next_empty_row(resolved_cells, local_auto_index, columns);
|
find_next_empty_row(resolved_cells, local_auto_index, columns);
|
||||||
|
|
||||||
|
top_hlines_start = pending_hlines.len();
|
||||||
|
|
||||||
local_auto_index = first_available_row * columns;
|
local_auto_index = first_available_row * columns;
|
||||||
|
|
||||||
(Some(items), None)
|
(Some(items), None)
|
||||||
@ -1316,6 +1335,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
|||||||
)
|
)
|
||||||
.at(cell_span)?,
|
.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
|
// 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 {
|
match row_group.kind {
|
||||||
RowGroupKind::Header => {
|
RowGroupKind::Header => {
|
||||||
if group_range.start != 0 {
|
if group_range.start != 0 {
|
||||||
|
BIN
tests/ref/grid-footer-top-hlines-with-only-row-pos-cell.png
Normal file
BIN
tests/ref/grid-footer-top-hlines-with-only-row-pos-cell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 385 B |
BIN
tests/ref/grid-footer-top-hlines-with-row-and-auto-pos-cell.png
Normal file
BIN
tests/ref/grid-footer-top-hlines-with-row-and-auto-pos-cell.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 579 B |
@ -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 ---
|
--- grid-footer-below-rowspans ---
|
||||||
// Footer should go below the rowspans.
|
// Footer should go below the rowspans.
|
||||||
#set page(margin: 2pt)
|
#set page(margin: 2pt)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user