From 0a09ff698fc6ce1db704b7c26245cf14c5285a9a Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Wed, 17 Jan 2024 14:43:04 +0100 Subject: [PATCH] LibWeb: Fix accounting for gaps in auto-fit count calculation in GFC Fixes a bug where gaps between repeated tracks were accounted for only once instead of multiple times, corresponding to the repeat count. Fixes https://github.com/SerenityOS/serenity/issues/22823 --- .../grid/columns-auto-fill-with-gap-3.txt | 19 ++++++++++++++ .../grid/columns-auto-fill-with-gap-3.html | 13 ++++++++++ .../LibWeb/Layout/GridFormattingContext.cpp | 25 +++++++++++-------- 3 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/grid/columns-auto-fill-with-gap-3.txt create mode 100644 Tests/LibWeb/Layout/input/grid/columns-auto-fill-with-gap-3.html diff --git a/Tests/LibWeb/Layout/expected/grid/columns-auto-fill-with-gap-3.txt b/Tests/LibWeb/Layout/expected/grid/columns-auto-fill-with-gap-3.txt new file mode 100644 index 0000000000..46a712060a --- /dev/null +++ b/Tests/LibWeb/Layout/expected/grid/columns-auto-fill-with-gap-3.txt @@ -0,0 +1,19 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x33 [BFC] children: not-inline + Box at (8,8) content-size 784x17 [GFC] children: not-inline + BlockContainer
at (8,8) content-size 63.125x17 [BFC] children: inline + frag 0 from TextNode start: 0, length: 7, rect: [8,8 63.125x17] baseline: 13.296875 + "Explore" + TextNode <#text> + BlockContainer
at (121.125,8) content-size 100.0625x17 [BFC] children: inline + frag 0 from TextNode start: 0, length: 12, rect: [121.125,8 100.0625x17] baseline: 13.296875 + "Wiki Content" + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x33] + PaintableBox (Box) [8,8 784x17] + PaintableWithLines (BlockContainer
) [8,8 63.125x17] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer
) [121.125,8 100.0625x17] + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/input/grid/columns-auto-fill-with-gap-3.html b/Tests/LibWeb/Layout/input/grid/columns-auto-fill-with-gap-3.html new file mode 100644 index 0000000000..39b59b3ec2 --- /dev/null +++ b/Tests/LibWeb/Layout/input/grid/columns-auto-fill-with-gap-3.html @@ -0,0 +1,13 @@ +
Explore
Wiki Content
\ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 49478aefca..1ad603b781 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -86,40 +86,43 @@ int GridFormattingContext::count_of_repeated_auto_fill_or_fit_tracks(GridDimensi auto const& grid_computed_values = grid_container().computed_values(); auto const& track_list = dimension == GridDimension::Row ? grid_computed_values.grid_template_rows().track_list() : grid_computed_values.grid_template_columns().track_list(); - CSSPixels sum_of_grid_track_sizes = 0; + CSSPixels size_of_repeated_tracks = 0; // (treating each track as its max track sizing function if that is definite or its minimum track sizing // function otherwise, flooring the max track sizing function by the min track sizing function if both // are definite, and taking gap into account) auto const& repeat_track_list = track_list.first().repeat().grid_track_size_list().track_list(); - for (auto& explicit_grid_track : repeat_track_list) { - auto track_sizing_function = explicit_grid_track; + for (auto const& explicit_grid_track : repeat_track_list) { + auto const& track_sizing_function = explicit_grid_track; if (track_sizing_function.is_minmax()) { if (track_sizing_function.minmax().max_grid_size().is_definite() && !track_sizing_function.minmax().min_grid_size().is_definite()) - sum_of_grid_track_sizes += resolve_definite_track_size(track_sizing_function.minmax().max_grid_size(), *m_available_space); + size_of_repeated_tracks += resolve_definite_track_size(track_sizing_function.minmax().max_grid_size(), *m_available_space); else if (track_sizing_function.minmax().min_grid_size().is_definite() && !track_sizing_function.minmax().max_grid_size().is_definite()) - sum_of_grid_track_sizes += resolve_definite_track_size(track_sizing_function.minmax().min_grid_size(), *m_available_space); + size_of_repeated_tracks += resolve_definite_track_size(track_sizing_function.minmax().min_grid_size(), *m_available_space); else if (track_sizing_function.minmax().min_grid_size().is_definite() && track_sizing_function.minmax().max_grid_size().is_definite()) - sum_of_grid_track_sizes += min(resolve_definite_track_size(track_sizing_function.minmax().min_grid_size(), *m_available_space), resolve_definite_track_size(track_sizing_function.minmax().max_grid_size(), *m_available_space)); + size_of_repeated_tracks += min(resolve_definite_track_size(track_sizing_function.minmax().min_grid_size(), *m_available_space), resolve_definite_track_size(track_sizing_function.minmax().max_grid_size(), *m_available_space)); } else { - sum_of_grid_track_sizes += min(resolve_definite_track_size(track_sizing_function.grid_size(), *m_available_space), resolve_definite_track_size(track_sizing_function.grid_size(), *m_available_space)); + size_of_repeated_tracks += min(resolve_definite_track_size(track_sizing_function.grid_size(), *m_available_space), resolve_definite_track_size(track_sizing_function.grid_size(), *m_available_space)); } } - if (sum_of_grid_track_sizes == 0) + if (size_of_repeated_tracks == 0) return 0; auto const& available_size = dimension == GridDimension::Column ? m_available_space->width : m_available_space->height; auto free_space = get_free_space(*m_available_space, dimension).to_px_or_zero(); auto const& gap = dimension == GridDimension::Column ? grid_computed_values.column_gap() : grid_computed_values.row_gap(); - free_space -= repeat_track_list.size() * gap.to_px(grid_container(), available_size.to_px_or_zero()); + auto gap_px = gap.to_px(grid_container(), available_size.to_px_or_zero()); + auto size_of_repeated_tracks_with_gap = size_of_repeated_tracks + repeat_track_list.size() * gap_px; // If any number of repetitions would overflow, then 1 repetition. - if (free_space <= sum_of_grid_track_sizes) { + if (free_space <= size_of_repeated_tracks_with_gap) { return 1; } // Otherwise, if the grid container has a definite min size in the relevant axis, the number of repetitions is the // smallest possible positive integer that fulfills that minimum requirement else if (available_size.is_definite()) { - return max(1, (free_space / sum_of_grid_track_sizes).to_int()); + // NOTE: Gap size is added to free space to compensate for the fact that the last track does not have a gap + auto number_of_repetitions = ((free_space + gap_px) / size_of_repeated_tracks_with_gap).to_int(); + return max(1, number_of_repetitions); } // Otherwise, the specified track list repeats only once. return 1;