From 4935055407e62196379b7b49baabafb6f92a70cf Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 6 Jul 2022 19:15:31 +0200 Subject: [PATCH] LibWeb: Keep the "remaining free space" across flexbox algo steps Instead of recomputing the "remaining free space" per flex line, remember it after calculating it during the "resolve flexible lengths" step so we can reuse it later. --- .../LibWeb/Layout/FlexFormattingContext.cpp | 27 +++++++++---------- .../LibWeb/Layout/FlexFormattingContext.h | 1 + 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index b633690d94..9236edb369 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -853,6 +853,7 @@ void FlexFormattingContext::resolve_flexible_lengths() }; float initial_free_space = calculate_free_space(); + flex_line.remaining_free_space = initial_free_space; // 6.4 Loop auto for_each_unfrozen_item = [&flex_line](auto callback) { @@ -864,7 +865,7 @@ void FlexFormattingContext::resolve_flexible_lengths() while (number_of_unfrozen_items_on_line > 0) { // b Calculate the remaining free space - auto remaining_free_space = calculate_free_space(); + flex_line.remaining_free_space = calculate_free_space(); float sum_of_unfrozen_flex_items_flex_factors = 0; for_each_unfrozen_item([&](FlexItem* item) { sum_of_unfrozen_flex_items_flex_factors += item->flex_factor.value_or(1); @@ -872,17 +873,17 @@ void FlexFormattingContext::resolve_flexible_lengths() if (sum_of_unfrozen_flex_items_flex_factors < 1) { auto intermediate_free_space = initial_free_space * sum_of_unfrozen_flex_items_flex_factors; - if (AK::abs(intermediate_free_space) < AK::abs(remaining_free_space)) - remaining_free_space = intermediate_free_space; + if (AK::abs(intermediate_free_space) < AK::abs(flex_line.remaining_free_space)) + flex_line.remaining_free_space = intermediate_free_space; } // c Distribute free space proportional to the flex factors - if (remaining_free_space != 0) { + if (flex_line.remaining_free_space != 0) { if (used_flex_factor == FlexFactor::FlexGrowFactor) { float sum_of_flex_grow_factor_of_unfrozen_items = sum_of_unfrozen_flex_items_flex_factors; for_each_unfrozen_item([&](FlexItem* flex_item) { float ratio = flex_item->flex_factor.value_or(1) / sum_of_flex_grow_factor_of_unfrozen_items; - flex_item->target_main_size = flex_item->flex_base_size + (remaining_free_space * ratio); + flex_item->target_main_size = flex_item->flex_base_size + (flex_line.remaining_free_space * ratio); }); } else if (used_flex_factor == FlexFactor::FlexShrinkFactor) { float sum_of_scaled_flex_shrink_factor_of_unfrozen_items = 0; @@ -895,7 +896,7 @@ void FlexFormattingContext::resolve_flexible_lengths() float ratio = 1.0f; if (sum_of_scaled_flex_shrink_factor_of_unfrozen_items != 0.0f) ratio = flex_item->scaled_flex_shrink_factor / sum_of_scaled_flex_shrink_factor_of_unfrozen_items; - flex_item->target_main_size = flex_item->flex_base_size - (AK::abs(remaining_free_space) * ratio); + flex_item->target_main_size = flex_item->flex_base_size - (AK::abs(flex_line.remaining_free_space) * ratio); }); } } else { @@ -1088,17 +1089,13 @@ void FlexFormattingContext::distribute_any_remaining_free_space() used_main_space += flex_item->main_size; if (is_main_axis_margin_first_auto(flex_item->box)) ++auto_margins; - else - used_main_space += flex_item->margins.main_before + flex_item->borders.main_before + flex_item->padding.main_before; if (is_main_axis_margin_second_auto(flex_item->box)) ++auto_margins; - else - used_main_space += flex_item->margins.main_after + flex_item->borders.main_after + flex_item->padding.main_after; } - float remaining_free_space = m_available_space->main.value_or(NumericLimits::max()) - used_main_space; - if (remaining_free_space > 0) { - float size_per_auto_margin = remaining_free_space / (float)auto_margins; + + if (flex_line.remaining_free_space > 0) { + float size_per_auto_margin = flex_line.remaining_free_space / (float)auto_margins; for (auto& flex_item : flex_line.items) { if (is_main_axis_margin_first_auto(flex_item->box)) set_main_axis_first_margin(*flex_item, size_per_auto_margin); @@ -1129,10 +1126,10 @@ void FlexFormattingContext::distribute_any_remaining_free_space() space_before_first_item = (m_available_space->main.value_or(NumericLimits::max()) - used_main_space) / 2.0f; break; case CSS::JustifyContent::SpaceBetween: - space_between_items = remaining_free_space / (number_of_items - 1); + space_between_items = flex_line.remaining_free_space / (number_of_items - 1); break; case CSS::JustifyContent::SpaceAround: - space_between_items = remaining_free_space / number_of_items; + space_between_items = flex_line.remaining_free_space / number_of_items; space_before_first_item = space_between_items / 2.0f; break; } diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index 0797d95460..5c752a96bd 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -57,6 +57,7 @@ private: struct FlexLine { Vector items; float cross_size { 0 }; + float remaining_free_space { 0 }; }; bool has_definite_main_size(Box const&) const;