Fast path for gutter-less grid

This commit is contained in:
Laurenz 2023-02-12 13:04:46 +01:00
parent 01a62a690b
commit fea238921f

View File

@ -220,7 +220,9 @@ struct GridLayouter<'a, 'v> {
/// The grid cells. /// The grid cells.
cells: &'a [Content], cells: &'a [Content],
/// Whether this is an RTL grid. /// Whether this is an RTL grid.
rtl: bool, is_rtl: bool,
/// Whether this grid has gutters.
has_gutter: bool,
/// The column tracks including gutter tracks. /// The column tracks including gutter tracks.
cols: Vec<TrackSizing>, cols: Vec<TrackSizing>,
/// The row tracks including gutter tracks. /// The row tracks including gutter tracks.
@ -280,6 +282,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
given.max(needed) given.max(needed)
}; };
let has_gutter = gutter.any(|tracks| !tracks.is_empty());
let auto = TrackSizing::Auto; let auto = TrackSizing::Auto;
let zero = TrackSizing::Relative(Rel::zero()); let zero = TrackSizing::Relative(Rel::zero());
let get_or = |tracks: &[_], idx, default| { let get_or = |tracks: &[_], idx, default| {
@ -289,22 +292,28 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
// Collect content and gutter columns. // Collect content and gutter columns.
for x in 0..c { for x in 0..c {
cols.push(get_or(tracks.x, x, auto)); cols.push(get_or(tracks.x, x, auto));
if has_gutter {
cols.push(get_or(gutter.x, x, zero)); cols.push(get_or(gutter.x, x, zero));
} }
}
// Collect content and gutter rows. // Collect content and gutter rows.
for y in 0..r { for y in 0..r {
rows.push(get_or(tracks.y, y, auto)); rows.push(get_or(tracks.y, y, auto));
if has_gutter {
rows.push(get_or(gutter.y, y, zero)); rows.push(get_or(gutter.y, y, zero));
} }
}
// Remove superfluous gutter tracks. // Remove superfluous gutter tracks.
if has_gutter {
cols.pop(); cols.pop();
rows.pop(); rows.pop();
}
// Reverse for RTL. // Reverse for RTL.
let rtl = styles.get(TextNode::DIR) == Dir::RTL; let is_rtl = styles.get(TextNode::DIR) == Dir::RTL;
if rtl { if is_rtl {
cols.reverse(); cols.reverse();
} }
@ -320,7 +329,8 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
Self { Self {
vt, vt,
cells, cells,
rtl, is_rtl,
has_gutter,
cols, cols,
rows, rows,
regions, regions,
@ -695,10 +705,11 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
assert!(y < self.rows.len()); assert!(y < self.rows.len());
// Columns are reorded, but the cell slice is not. // Columns are reorded, but the cell slice is not.
if self.rtl { if self.is_rtl {
x = self.cols.len() - 1 - x; x = self.cols.len() - 1 - x;
} }
if self.has_gutter {
// Even columns and rows are children, odd ones are gutter. // Even columns and rows are children, odd ones are gutter.
if x % 2 == 0 && y % 2 == 0 { if x % 2 == 0 && y % 2 == 0 {
let c = 1 + self.cols.len() / 2; let c = 1 + self.cols.len() / 2;
@ -706,5 +717,9 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
} else { } else {
None None
} }
} else {
let c = self.cols.len();
self.cells.get(y * c + x)
}
} }
} }