mirror of
https://github.com/typst/typst
synced 2025-06-15 00:26:26 +08:00
use header.range field
a bit verbose at times but seems potentially more consistent
This commit is contained in:
parent
88c9dea3fa
commit
b997450a4b
@ -287,9 +287,9 @@ impl<'a> GridLayouter<'a> {
|
||||
while y < self.grid.rows.len() {
|
||||
if let Some(next_header) = self.upcoming_headers.get(consecutive_header_count)
|
||||
{
|
||||
if next_header.range().contains(&y) {
|
||||
if next_header.range.contains(&y) {
|
||||
self.place_new_headers(&mut consecutive_header_count, engine)?;
|
||||
y = next_header.end;
|
||||
y = next_header.range.end;
|
||||
|
||||
// Skip header rows during normal layout.
|
||||
continue;
|
||||
|
@ -39,7 +39,8 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
if new_upcoming_headers.first().is_some_and(|next_header| {
|
||||
consecutive_headers.last().is_none_or(|latest_header| {
|
||||
!latest_header.short_lived && next_header.start == latest_header.end
|
||||
!latest_header.short_lived
|
||||
&& next_header.range.start == latest_header.range.end
|
||||
}) && !next_header.short_lived
|
||||
}) {
|
||||
// More headers coming, so wait until we reach them.
|
||||
@ -131,7 +132,7 @@ impl<'a> GridLayouter<'a> {
|
||||
as_short_lived: bool,
|
||||
) -> SourceResult<Abs> {
|
||||
let mut header_height = Abs::zero();
|
||||
for y in header.range() {
|
||||
for y in header.range.clone() {
|
||||
header_height += self
|
||||
.layout_row_with_state(
|
||||
y,
|
||||
@ -261,7 +262,7 @@ impl<'a> GridLayouter<'a> {
|
||||
self.unbreakable_rows_left += repeating_header_rows + pending_header_rows;
|
||||
|
||||
self.current.last_repeated_header_end =
|
||||
self.repeating_headers.last().map(|h| h.end).unwrap_or_default();
|
||||
self.repeating_headers.last().map(|h| h.range.end).unwrap_or_default();
|
||||
|
||||
// Reset the header height for this region.
|
||||
// It will be re-calculated when laying out each header row.
|
||||
@ -453,8 +454,8 @@ impl<'a> GridLayouter<'a> {
|
||||
// assume that the amount of unbreakable rows following the first row
|
||||
// in the header will be precisely the rows in the header.
|
||||
self.simulate_unbreakable_row_group(
|
||||
header.start,
|
||||
Some(header.end - header.start),
|
||||
header.range.start,
|
||||
Some(header.range.end - header.range.start),
|
||||
regions,
|
||||
engine,
|
||||
disambiguator,
|
||||
@ -569,5 +570,5 @@ impl<'a> GridLayouter<'a> {
|
||||
pub fn total_header_row_count<'h>(
|
||||
headers: impl IntoIterator<Item = &'h Header>,
|
||||
) -> usize {
|
||||
headers.into_iter().map(|h| h.end - h.start).sum()
|
||||
headers.into_iter().map(|h| h.range.end - h.range.start).sum()
|
||||
}
|
||||
|
@ -428,10 +428,8 @@ pub struct Line {
|
||||
/// A repeatable grid header. Starts at the first row.
|
||||
#[derive(Debug)]
|
||||
pub struct Header {
|
||||
/// The first row included in this header.
|
||||
pub start: usize,
|
||||
/// The index after the last row included in this header.
|
||||
pub end: usize,
|
||||
/// The range of rows included in this header.
|
||||
pub range: Range<usize>,
|
||||
/// The header's level.
|
||||
///
|
||||
/// Higher level headers repeat together with lower level headers. If a
|
||||
@ -446,14 +444,6 @@ pub struct Header {
|
||||
pub short_lived: bool,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
/// The header's range of included rows.
|
||||
#[inline]
|
||||
pub fn range(&self) -> Range<usize> {
|
||||
self.start..self.end
|
||||
}
|
||||
}
|
||||
|
||||
/// A repeatable grid footer. Stops at the last row.
|
||||
#[derive(Debug)]
|
||||
pub struct Footer {
|
||||
@ -1594,13 +1584,11 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
match row_group.kind {
|
||||
RowGroupKind::Header => {
|
||||
let data = Header {
|
||||
start: group_range.start,
|
||||
|
||||
// Later on, we have to correct this number in case there
|
||||
// Later on, we have to correct this range in case there
|
||||
// is gutter. But only once all cells have been analyzed
|
||||
// and the header has fully expanded in the fixup loop
|
||||
// below.
|
||||
end: group_range.end,
|
||||
range: group_range,
|
||||
|
||||
level: row_group.repeatable_level.get(),
|
||||
|
||||
@ -1613,13 +1601,13 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// lived if they would have a higher or equal level, as
|
||||
// then they would immediately stop repeating during
|
||||
// layout.
|
||||
let mut consecutive_header_start = data.start;
|
||||
let mut consecutive_header_start = data.range.start;
|
||||
for conflicting_header in
|
||||
headers.iter_mut().rev().take_while(move |h| {
|
||||
let conflicts = h.end == consecutive_header_start
|
||||
let conflicts = h.range.end == consecutive_header_start
|
||||
&& h.level >= data.level;
|
||||
|
||||
consecutive_header_start = h.start;
|
||||
consecutive_header_start = h.range.start;
|
||||
conflicts
|
||||
})
|
||||
{
|
||||
@ -1841,9 +1829,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
let mut consecutive_header_start =
|
||||
footer.as_ref().map(|(_, _, f)| f.start).unwrap_or(row_amount);
|
||||
for header_at_the_end in headers.iter_mut().rev().take_while(move |h| {
|
||||
let at_the_end = h.end == consecutive_header_start;
|
||||
let at_the_end = h.range.end == consecutive_header_start;
|
||||
|
||||
consecutive_header_start = h.start;
|
||||
consecutive_header_start = h.range.start;
|
||||
at_the_end
|
||||
}) {
|
||||
header_at_the_end.unwrap_mut().short_lived = true;
|
||||
@ -1858,7 +1846,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
|
||||
// Index of first y is doubled, as each row before it
|
||||
// receives a gutter row below.
|
||||
header.start *= 2;
|
||||
header.range.start *= 2;
|
||||
|
||||
// - 'header.end' is always 'last y + 1'. The header stops
|
||||
// before that row.
|
||||
@ -1871,14 +1859,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// to the index of the gutter row right below the header,
|
||||
// which is what we want (that gutter spacing should be
|
||||
// repeated across pages to maintain uniformity).
|
||||
header.end *= 2;
|
||||
header.range.end *= 2;
|
||||
|
||||
// If the header occupies the entire grid, ensure we don't
|
||||
// include an extra gutter row when it doesn't exist, since
|
||||
// the last row of the header is at the very bottom,
|
||||
// therefore '2 * last y + 1' is not a valid index.
|
||||
let row_amount = (2 * row_amount).saturating_sub(1);
|
||||
header.end = header.end.min(row_amount);
|
||||
header.range.end = header.range.end.min(row_amount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1898,7 +1886,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// only the gutter above the footer is kept, ensuring the same
|
||||
// gutter row isn't laid out two times in a row. When laying
|
||||
// out the footer for real, the mechanism can be disabled.
|
||||
let last_header_end = headers.last().map(|header| header.end);
|
||||
let last_header_end = headers.last().map(|header| header.range.end);
|
||||
|
||||
if has_gutter {
|
||||
// Convert the footer's start index to post-gutter coordinates.
|
||||
@ -2122,7 +2110,7 @@ fn check_for_conflicting_cell_row(
|
||||
// conflict.
|
||||
if headers
|
||||
.iter()
|
||||
.any(|header| cell_y < header.end && cell_y + rowspan > header.start)
|
||||
.any(|header| cell_y < header.range.end && cell_y + rowspan > header.range.start)
|
||||
{
|
||||
bail!(
|
||||
"cell would conflict with header spanning the same position";
|
||||
@ -2341,14 +2329,14 @@ fn find_next_available_position(
|
||||
}
|
||||
} else if let Some(header) = headers
|
||||
.get(*next_header)
|
||||
.filter(|header| resolved_index >= header.start * columns)
|
||||
.filter(|header| resolved_index >= header.range.start * columns)
|
||||
{
|
||||
// Skip header (can't place a cell inside it from outside it).
|
||||
// No changes needed if we already passed this header (which
|
||||
// also triggers this branch) - in that case, we only update the
|
||||
// counter.
|
||||
if resolved_index < header.end * columns {
|
||||
resolved_index = header.end * columns;
|
||||
if resolved_index < header.range.end * columns {
|
||||
resolved_index = header.range.end * columns;
|
||||
|
||||
if skip_rows {
|
||||
// Ensure the cell's chosen column is kept after the
|
||||
|
@ -306,8 +306,8 @@ fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
|
||||
.headers
|
||||
.iter()
|
||||
.take_while(|hd| {
|
||||
let is_consecutive = hd.start == consecutive_header_end;
|
||||
consecutive_header_end = hd.end;
|
||||
let is_consecutive = hd.range.start == consecutive_header_end;
|
||||
consecutive_header_end = hd.range.end;
|
||||
|
||||
is_consecutive
|
||||
})
|
||||
@ -315,7 +315,7 @@ fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
|
||||
|
||||
let (y_offset, header) = if first_mid_table_header > 0 {
|
||||
let removed_header_rows =
|
||||
grid.headers.get(first_mid_table_header - 1).unwrap().end;
|
||||
grid.headers.get(first_mid_table_header - 1).unwrap().range.end;
|
||||
let rows = rows.drain(..removed_header_rows);
|
||||
|
||||
(
|
||||
@ -335,9 +335,9 @@ fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
|
||||
Content::sequence(rows.into_iter().enumerate().map(|(relative_y, row)| {
|
||||
let y = relative_y + y_offset;
|
||||
if let Some(current_header) =
|
||||
grid.headers.get(next_header).filter(|h| h.range().contains(&y))
|
||||
grid.headers.get(next_header).filter(|h| h.range.contains(&y))
|
||||
{
|
||||
if y + 1 == current_header.end {
|
||||
if y + 1 == current_header.range.end {
|
||||
next_header += 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user