From 4cbd975b661860a26a2d033dbae6be5b13daac54 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 11 Feb 2025 10:54:52 +0100 Subject: [PATCH] LibWeb: Simplify determination of flex item's hypothetical cross size The spec tells us to treat `auto` as `fit-content` when determining flex item cross sizes, so let's just do *that* instead of awkwardly doing an uncacheable nested layout of the item. This was the only instance of `LayoutState` nesting outside of intrinsic sizing, so removing it is an important step towards simplifying layout. Turns out it was a lot easier than expected. --- .../LibWeb/Layout/FlexFormattingContext.cpp | 49 +++---------------- 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 2172ad2475e..0ede577ac11 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -1093,12 +1093,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& return; } - auto computed_cross_size = [&]() -> CSS::Size { - // "... treating auto as fit-content" - if (should_treat_cross_size_as_auto(item.box)) - return CSS::Size::make_fit_content(); - return this->computed_cross_size(item.box); - }(); + auto computed_cross_size = this->computed_cross_size(item.box); if (computed_cross_size.is_min_content()) { item.hypothetical_cross_size = css_clamp(calculate_min_content_cross_size(item), clamp_min, clamp_max); @@ -1110,44 +1105,16 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& return; } - if (computed_cross_size.is_fit_content()) { - CSSPixels fit_content_cross_size = 0; - if (is_row_layout()) { - auto available_width = item.main_size.has_value() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite(); - auto available_height = AvailableSize::make_indefinite(); - fit_content_cross_size = calculate_fit_content_height(item.box, AvailableSpace(available_width, available_height)); - } else { - fit_content_cross_size = calculate_fit_content_width(item.box, m_available_space_for_items->space); - } - - item.hypothetical_cross_size = css_clamp(fit_content_cross_size, clamp_min, clamp_max); - return; - } - - // For indefinite cross sizes, we perform a throwaway layout and then measure it. - LayoutState throwaway_state(&m_state); - - auto& box_state = throwaway_state.get_mutable(item.box); + // "... treating auto as fit-content" + auto fit_content_cross_size = calculate_fit_content_cross_size(item); if (is_row_layout()) { - box_state.set_content_width(item.main_size.value()); + auto available_width = item.main_size.has_value() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite(); + auto available_height = AvailableSize::make_indefinite(); + fit_content_cross_size = calculate_fit_content_height(item.box, AvailableSpace(available_width, available_height)); } else { - box_state.set_content_height(item.main_size.value()); + fit_content_cross_size = calculate_fit_content_width(item.box, m_available_space_for_items->space); } - - // Item has definite main size, layout with that as the used main size. - auto independent_formatting_context = create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::Normal, item.box); - // NOTE: Flex items should always create an independent formatting context! - VERIFY(independent_formatting_context); - - auto available_width = is_row_layout() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite(); - auto available_height = is_row_layout() ? AvailableSize::make_indefinite() : AvailableSize::make_definite(item.main_size.value()); - - independent_formatting_context->run(AvailableSpace(available_width, available_height)); - - auto automatic_cross_size = is_row_layout() ? independent_formatting_context->automatic_content_height() - : independent_formatting_context->automatic_content_width(); - - item.hypothetical_cross_size = css_clamp(automatic_cross_size, clamp_min, clamp_max); + item.hypothetical_cross_size = css_clamp(fit_content_cross_size, clamp_min, clamp_max); } // https://www.w3.org/TR/css-flexbox-1/#algo-cross-line