factor out 'resolve_cell'

This commit is contained in:
PgBiel 2025-03-05 16:13:05 -03:00
parent ee8561a963
commit 9da25616a9

View File

@ -941,28 +941,6 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
let mut footer: Option<(usize, Span, Footer)> = None; let mut footer: Option<(usize, Span, Footer)> = None;
let mut repeat_footer = false; let mut repeat_footer = false;
// Resolves the breakability of a cell. Cells that span at least one
// auto-sized row or gutter are considered breakable.
let resolve_breakable = |y, rowspan| {
let auto = Sizing::Auto;
let zero = Sizing::Rel(Rel::zero());
self.tracks
.y
.iter()
.chain(std::iter::repeat(self.tracks.y.last().unwrap_or(&auto)))
.skip(y)
.take(rowspan)
.any(|row| row == &Sizing::Auto)
|| self
.gutter
.y
.iter()
.chain(std::iter::repeat(self.gutter.y.last().unwrap_or(&zero)))
.skip(y)
.take(rowspan - 1)
.any(|row_gutter| row_gutter == &Sizing::Auto)
};
// We can't just use the cell's index in the 'cells' vector to // We can't just use the cell's index in the 'cells' vector to
// determine its automatic position, since cells could have arbitrary // determine its automatic position, since cells could have arbitrary
// positions, so the position of a cell in 'cells' can differ from its // positions, so the position of a cell in 'cells' can differ from its
@ -1005,7 +983,6 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
&mut repeat_header, &mut repeat_header,
&mut footer, &mut footer,
&mut repeat_footer, &mut repeat_footer,
resolve_breakable,
&mut auto_index, &mut auto_index,
&mut resolved_cells, &mut resolved_cells,
child, child,
@ -1042,18 +1019,13 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// Ensure all absent entries are affected by show rules and // Ensure all absent entries are affected by show rules and
// grid styling by turning them into resolved empty cells. // grid styling by turning them into resolved empty cells.
let new_cell = T::default().resolve_cell( Ok(Entry::Cell(self.resolve_cell(
T::default(),
x, x,
y, y,
&self.fill.resolve(self.engine, self.styles, x, y)?, 1,
self.align.resolve(self.engine, self.styles, x, y)?, Span::detached(),
self.inset.resolve(self.engine, self.styles, x, y)?, )?))
self.stroke.resolve(self.engine, self.styles, x, y)?,
resolve_breakable(y, 1),
self.locator.next(&()),
self.styles,
);
Ok(Entry::Cell(new_cell))
} }
}) })
.collect::<SourceResult<Vec<Entry>>>()?; .collect::<SourceResult<Vec<Entry>>>()?;
@ -1229,11 +1201,10 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
repeat_header: &mut bool, repeat_header: &mut bool,
footer: &mut Option<(usize, Span, Footer)>, footer: &mut Option<(usize, Span, Footer)>,
repeat_footer: &mut bool, repeat_footer: &mut bool,
resolve_breakable: impl Fn(usize, usize) -> bool,
auto_index: &mut usize, auto_index: &mut usize,
resolved_cells: &mut Vec<Option<Entry<'x>>>, resolved_cells: &mut Vec<Option<Entry<'x>>>,
child: ResolvableGridChild<T, I>, child: ResolvableGridChild<T, I>,
) -> Result<(), ecow::EcoVec<crate::diag::SourceDiagnostic>> ) -> SourceResult<()>
where where
T: ResolvableCell + Default, T: ResolvableCell + Default,
I: Iterator<Item = ResolvableGridItem<T>>, I: Iterator<Item = ResolvableGridItem<T>>,
@ -1494,17 +1465,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// Let's resolve the cell so it can determine its own fields // Let's resolve the cell so it can determine its own fields
// based on its final position. // based on its final position.
let cell = cell.resolve_cell( let cell = self.resolve_cell(cell, x, y, rowspan, cell_span)?;
x,
y,
&self.fill.resolve(self.engine, self.styles, x, y)?,
self.align.resolve(self.engine, self.styles, x, y)?,
self.inset.resolve(self.engine, self.styles, x, y)?,
self.stroke.resolve(self.engine, self.styles, x, y)?,
resolve_breakable(y, rowspan),
self.locator.next(&cell_span),
self.styles,
);
if largest_index >= resolved_cells.len() { if largest_index >= resolved_cells.len() {
// Ensure the length of the vector of resolved cells is // Ensure the length of the vector of resolved cells is
@ -1598,39 +1559,14 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// and footers without having to loop through them each time. // and footers without having to loop through them each time.
// Cells themselves, unfortunately, still have to. // Cells themselves, unfortunately, still have to.
assert!(resolved_cells[local_auto_index].is_none()); assert!(resolved_cells[local_auto_index].is_none());
let (first_x, first_y) = (0, first_available_row);
resolved_cells[local_auto_index] = resolved_cells[local_auto_index] =
Some(Entry::Cell(T::default().resolve_cell( Some(Entry::Cell(self.resolve_cell(
first_x, T::default(),
first_y, 0,
&self.fill.resolve( first_available_row,
self.engine, 1,
self.styles, Span::detached(),
first_x, )?));
first_y,
)?,
self.align.resolve(
self.engine,
self.styles,
first_x,
first_y,
)?,
self.inset.resolve(
self.engine,
self.styles,
first_x,
first_y,
)?,
self.stroke.resolve(
self.engine,
self.styles,
first_x,
first_y,
)?,
resolve_breakable(first_y, 1),
self.locator.next(&()),
self.styles,
)));
group_start..group_end group_start..group_end
} }
@ -1680,6 +1616,53 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
Ok(()) Ok(())
} }
/// Resolves the cell's fields based on grid-wide properties.
fn resolve_cell<T>(
&mut self,
cell: T,
x: usize,
y: usize,
rowspan: usize,
cell_span: Span,
) -> SourceResult<Cell<'x>>
where
T: ResolvableCell + Default,
{
// Resolve the breakability of a cell. Cells that span at least one
// auto-sized row or gutter are considered breakable.
let breakable = {
let auto = Sizing::Auto;
let zero = Sizing::Rel(Rel::zero());
self.tracks
.y
.iter()
.chain(std::iter::repeat(self.tracks.y.last().unwrap_or(&auto)))
.skip(y)
.take(rowspan)
.any(|row| row == &Sizing::Auto)
|| self
.gutter
.y
.iter()
.chain(std::iter::repeat(self.gutter.y.last().unwrap_or(&zero)))
.skip(y)
.take(rowspan - 1)
.any(|row_gutter| row_gutter == &Sizing::Auto)
};
Ok(cell.resolve_cell(
x,
y,
&self.fill.resolve(self.engine, self.styles, x, y)?,
self.align.resolve(self.engine, self.styles, x, y)?,
self.inset.resolve(self.engine, self.styles, x, y)?,
self.stroke.resolve(self.engine, self.styles, x, y)?,
breakable,
self.locator.next(&cell_span),
self.styles,
))
}
} }
/// Given the existing range of a row group (header or footer), tries to expand /// Given the existing range of a row group (header or footer), tries to expand