Skip to content

Commit

Permalink
Fix panics in the grid algorithm (#691)
Browse files Browse the repository at this point in the history
* Fix typo (max -> min) in grid track repetition resolution.

* Remove first/last optimisation that breaks with zero-sized track lists

* Grid: Fix crash when placing item with definite primary axis / indefinite secondary axis
  • Loading branch information
nicoburns authored Jul 16, 2024
1 parent b746ac4 commit 0ce2f3e
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/compute/grid/explicit_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub(crate) fn compute_explicit_grid_size_in_axis(
/// otherwise, flooring the max track sizing function by the min track sizing function if both are definite
fn track_definite_value(sizing_function: &NonRepeatedTrackSizingFunction, parent_size: Option<f32>) -> f32 {
let max_size = sizing_function.max.definite_value(parent_size);
let min_size = sizing_function.max.definite_value(parent_size);
let min_size = sizing_function.min.definite_value(parent_size);
max_size.map(|max| max.maybe_min(min_size)).or(min_size).unwrap()
}

Expand Down
5 changes: 3 additions & 2 deletions src/compute/grid/placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ fn place_indefinitely_positioned_item(
let primary_placement_style = placement.get(primary_axis);
let secondary_placement_style = placement.get(primary_axis.other_axis());

let primary_span = primary_placement_style.indefinite_span();
let secondary_span = secondary_placement_style.indefinite_span();
let has_definite_primary_axis_position = primary_placement_style.is_definite();
let primary_axis_grid_start_line = cell_occupancy_matrix.track_counts(primary_axis).implicit_start_line();
Expand Down Expand Up @@ -256,7 +255,7 @@ fn place_indefinitely_positioned_item(
// Item has fixed primary axis position: so we simply increment the secondary axis position
// until we find a space that the item fits in
loop {
let primary_span = Line { start: primary_idx, end: primary_idx + primary_span };
let primary_span = Line { start: primary_idx, end: primary_idx + definite_primary_placement.span() };
let secondary_span = Line { start: secondary_idx, end: secondary_idx + secondary_span };

// If area is occupied, increment the index and try again
Expand All @@ -269,6 +268,8 @@ fn place_indefinitely_positioned_item(
return (primary_span, secondary_span);
}
} else {
let primary_span = primary_placement_style.indefinite_span();

// Item does not have any fixed axis, so we search along the primary axis until we hit the end of the already
// existent tracks, and then we reset the primary axis back to zero and increment the secondary axis index.
// We continue in this vein until we find a space that the item fits in.
Expand Down
11 changes: 1 addition & 10 deletions src/compute/grid/track_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,16 +399,7 @@ fn flush_planned_growth_limit_increases(tracks: &mut [GridTrack], set_infinitely
/// Initialize each track’s base size and growth limit.
#[inline(always)]
fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_inner_node_size: Option<f32>) {
let last_track_idx = axis_tracks.len() - 1;

// First and last grid lines are always zero-sized.
axis_tracks[0].base_size = 0.0;
axis_tracks[0].growth_limit = 0.0;
axis_tracks[last_track_idx].base_size = 0.0;
axis_tracks[last_track_idx].growth_limit = 0.0;

let all_but_first_and_last = 1..last_track_idx;
for track in axis_tracks[all_but_first_and_last].iter_mut() {
for track in axis_tracks.iter_mut() {
// For each track, if the track’s min track sizing function is:
// - A fixed sizing function
// Resolve to an absolute length and use that size as the track’s initial base size.
Expand Down

0 comments on commit 0ce2f3e

Please sign in to comment.