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.
This commit is contained in:
Aliaksandr Kalenik 2023-08-04 18:11:49 +02:00 committed by Andreas Kling
parent de1726caee
commit 79cbbfc67f
Notes: sideshowbarker 2024-07-16 20:05:14 +09:00
3 changed files with 42 additions and 6 deletions

View File

@ -0,0 +1,21 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (1,1) content-size 798x56.90625 [BFC] children: not-inline
Box <body> at (10,10) content-size 780x38.90625 [GFC] children: not-inline
BlockContainer <div.foo> 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 <div.bar> 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<HTML>) [0,0 800x58.90625]
PaintableBox (Box<BODY>) [9,9 782x40.90625]
PaintableWithLines (BlockContainer<DIV>.foo) [10,10 780x19.4375] overflow: [11,11 778x17.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.bar) [10,29.4375 780x19.46875]
TextPaintable (TextNode<#text>)

View File

@ -0,0 +1,15 @@
<!doctype html><style>
* {
border: 1px solid black;
}
body {
display: grid;
grid-template-rows: repeat(10, min-content) 1fr;
}
.foo {
grid-area: 4 / 1 / 8 / 2;
}
.bar {
grid-area: 9 / 1 / 10 / 2;
}
</style><body><div class="foo">foo</div><div class="bar">bar</div>

View File

@ -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 tracks 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 tracks 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;