mirror of
https://github.com/typst/typst
synced 2025-08-19 17:38:32 +08:00
Move grid cell locator creation to GridLayouter (#6746)
This commit is contained in:
parent
a7c8fd6872
commit
343a57b50d
@ -5,7 +5,7 @@ use typst_library::diag::{At, bail, warning};
|
||||
use typst_library::foundations::{
|
||||
Content, NativeElement, NativeRuleMap, ShowFn, Smart, StyleChain, Target,
|
||||
};
|
||||
use typst_library::introspection::{Counter, Locator};
|
||||
use typst_library::introspection::Counter;
|
||||
use typst_library::layout::resolve::{Cell, CellGrid, Entry, table_to_cellgrid};
|
||||
use typst_library::layout::{BlockBody, BlockElem, BoxElem, OuterVAlignment, Sizing};
|
||||
use typst_library::model::{
|
||||
@ -278,9 +278,7 @@ const REF_RULE: ShowFn<RefElem> = |elem, engine, styles| elem.realize(engine, st
|
||||
const CITE_GROUP_RULE: ShowFn<CiteGroup> = |elem, engine, _| elem.realize(engine);
|
||||
|
||||
const TABLE_RULE: ShowFn<TableElem> = |elem, engine, styles| {
|
||||
// The locator is not used by HTML export, so we can just fabricate one.
|
||||
let locator = Locator::root();
|
||||
Ok(show_cellgrid(table_to_cellgrid(elem, engine, locator, styles)?, styles))
|
||||
Ok(show_cellgrid(table_to_cellgrid(elem, engine, styles)?, styles))
|
||||
};
|
||||
|
||||
fn show_cellgrid(grid: CellGrid, styles: StyleChain) -> Content {
|
||||
|
@ -1,11 +1,14 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use typst_library::diag::{SourceResult, bail};
|
||||
use typst_library::engine::Engine;
|
||||
use typst_library::foundations::{Resolve, StyleChain};
|
||||
use typst_library::introspection::Locator;
|
||||
use typst_library::layout::grid::resolve::{
|
||||
Cell, CellGrid, Header, LinePosition, Repeatable,
|
||||
};
|
||||
use typst_library::layout::resolve::Entry;
|
||||
use typst_library::layout::{
|
||||
Abs, Axes, Dir, Fr, Fragment, Frame, FrameItem, Length, Point, Region, Regions, Rel,
|
||||
Size, Sizing,
|
||||
@ -23,9 +26,11 @@ use super::{
|
||||
/// Performs grid layout.
|
||||
pub struct GridLayouter<'a> {
|
||||
/// The grid of cells.
|
||||
pub(super) grid: &'a CellGrid<'a>,
|
||||
pub(super) grid: &'a CellGrid,
|
||||
/// The regions to layout children into.
|
||||
pub(super) regions: Regions<'a>,
|
||||
/// The locators for the each cell in the cell grid.
|
||||
pub(super) cell_locators: FxHashMap<Axes<usize>, Locator<'a>>,
|
||||
/// The inherited styles.
|
||||
pub(super) styles: StyleChain<'a>,
|
||||
/// Resolved column sizes.
|
||||
@ -228,8 +233,9 @@ impl<'a> GridLayouter<'a> {
|
||||
///
|
||||
/// This prepares grid layout by unifying content and gutter tracks.
|
||||
pub fn new(
|
||||
grid: &'a CellGrid<'a>,
|
||||
grid: &'a CellGrid,
|
||||
regions: Regions<'a>,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain<'a>,
|
||||
span: Span,
|
||||
) -> Self {
|
||||
@ -238,9 +244,22 @@ impl<'a> GridLayouter<'a> {
|
||||
let mut regions = regions;
|
||||
regions.expand = Axes::new(true, false);
|
||||
|
||||
// Prepare the locators for each cell in the cell grid.
|
||||
let mut locator = locator.split();
|
||||
let mut cell_locators = FxHashMap::default();
|
||||
for y in 0..grid.rows.len() {
|
||||
for x in 0..grid.cols.len() {
|
||||
let Some(Entry::Cell(cell)) = grid.entry(x, y) else {
|
||||
continue;
|
||||
};
|
||||
cell_locators.insert(Axes::new(x, y), locator.next(&cell.body.span()));
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
grid,
|
||||
regions,
|
||||
cell_locators,
|
||||
styles,
|
||||
rcols: vec![Abs::zero(); grid.cols.len()],
|
||||
width: Abs::zero(),
|
||||
@ -270,6 +289,22 @@ impl<'a> GridLayouter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [`Locator`] for use in [`layout_cell`].
|
||||
pub(super) fn cell_locator(
|
||||
&self,
|
||||
pos: Axes<usize>,
|
||||
disambiguator: usize,
|
||||
) -> Locator<'a> {
|
||||
let mut cell_locator = self.cell_locators[&pos].relayout();
|
||||
|
||||
// The disambiguator is used for repeated cells, e.g. in repeated headers.
|
||||
if disambiguator > 0 {
|
||||
cell_locator = cell_locator.split().next_inner(disambiguator as u128);
|
||||
}
|
||||
|
||||
cell_locator
|
||||
}
|
||||
|
||||
/// Determines the columns sizes and then layouts the grid row-by-row.
|
||||
pub fn layout(mut self, engine: &mut Engine) -> SourceResult<Fragment> {
|
||||
self.measure_columns(engine)?;
|
||||
@ -1037,8 +1072,9 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
let size = Size::new(available, height);
|
||||
let pod = Region::new(size, Axes::splat(false));
|
||||
let frame =
|
||||
layout_cell(cell, engine, 0, self.styles, pod.into())?.into_frame();
|
||||
let locator = self.cell_locator(parent, 0);
|
||||
let frame = layout_cell(cell, engine, locator, self.styles, pod.into())?
|
||||
.into_frame();
|
||||
resolved.set_max(frame.width() - already_covered_width);
|
||||
}
|
||||
|
||||
@ -1276,8 +1312,9 @@ impl<'a> GridLayouter<'a> {
|
||||
pod
|
||||
};
|
||||
|
||||
let locator = self.cell_locator(parent, disambiguator);
|
||||
let frames =
|
||||
layout_cell(cell, engine, disambiguator, self.styles, pod)?.into_frames();
|
||||
layout_cell(cell, engine, locator, self.styles, pod)?.into_frames();
|
||||
|
||||
// Skip the first region if one cell in it is empty. Then,
|
||||
// remeasure.
|
||||
@ -1434,9 +1471,9 @@ impl<'a> GridLayouter<'a> {
|
||||
// rows.
|
||||
pod.full = self.regions.full;
|
||||
}
|
||||
let frame =
|
||||
layout_cell(cell, engine, disambiguator, self.styles, pod)?
|
||||
.into_frame();
|
||||
let locator = self.cell_locator(Axes::new(x, y), disambiguator);
|
||||
let frame = layout_cell(cell, engine, locator, self.styles, pod)?
|
||||
.into_frame();
|
||||
let mut pos = offset;
|
||||
if self.is_rtl {
|
||||
// In RTL cells expand to the left, thus the position
|
||||
@ -1483,8 +1520,8 @@ impl<'a> GridLayouter<'a> {
|
||||
pod.size.x = width;
|
||||
|
||||
// Push the layouted frames into the individual output frames.
|
||||
let fragment =
|
||||
layout_cell(cell, engine, disambiguator, self.styles, pod)?;
|
||||
let locator = self.cell_locator(Axes::new(x, y), disambiguator);
|
||||
let fragment = layout_cell(cell, engine, locator, self.styles, pod)?;
|
||||
for (output, frame) in outputs.iter_mut().zip(fragment) {
|
||||
let mut pos = offset;
|
||||
if self.is_rtl {
|
||||
|
@ -560,17 +560,15 @@ pub fn hline_stroke_at_column(
|
||||
mod test {
|
||||
use std::num::NonZeroUsize;
|
||||
use typst_library::foundations::Content;
|
||||
use typst_library::introspection::Locator;
|
||||
use typst_library::layout::grid::resolve::{Cell, Entry, LinePosition};
|
||||
use typst_library::layout::{Axes, Sides, Sizing};
|
||||
use typst_utils::NonZeroExt;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn sample_cell() -> Cell<'static> {
|
||||
fn sample_cell() -> Cell {
|
||||
Cell {
|
||||
body: Content::default(),
|
||||
locator: Locator::root(),
|
||||
fill: None,
|
||||
colspan: NonZeroUsize::ONE,
|
||||
rowspan: NonZeroUsize::ONE,
|
||||
@ -580,10 +578,9 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
fn cell_with_colspan_rowspan(colspan: usize, rowspan: usize) -> Cell<'static> {
|
||||
fn cell_with_colspan_rowspan(colspan: usize, rowspan: usize) -> Cell {
|
||||
Cell {
|
||||
body: Content::default(),
|
||||
locator: Locator::root(),
|
||||
fill: None,
|
||||
colspan: NonZeroUsize::try_from(colspan).unwrap(),
|
||||
rowspan: NonZeroUsize::try_from(rowspan).unwrap(),
|
||||
@ -593,7 +590,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_grid_for_vlines(gutters: bool) -> CellGrid<'static> {
|
||||
fn sample_grid_for_vlines(gutters: bool) -> CellGrid {
|
||||
const COLS: usize = 4;
|
||||
const ROWS: usize = 6;
|
||||
let entries = vec![
|
||||
@ -1116,7 +1113,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_grid_for_hlines(gutters: bool) -> CellGrid<'static> {
|
||||
fn sample_grid_for_hlines(gutters: bool) -> CellGrid {
|
||||
const COLS: usize = 4;
|
||||
const ROWS: usize = 9;
|
||||
let entries = vec![
|
||||
|
@ -28,14 +28,10 @@ use self::rowspans::{Rowspan, UnbreakableRowGroup};
|
||||
pub fn layout_cell(
|
||||
cell: &Cell,
|
||||
engine: &mut Engine,
|
||||
disambiguator: usize,
|
||||
locator: Locator,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
let mut locator = cell.locator.relayout();
|
||||
if disambiguator > 0 {
|
||||
locator = locator.split().next_inner(disambiguator as u128);
|
||||
}
|
||||
crate::layout_fragment(engine, &cell.body, locator, styles, regions)
|
||||
}
|
||||
|
||||
@ -48,8 +44,8 @@ pub fn layout_grid(
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
let grid = grid_to_cellgrid(elem, engine, locator, styles)?;
|
||||
GridLayouter::new(&grid, regions, styles, elem.span()).layout(engine)
|
||||
let grid = grid_to_cellgrid(elem, engine, styles)?;
|
||||
GridLayouter::new(&grid, regions, locator, styles, elem.span()).layout(engine)
|
||||
}
|
||||
|
||||
/// Layout the table.
|
||||
@ -61,6 +57,6 @@ pub fn layout_table(
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
let grid = table_to_cellgrid(elem, engine, locator, styles)?;
|
||||
GridLayouter::new(&grid, regions, styles, elem.span()).layout(engine)
|
||||
let grid = table_to_cellgrid(elem, engine, styles)?;
|
||||
GridLayouter::new(&grid, regions, locator, styles, elem.span()).layout(engine)
|
||||
}
|
||||
|
@ -145,7 +145,8 @@ impl GridLayouter<'_> {
|
||||
}
|
||||
|
||||
// Push the layouted frames directly into the finished frames.
|
||||
let fragment = layout_cell(cell, engine, disambiguator, self.styles, pod)?;
|
||||
let locator = self.cell_locator(Axes::new(x, y), disambiguator);
|
||||
let fragment = layout_cell(cell, engine, locator, self.styles, pod)?;
|
||||
let (current_region, current_header_row_height) = current_region_data.unzip();
|
||||
|
||||
// Clever trick to process finished header rows:
|
||||
|
@ -36,8 +36,6 @@ pub fn layout_list(
|
||||
.aligned(HAlignment::Start + VAlignment::Top);
|
||||
|
||||
let mut cells = vec![];
|
||||
let mut locator = locator.split();
|
||||
|
||||
for item in &elem.children {
|
||||
// Text in wide lists shall always turn into paragraphs.
|
||||
let mut body = item.body.clone();
|
||||
@ -45,13 +43,10 @@ pub fn layout_list(
|
||||
body += ParbreakElem::shared();
|
||||
}
|
||||
|
||||
cells.push(Cell::new(Content::empty(), locator.next(&())));
|
||||
cells.push(Cell::new(marker.clone(), locator.next(&marker.span())));
|
||||
cells.push(Cell::new(Content::empty(), locator.next(&())));
|
||||
cells.push(Cell::new(
|
||||
body.set(ListElem::depth, Depth(1)),
|
||||
locator.next(&item.body.span()),
|
||||
));
|
||||
cells.push(Cell::new(Content::empty()));
|
||||
cells.push(Cell::new(marker.clone()));
|
||||
cells.push(Cell::new(Content::empty()));
|
||||
cells.push(Cell::new(body.set(ListElem::depth, Depth(1))));
|
||||
}
|
||||
|
||||
let grid = CellGrid::new(
|
||||
@ -64,7 +59,7 @@ pub fn layout_list(
|
||||
Axes::with_y(&[gutter.into()]),
|
||||
cells,
|
||||
);
|
||||
let layouter = GridLayouter::new(&grid, regions, styles, elem.span());
|
||||
let layouter = GridLayouter::new(&grid, regions, locator, styles, elem.span());
|
||||
|
||||
layouter.layout(engine)
|
||||
}
|
||||
@ -88,7 +83,6 @@ pub fn layout_enum(
|
||||
});
|
||||
|
||||
let mut cells = vec![];
|
||||
let mut locator = locator.split();
|
||||
let mut number = elem
|
||||
.start
|
||||
.get(styles)
|
||||
@ -131,13 +125,10 @@ pub fn layout_enum(
|
||||
body += ParbreakElem::shared();
|
||||
}
|
||||
|
||||
cells.push(Cell::new(Content::empty(), locator.next(&())));
|
||||
cells.push(Cell::new(resolved, locator.next(&())));
|
||||
cells.push(Cell::new(Content::empty(), locator.next(&())));
|
||||
cells.push(Cell::new(
|
||||
body.set(EnumElem::parents, smallvec![number]),
|
||||
locator.next(&item.body.span()),
|
||||
));
|
||||
cells.push(Cell::new(Content::empty()));
|
||||
cells.push(Cell::new(resolved));
|
||||
cells.push(Cell::new(Content::empty()));
|
||||
cells.push(Cell::new(body.set(EnumElem::parents, smallvec![number])));
|
||||
number =
|
||||
if reversed { number.saturating_sub(1) } else { number.saturating_add(1) };
|
||||
}
|
||||
@ -152,7 +143,7 @@ pub fn layout_enum(
|
||||
Axes::with_y(&[gutter.into()]),
|
||||
cells,
|
||||
);
|
||||
let layouter = GridLayouter::new(&grid, regions, styles, elem.span());
|
||||
let layouter = GridLayouter::new(&grid, regions, locator, styles, elem.span());
|
||||
|
||||
layouter.layout(engine)
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ use typst_library::diag::{
|
||||
};
|
||||
use typst_library::engine::Engine;
|
||||
use typst_library::foundations::{Content, Fold, Packed, Smart, StyleChain};
|
||||
use typst_library::introspection::Locator;
|
||||
use typst_library::layout::{
|
||||
Abs, Alignment, Axes, Celled, GridCell, GridChild, GridElem, GridItem, Length,
|
||||
OuterHAlignment, OuterVAlignment, Rel, ResolvedCelled, Sides, Sizing,
|
||||
@ -21,16 +20,13 @@ use typst_library::visualize::{Paint, Stroke};
|
||||
use typst_syntax::Span;
|
||||
use typst_utils::{NonZeroExt, SmallBitSet};
|
||||
|
||||
use crate::introspection::SplitLocator;
|
||||
|
||||
/// Convert a grid to a cell grid.
|
||||
#[typst_macros::time(span = elem.span())]
|
||||
pub fn grid_to_cellgrid<'a>(
|
||||
pub fn grid_to_cellgrid(
|
||||
elem: &Packed<GridElem>,
|
||||
engine: &mut Engine,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<CellGrid<'a>> {
|
||||
) -> SourceResult<CellGrid> {
|
||||
let inset = elem.inset.get_cloned(styles);
|
||||
let align = elem.align.get_ref(styles);
|
||||
let columns = elem.columns.get_ref(styles);
|
||||
@ -64,7 +60,6 @@ pub fn grid_to_cellgrid<'a>(
|
||||
resolve_cellgrid(
|
||||
tracks,
|
||||
gutter,
|
||||
locator,
|
||||
children,
|
||||
fill,
|
||||
align,
|
||||
@ -79,12 +74,11 @@ pub fn grid_to_cellgrid<'a>(
|
||||
|
||||
/// Convert a table to a cell grid.
|
||||
#[typst_macros::time(span = elem.span())]
|
||||
pub fn table_to_cellgrid<'a>(
|
||||
pub fn table_to_cellgrid(
|
||||
elem: &Packed<TableElem>,
|
||||
engine: &mut Engine,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<CellGrid<'a>> {
|
||||
) -> SourceResult<CellGrid> {
|
||||
let inset = elem.inset.get_cloned(styles);
|
||||
let align = elem.align.get_ref(styles);
|
||||
let columns = elem.columns.get_ref(styles);
|
||||
@ -118,7 +112,6 @@ pub fn table_to_cellgrid<'a>(
|
||||
resolve_cellgrid(
|
||||
tracks,
|
||||
gutter,
|
||||
locator,
|
||||
children,
|
||||
fill,
|
||||
align,
|
||||
@ -206,7 +199,7 @@ fn table_item_to_resolvable(
|
||||
}
|
||||
|
||||
impl ResolvableCell for Packed<TableCell> {
|
||||
fn resolve_cell<'a>(
|
||||
fn resolve_cell(
|
||||
mut self,
|
||||
x: usize,
|
||||
y: usize,
|
||||
@ -215,9 +208,8 @@ impl ResolvableCell for Packed<TableCell> {
|
||||
inset: Sides<Option<Rel<Length>>>,
|
||||
stroke: Sides<Option<Option<Arc<Stroke<Abs>>>>>,
|
||||
breakable: bool,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain,
|
||||
) -> Cell<'a> {
|
||||
) -> Cell {
|
||||
let cell = &mut *self;
|
||||
let colspan = cell.colspan.get(styles);
|
||||
let rowspan = cell.rowspan.get(styles);
|
||||
@ -269,7 +261,6 @@ impl ResolvableCell for Packed<TableCell> {
|
||||
cell.breakable.set(Smart::Custom(breakable));
|
||||
Cell {
|
||||
body: self.pack(),
|
||||
locator,
|
||||
fill,
|
||||
colspan,
|
||||
rowspan,
|
||||
@ -301,7 +292,7 @@ impl ResolvableCell for Packed<TableCell> {
|
||||
}
|
||||
|
||||
impl ResolvableCell for Packed<GridCell> {
|
||||
fn resolve_cell<'a>(
|
||||
fn resolve_cell(
|
||||
mut self,
|
||||
x: usize,
|
||||
y: usize,
|
||||
@ -310,9 +301,8 @@ impl ResolvableCell for Packed<GridCell> {
|
||||
inset: Sides<Option<Rel<Length>>>,
|
||||
stroke: Sides<Option<Option<Arc<Stroke<Abs>>>>>,
|
||||
breakable: bool,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain,
|
||||
) -> Cell<'a> {
|
||||
) -> Cell {
|
||||
let cell = &mut *self;
|
||||
let colspan = cell.colspan.get(styles);
|
||||
let rowspan = cell.rowspan.get(styles);
|
||||
@ -364,7 +354,6 @@ impl ResolvableCell for Packed<GridCell> {
|
||||
cell.breakable.set(Smart::Custom(breakable));
|
||||
Cell {
|
||||
body: self.pack(),
|
||||
locator,
|
||||
fill,
|
||||
colspan,
|
||||
rowspan,
|
||||
@ -507,7 +496,7 @@ pub trait ResolvableCell {
|
||||
/// the `breakable` field.
|
||||
/// Returns a final Cell.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn resolve_cell<'a>(
|
||||
fn resolve_cell(
|
||||
self,
|
||||
x: usize,
|
||||
y: usize,
|
||||
@ -516,9 +505,8 @@ pub trait ResolvableCell {
|
||||
inset: Sides<Option<Rel<Length>>>,
|
||||
stroke: Sides<Option<Option<Arc<Stroke<Abs>>>>>,
|
||||
breakable: bool,
|
||||
locator: Locator<'a>,
|
||||
styles: StyleChain,
|
||||
) -> Cell<'a>;
|
||||
) -> Cell;
|
||||
|
||||
/// Returns this cell's column override.
|
||||
fn x(&self, styles: StyleChain) -> Smart<usize>;
|
||||
@ -570,11 +558,9 @@ pub enum ResolvableGridItem<T: ResolvableCell> {
|
||||
}
|
||||
|
||||
/// Represents a cell in CellGrid, to be laid out by GridLayouter.
|
||||
pub struct Cell<'a> {
|
||||
pub struct Cell {
|
||||
/// The cell's body.
|
||||
pub body: Content,
|
||||
/// The cell's locator.
|
||||
pub locator: Locator<'a>,
|
||||
/// The cell's fill.
|
||||
pub fill: Option<Paint>,
|
||||
/// The amount of columns spanned by the cell.
|
||||
@ -600,12 +586,11 @@ pub struct Cell<'a> {
|
||||
pub breakable: bool,
|
||||
}
|
||||
|
||||
impl<'a> Cell<'a> {
|
||||
/// Create a simple cell given its body and its locator.
|
||||
pub fn new(body: Content, locator: Locator<'a>) -> Self {
|
||||
impl Cell {
|
||||
/// Create a simple cell given its body.
|
||||
pub fn new(body: Content) -> Self {
|
||||
Self {
|
||||
body,
|
||||
locator,
|
||||
fill: None,
|
||||
colspan: NonZeroUsize::ONE,
|
||||
rowspan: NonZeroUsize::ONE,
|
||||
@ -629,9 +614,9 @@ pub enum LinePosition {
|
||||
}
|
||||
|
||||
/// A grid entry.
|
||||
pub enum Entry<'a> {
|
||||
pub enum Entry {
|
||||
/// An entry which holds a cell.
|
||||
Cell(Cell<'a>),
|
||||
Cell(Cell),
|
||||
/// An entry which is merged with another cell.
|
||||
Merged {
|
||||
/// The index of the cell this entry is merged with.
|
||||
@ -639,9 +624,9 @@ pub enum Entry<'a> {
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> Entry<'a> {
|
||||
impl Entry {
|
||||
/// Obtains the cell inside this entry, if this is not a merged cell.
|
||||
pub fn as_cell(&self) -> Option<&Cell<'a>> {
|
||||
pub fn as_cell(&self) -> Option<&Cell> {
|
||||
match self {
|
||||
Self::Cell(cell) => Some(cell),
|
||||
Self::Merged { .. } => None,
|
||||
@ -657,9 +642,9 @@ pub enum ResolvableGridChild<T: ResolvableCell, I> {
|
||||
}
|
||||
|
||||
/// A grid of cells, including the columns, rows, and cell data.
|
||||
pub struct CellGrid<'a> {
|
||||
pub struct CellGrid {
|
||||
/// The grid cells.
|
||||
pub entries: Vec<Entry<'a>>,
|
||||
pub entries: Vec<Entry>,
|
||||
/// The column tracks including gutter tracks.
|
||||
pub cols: Vec<Sizing>,
|
||||
/// The row tracks including gutter tracks.
|
||||
@ -680,12 +665,12 @@ pub struct CellGrid<'a> {
|
||||
pub has_gutter: bool,
|
||||
}
|
||||
|
||||
impl<'a> CellGrid<'a> {
|
||||
impl CellGrid {
|
||||
/// Generates the cell grid, given the tracks and cells.
|
||||
pub fn new(
|
||||
tracks: Axes<&[Sizing]>,
|
||||
gutter: Axes<&[Sizing]>,
|
||||
cells: impl IntoIterator<Item = Cell<'a>>,
|
||||
cells: impl IntoIterator<Item = Cell>,
|
||||
) -> Self {
|
||||
let entries = cells.into_iter().map(Entry::Cell).collect();
|
||||
Self::new_internal(tracks, gutter, vec![], vec![], vec![], None, entries)
|
||||
@ -699,7 +684,7 @@ impl<'a> CellGrid<'a> {
|
||||
hlines: Vec<Vec<Line>>,
|
||||
headers: Vec<Repeatable<Header>>,
|
||||
footer: Option<Repeatable<Footer>>,
|
||||
entries: Vec<Entry<'a>>,
|
||||
entries: Vec<Entry>,
|
||||
) -> Self {
|
||||
let mut cols = vec![];
|
||||
let mut rows = vec![];
|
||||
@ -761,7 +746,7 @@ impl<'a> CellGrid<'a> {
|
||||
///
|
||||
/// Returns `None` if it's a gutter cell.
|
||||
#[track_caller]
|
||||
pub fn entry(&self, x: usize, y: usize) -> Option<&Entry<'a>> {
|
||||
pub fn entry(&self, x: usize, y: usize) -> Option<&Entry> {
|
||||
assert!(x < self.cols.len());
|
||||
assert!(y < self.rows.len());
|
||||
|
||||
@ -783,7 +768,7 @@ impl<'a> CellGrid<'a> {
|
||||
///
|
||||
/// Returns `None` if it's a gutter cell or merged position.
|
||||
#[track_caller]
|
||||
pub fn cell(&self, x: usize, y: usize) -> Option<&Cell<'a>> {
|
||||
pub fn cell(&self, x: usize, y: usize) -> Option<&Cell> {
|
||||
self.entry(x, y).and_then(Entry::as_cell)
|
||||
}
|
||||
|
||||
@ -892,10 +877,9 @@ impl<'a> CellGrid<'a> {
|
||||
/// must implement Default in order to fill positions in the grid which
|
||||
/// weren't explicitly specified by the user with empty cells.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn resolve_cellgrid<'a, 'x, T, C, I>(
|
||||
pub fn resolve_cellgrid<'a, T, C, I>(
|
||||
tracks: Axes<&'a [Sizing]>,
|
||||
gutter: Axes<&'a [Sizing]>,
|
||||
locator: Locator<'x>,
|
||||
children: C,
|
||||
fill: &'a Celled<Option<Paint>>,
|
||||
align: &'a Celled<Smart<Alignment>>,
|
||||
@ -904,7 +888,7 @@ pub fn resolve_cellgrid<'a, 'x, T, C, I>(
|
||||
engine: &'a mut Engine,
|
||||
styles: StyleChain<'a>,
|
||||
span: Span,
|
||||
) -> SourceResult<CellGrid<'x>>
|
||||
) -> SourceResult<CellGrid>
|
||||
where
|
||||
T: ResolvableCell + Default,
|
||||
I: Iterator<Item = ResolvableGridItem<T>>,
|
||||
@ -914,7 +898,6 @@ where
|
||||
CellGridResolver {
|
||||
tracks,
|
||||
gutter,
|
||||
locator: locator.split(),
|
||||
fill,
|
||||
align,
|
||||
inset,
|
||||
@ -926,10 +909,9 @@ where
|
||||
.resolve(children)
|
||||
}
|
||||
|
||||
struct CellGridResolver<'a, 'b, 'x> {
|
||||
struct CellGridResolver<'a, 'b> {
|
||||
tracks: Axes<&'a [Sizing]>,
|
||||
gutter: Axes<&'a [Sizing]>,
|
||||
locator: SplitLocator<'x>,
|
||||
fill: &'a Celled<Option<Paint>>,
|
||||
align: &'a Celled<Smart<Alignment>>,
|
||||
inset: &'a Celled<Sides<Option<Rel<Length>>>>,
|
||||
@ -996,8 +978,8 @@ struct RowGroupData {
|
||||
top_hlines_end: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
fn resolve<T, C, I>(mut self, children: C) -> SourceResult<CellGrid<'x>>
|
||||
impl CellGridResolver<'_, '_> {
|
||||
fn resolve<T, C, I>(mut self, children: C) -> SourceResult<CellGrid>
|
||||
where
|
||||
T: ResolvableCell + Default,
|
||||
I: Iterator<Item = ResolvableGridItem<T>>,
|
||||
@ -1138,7 +1120,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
footer: &mut Option<(usize, Span, Footer)>,
|
||||
repeat_footer: &mut bool,
|
||||
auto_index: &mut usize,
|
||||
resolved_cells: &mut Vec<Option<Entry<'x>>>,
|
||||
resolved_cells: &mut Vec<Option<Entry>>,
|
||||
at_least_one_cell: &mut bool,
|
||||
child: ResolvableGridChild<T, I>,
|
||||
) -> SourceResult<()>
|
||||
@ -1441,7 +1423,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
|
||||
// Let's resolve the cell so it can determine its own fields
|
||||
// based on its final position.
|
||||
let cell = self.resolve_cell(cell, x, y, rowspan, cell_span)?;
|
||||
let cell = self.resolve_cell(cell, x, y, rowspan)?;
|
||||
|
||||
if largest_index >= resolved_cells.len() {
|
||||
// Ensure the length of the vector of resolved cells is
|
||||
@ -1538,14 +1520,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// and footers without having to loop through them each time.
|
||||
// Cells themselves, unfortunately, still have to.
|
||||
assert!(resolved_cells[*local_auto_index].is_none());
|
||||
resolved_cells[*local_auto_index] =
|
||||
Some(Entry::Cell(self.resolve_cell(
|
||||
T::default(),
|
||||
0,
|
||||
first_available_row,
|
||||
1,
|
||||
Span::detached(),
|
||||
)?));
|
||||
resolved_cells[*local_auto_index] = Some(Entry::Cell(
|
||||
self.resolve_cell(T::default(), 0, first_available_row, 1)?,
|
||||
));
|
||||
|
||||
group_start..group_end
|
||||
}
|
||||
@ -1635,9 +1612,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
/// can be affected by show rules and grid-wide styling.
|
||||
fn fixup_cells<T>(
|
||||
&mut self,
|
||||
resolved_cells: Vec<Option<Entry<'x>>>,
|
||||
resolved_cells: Vec<Option<Entry>>,
|
||||
columns: usize,
|
||||
) -> SourceResult<Vec<Entry<'x>>>
|
||||
) -> SourceResult<Vec<Entry>>
|
||||
where
|
||||
T: ResolvableCell + Default,
|
||||
{
|
||||
@ -1657,13 +1634,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
let x = i % columns;
|
||||
let y = i / columns;
|
||||
|
||||
Ok(Entry::Cell(self.resolve_cell(
|
||||
T::default(),
|
||||
x,
|
||||
y,
|
||||
1,
|
||||
Span::detached(),
|
||||
)?))
|
||||
Ok(Entry::Cell(self.resolve_cell(T::default(), x, y, 1)?))
|
||||
}
|
||||
})
|
||||
.collect::<SourceResult<Vec<Entry>>>()
|
||||
@ -1915,8 +1886,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
x: usize,
|
||||
y: usize,
|
||||
rowspan: usize,
|
||||
cell_span: Span,
|
||||
) -> SourceResult<Cell<'x>>
|
||||
) -> SourceResult<Cell>
|
||||
where
|
||||
T: ResolvableCell + Default,
|
||||
{
|
||||
@ -1950,7 +1920,6 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
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,
|
||||
))
|
||||
}
|
||||
@ -1962,7 +1931,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
/// returned. Otherwise, the new `start..end` range of rows in the row group is
|
||||
/// returned.
|
||||
fn expand_row_group(
|
||||
resolved_cells: &[Option<Entry<'_>>],
|
||||
resolved_cells: &[Option<Entry>],
|
||||
group_range: Option<&Range<usize>>,
|
||||
group_kind: RowGroupKind,
|
||||
first_available_row: usize,
|
||||
@ -2280,7 +2249,7 @@ fn resolve_cell_position(
|
||||
fn find_next_available_position(
|
||||
header_rows: &SmallBitSet,
|
||||
footer: Option<&(usize, Span, Footer)>,
|
||||
resolved_cells: &[Option<Entry<'_>>],
|
||||
resolved_cells: &[Option<Entry>],
|
||||
columns: usize,
|
||||
initial_index: usize,
|
||||
skip_rows: bool,
|
||||
|
Loading…
x
Reference in New Issue
Block a user