move lrows to Current

This commit is contained in:
PgBiel 2025-05-04 02:28:10 -03:00
parent b7c1dba314
commit 4bcf5c11a7
3 changed files with 27 additions and 24 deletions

View File

@ -34,8 +34,6 @@ pub struct GridLayouter<'a> {
pub(super) width: Abs, pub(super) width: Abs,
/// Resolved row sizes, by region. /// Resolved row sizes, by region.
pub(super) rrows: Vec<Vec<RowPiece>>, pub(super) rrows: Vec<Vec<RowPiece>>,
/// Rows in the current region.
pub(super) lrows: Vec<Row>,
/// The amount of unbreakable rows remaining to be laid out in the /// The amount of unbreakable rows remaining to be laid out in the
/// current unbreakable row group. While this is positive, no region breaks /// current unbreakable row group. While this is positive, no region breaks
/// should occur. /// should occur.
@ -77,6 +75,8 @@ pub struct GridLayouter<'a> {
pub(super) struct Current { pub(super) struct Current {
/// The initial size of the current region before we started subtracting. /// The initial size of the current region before we started subtracting.
pub(super) initial: Size, pub(super) initial: Size,
/// Rows in the current region.
pub(super) lrows: Vec<Row>,
/// The amount of repeated header rows at the start of the current region. /// The amount of repeated header rows at the start of the current region.
/// Thus, excludes rows from pending headers (which were placed for the /// Thus, excludes rows from pending headers (which were placed for the
/// first time). /// first time).
@ -235,7 +235,6 @@ impl<'a> GridLayouter<'a> {
rcols: vec![Abs::zero(); grid.cols.len()], rcols: vec![Abs::zero(); grid.cols.len()],
width: Abs::zero(), width: Abs::zero(),
rrows: vec![], rrows: vec![],
lrows: vec![],
unbreakable_rows_left: 0, unbreakable_rows_left: 0,
rowspans: vec![], rowspans: vec![],
finished: vec![], finished: vec![],
@ -247,6 +246,7 @@ impl<'a> GridLayouter<'a> {
row_state: RowState::default(), row_state: RowState::default(),
current: Current { current: Current {
initial: regions.size, initial: regions.size,
lrows: vec![],
repeated_header_rows: 0, repeated_header_rows: 0,
last_repeated_header_end: 0, last_repeated_header_end: 0,
lrows_orphan_snapshot: None, lrows_orphan_snapshot: None,
@ -389,7 +389,7 @@ impl<'a> GridLayouter<'a> {
} }
// Don't layout gutter rows at the top of a region. // Don't layout gutter rows at the top of a region.
if is_content_row || !self.lrows.is_empty() { if is_content_row || !self.current.lrows.is_empty() {
match self.grid.rows[y] { match self.grid.rows[y] {
Sizing::Auto => self.layout_auto_row(engine, disambiguator, y)?, Sizing::Auto => self.layout_auto_row(engine, disambiguator, y)?,
Sizing::Rel(v) => { Sizing::Rel(v) => {
@ -399,7 +399,7 @@ impl<'a> GridLayouter<'a> {
if !self.row_state.in_active_repeatable { if !self.row_state.in_active_repeatable {
self.flush_orphans(); self.flush_orphans();
} }
self.lrows.push(Row::Fr(v, y, disambiguator)) self.current.lrows.push(Row::Fr(v, y, disambiguator))
} }
} }
} }
@ -1138,12 +1138,13 @@ impl<'a> GridLayouter<'a> {
// Expand all but the last region. // Expand all but the last region.
// Skip the first region if the space is eaten up by an fr row. // Skip the first region if the space is eaten up by an fr row.
let len = resolved.len(); let len = resolved.len();
for ((i, region), target) in self for ((i, region), target) in
.regions self.regions
.iter() .iter()
.enumerate() .enumerate()
.zip(&mut resolved[..len - 1]) .zip(&mut resolved[..len - 1])
.skip(self.lrows.iter().any(|row| matches!(row, Row::Fr(..))) as usize) .skip(self.current.lrows.iter().any(|row| matches!(row, Row::Fr(..)))
as usize)
{ {
// Subtract header and footer heights from the region height when // Subtract header and footer heights from the region height when
// it's not the first. Ignore non-repeating headers as they only // it's not the first. Ignore non-repeating headers as they only
@ -1520,7 +1521,7 @@ impl<'a> GridLayouter<'a> {
self.flush_orphans(); self.flush_orphans();
} }
self.regions.size.y -= frame.height(); self.regions.size.y -= frame.height();
self.lrows.push(Row::Frame(frame, y, is_last)); self.current.lrows.push(Row::Frame(frame, y, is_last));
} }
/// Finish rows for one region. /// Finish rows for one region.
@ -1531,7 +1532,7 @@ impl<'a> GridLayouter<'a> {
) -> SourceResult<()> { ) -> SourceResult<()> {
if let Some(orphan_snapshot) = self.current.lrows_orphan_snapshot.take() { if let Some(orphan_snapshot) = self.current.lrows_orphan_snapshot.take() {
if !last { if !last {
self.lrows.truncate(orphan_snapshot); self.current.lrows.truncate(orphan_snapshot);
self.current.repeated_header_rows = self.current.repeated_header_rows =
self.current.repeated_header_rows.min(orphan_snapshot); self.current.repeated_header_rows.min(orphan_snapshot);
@ -1543,14 +1544,15 @@ impl<'a> GridLayouter<'a> {
} }
if self if self
.current
.lrows .lrows
.last() .last()
.is_some_and(|row| self.grid.is_gutter_track(row.index())) .is_some_and(|row| self.grid.is_gutter_track(row.index()))
{ {
// Remove the last row in the region if it is a gutter row. // Remove the last row in the region if it is a gutter row.
self.lrows.pop().unwrap(); self.current.lrows.pop().unwrap();
self.current.repeated_header_rows = self.current.repeated_header_rows =
self.current.repeated_header_rows.min(self.lrows.len()); self.current.repeated_header_rows.min(self.current.lrows.len());
} }
// If no rows other than the footer have been laid out so far // If no rows other than the footer have been laid out so far
@ -1566,7 +1568,7 @@ impl<'a> GridLayouter<'a> {
// similar mechanism / when implementing multiple footers. // similar mechanism / when implementing multiple footers.
let footer_would_be_widow = let footer_would_be_widow =
matches!(self.grid.footer, Some(Repeatable::Repeated(_))) matches!(self.grid.footer, Some(Repeatable::Repeated(_)))
&& self.lrows.is_empty() && self.current.lrows.is_empty()
&& may_progress_with_offset( && may_progress_with_offset(
self.regions, self.regions,
// This header height isn't doing much as we just // This header height isn't doing much as we just
@ -1584,7 +1586,7 @@ impl<'a> GridLayouter<'a> {
// twice. // twice.
// TODO: this check can be replaced by a vector of repeating // TODO: this check can be replaced by a vector of repeating
// footers in the future. // footers in the future.
if self.lrows.iter().all(|row| row.index() < footer.start) { if self.current.lrows.iter().all(|row| row.index() < footer.start) {
laid_out_footer_start = Some(footer.start); laid_out_footer_start = Some(footer.start);
self.layout_footer(footer, engine, self.finished.len())?; self.layout_footer(footer, engine, self.finished.len())?;
} }
@ -1594,7 +1596,7 @@ impl<'a> GridLayouter<'a> {
// Determine the height of existing rows in the region. // Determine the height of existing rows in the region.
let mut used = Abs::zero(); let mut used = Abs::zero();
let mut fr = Fr::zero(); let mut fr = Fr::zero();
for row in &self.lrows { for row in &self.current.lrows {
match row { match row {
Row::Frame(frame, _, _) => used += frame.height(), Row::Frame(frame, _, _) => used += frame.height(),
Row::Fr(v, _, _) => fr += *v, Row::Fr(v, _, _) => fr += *v,
@ -1616,7 +1618,7 @@ impl<'a> GridLayouter<'a> {
let mut repeated_header_row_height = Abs::zero(); let mut repeated_header_row_height = Abs::zero();
// Place finished rows and layout fractional rows. // Place finished rows and layout fractional rows.
for (i, row) in std::mem::take(&mut self.lrows).into_iter().enumerate() { for (i, row) in std::mem::take(&mut self.current.lrows).into_iter().enumerate() {
let (frame, y, is_last) = match row { let (frame, y, is_last) = match row {
Row::Frame(frame, y, is_last) => (frame, y, is_last), Row::Frame(frame, y, is_last) => (frame, y, is_last),
Row::Fr(v, y, disambiguator) => { Row::Fr(v, y, disambiguator) => {

View File

@ -262,7 +262,7 @@ impl<'a> GridLayouter<'a> {
self.current.repeating_header_height = Abs::zero(); self.current.repeating_header_height = Abs::zero();
self.current.repeating_header_heights.clear(); self.current.repeating_header_heights.clear();
debug_assert!(self.lrows.is_empty()); debug_assert!(self.current.lrows.is_empty());
debug_assert!(self.current.lrows_orphan_snapshot.is_none()); debug_assert!(self.current.lrows_orphan_snapshot.is_none());
if may_progress_with_offset(self.regions, self.current.footer_height) { if may_progress_with_offset(self.regions, self.current.footer_height) {
// Enable orphan prevention for headers at the top of the region. // Enable orphan prevention for headers at the top of the region.
@ -271,7 +271,7 @@ impl<'a> GridLayouter<'a> {
// at the 'last' region after the first skip, at which the snapshot // at the 'last' region after the first skip, at which the snapshot
// is handled by 'layout_new_headers'. Either way, we keep this // is handled by 'layout_new_headers'. Either way, we keep this
// here for correctness. // here for correctness.
self.current.lrows_orphan_snapshot = Some(self.lrows.len()); self.current.lrows_orphan_snapshot = Some(self.current.lrows.len());
} }
// Use indices to avoid double borrow. We don't mutate headers in // Use indices to avoid double borrow. We don't mutate headers in
@ -306,7 +306,7 @@ impl<'a> GridLayouter<'a> {
i += 1; i += 1;
} }
self.current.repeated_header_rows = self.lrows.len(); self.current.repeated_header_rows = self.current.lrows.len();
for header in self.pending_headers { for header in self.pending_headers {
let header_height = let header_height =
self.layout_header_rows(header.unwrap(), engine, disambiguator, false)?; self.layout_header_rows(header.unwrap(), engine, disambiguator, false)?;
@ -372,7 +372,7 @@ impl<'a> GridLayouter<'a> {
self.current.header_height + self.current.footer_height, self.current.header_height + self.current.footer_height,
) )
{ {
self.current.lrows_orphan_snapshot = Some(self.lrows.len()); self.current.lrows_orphan_snapshot = Some(self.current.lrows.len());
} }
self.unbreakable_rows_left += self.unbreakable_rows_left +=

View File

@ -479,6 +479,7 @@ impl GridLayouter<'_> {
// Height of the rowspan covered by spanned rows in the current // Height of the rowspan covered by spanned rows in the current
// region. // region.
let laid_out_height: Abs = self let laid_out_height: Abs = self
.current
.lrows .lrows
.iter() .iter()
.filter_map(|row| match row { .filter_map(|row| match row {
@ -536,7 +537,7 @@ impl GridLayouter<'_> {
// 'breakable' can only be true outside of headers // 'breakable' can only be true outside of headers
// and unbreakable rows in general, so there is no risk // and unbreakable rows in general, so there is no risk
// of accessing an incomplete list of rows. // of accessing an incomplete list of rows.
let initial_header_height = self.lrows let initial_header_height = self.current.lrows
[..self.current.repeated_header_rows] [..self.current.repeated_header_rows]
.iter() .iter()
.map(|row| match row { .map(|row| match row {