From 79cbbfc67f72db57bfab7d6971deba6428d8ca97 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Fri, 4 Aug 2023 18:11:49 +0200 Subject: [PATCH] LibWeb: Fix infinite spinning while distributing extra space in GFC Fixes infinite spinning in the cases when CSSPixels does not have enough precision to represent increase per track which happens when very small extra_space got divided by affected tracks number. --- ...nfinite-spinning-in-space-distribution.txt | 21 +++++++++++++++++++ ...finite-spinning-in-space-distribution.html | 15 +++++++++++++ .../LibWeb/Layout/GridFormattingContext.cpp | 12 +++++------ 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/grid/should-not-cause-infinite-spinning-in-space-distribution.txt create mode 100644 Tests/LibWeb/Layout/input/grid/should-not-cause-infinite-spinning-in-space-distribution.html diff --git a/Tests/LibWeb/Layout/expected/grid/should-not-cause-infinite-spinning-in-space-distribution.txt b/Tests/LibWeb/Layout/expected/grid/should-not-cause-infinite-spinning-in-space-distribution.txt new file mode 100644 index 0000000000..e5796a2c00 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/grid/should-not-cause-infinite-spinning-in-space-distribution.txt @@ -0,0 +1,21 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x56.90625 [BFC] children: not-inline + Box at (10,10) content-size 780x38.90625 [GFC] children: not-inline + BlockContainer at (11,11) content-size 778x17.4375 [BFC] children: inline + line 0 width: 27.15625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [11,11 27.15625x17.46875] + "foo" + TextNode <#text> + BlockContainer at (11,30.4375) content-size 778x17.46875 [BFC] children: inline + line 0 width: 27.640625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [11,30.4375 27.640625x17.46875] + "bar" + TextNode <#text> + +PaintableWithLines (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x58.90625] + PaintableBox (Box) [9,9 782x40.90625] + PaintableWithLines (BlockContainer
.foo) [10,10 780x19.4375] overflow: [11,11 778x17.46875] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer
.bar) [10,29.4375 780x19.46875] + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/input/grid/should-not-cause-infinite-spinning-in-space-distribution.html b/Tests/LibWeb/Layout/input/grid/should-not-cause-infinite-spinning-in-space-distribution.html new file mode 100644 index 0000000000..869d1bd3b6 --- /dev/null +++ b/Tests/LibWeb/Layout/input/grid/should-not-cause-infinite-spinning-in-space-distribution.html @@ -0,0 +1,15 @@ +
foo
bar
\ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index ca0634789a..96fa2cea95 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -797,9 +797,7 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_base_si auto extra_space = max(CSSPixels(0), item_size_contribution - spanned_tracks_sizes_sum); // 2. Distribute space up to limits: - // FIXME: If a fixed-point type were used to represent CSS pixels, it would be possible to compare with 0 - // instead of epsilon. - while (extra_space > CSSPixels::epsilon()) { + while (true) { auto all_frozen = all_of(affected_tracks, [](auto const& track) { return track.base_size_frozen; }); if (all_frozen) break; @@ -808,6 +806,8 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_base_si // equally among such tracks, freezing a track’s item-incurred increase as its affected size + item-incurred // increase reaches its limit CSSPixels increase_per_track = extra_space / affected_tracks.size(); + if (increase_per_track == 0) + break; for (auto& track : affected_tracks) { if (track.base_size_frozen) continue; @@ -887,9 +887,7 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_growth_ auto extra_space = max(CSSPixels(0), item_size_contribution - spanned_tracks_sizes_sum); // 2. Distribute space up to limits: - // FIXME: If a fixed-point type were used to represent CSS pixels, it would be possible to compare with 0 - // instead of epsilon. - while (extra_space > CSSPixels::epsilon()) { + while (true) { auto all_frozen = all_of(affected_tracks, [](auto const& track) { return track.growth_limit_frozen; }); if (all_frozen) break; @@ -898,6 +896,8 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_growth_ // equally among such tracks, freezing a track’s item-incurred increase as its affected size + item-incurred // increase reaches its limit CSSPixels increase_per_track = extra_space / affected_tracks.size(); + if (increase_per_track == 0) + break; for (auto& track : affected_tracks) { if (track.growth_limit_frozen) continue;