From ac124fbaae7732e733f21f5a550840e620ecfb8d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 17 Jul 2023 21:19:33 +0200 Subject: [PATCH] LibWeb: Resolve flex item percentages against used flex container sizes Once we've resolved the used flex item width & height, we should allow percentage flex item sizes to resolve against them instead of forcing flex items to always treat percentages as auto while doing intrinsic sizing layout. Regressed in 8dd489da61362738a39ec938732e3d054ff5da8b. --- ...-column-item-with-percentage-max-width.txt | 11 ++ ...column-item-with-percentage-max-width.html | 24 +++++ .../LibWeb/Layout/FlexFormattingContext.cpp | 100 +++++++++--------- .../LibWeb/Layout/FlexFormattingContext.h | 12 +-- .../LibWeb/Layout/FormattingContext.cpp | 32 ++++++ .../LibWeb/Layout/FormattingContext.h | 3 + 6 files changed, 126 insertions(+), 56 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/flex/flex-column-item-with-percentage-max-width.txt create mode 100644 Tests/LibWeb/Layout/input/flex/flex-column-item-with-percentage-max-width.html diff --git a/Tests/LibWeb/Layout/expected/flex/flex-column-item-with-percentage-max-width.txt b/Tests/LibWeb/Layout/expected/flex/flex-column-item-with-percentage-max-width.txt new file mode 100644 index 0000000000..6fc0fc2d4c --- /dev/null +++ b/Tests/LibWeb/Layout/expected/flex/flex-column-item-with-percentage-max-width.txt @@ -0,0 +1,11 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x120 [BFC] children: not-inline + BlockContainer at (10,10) content-size 54x102 children: not-inline + Box at (11,11) content-size 52x100 flex-container(column) [FFC] children: not-inline + BlockContainer at (12,12) content-size 50x17.46875 flex-item [BFC] children: inline + line 0 width: 39.78125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 5, rect: [12,12 39.78125x17.46875] + "Hello" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) [BFC] children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/flex/flex-column-item-with-percentage-max-width.html b/Tests/LibWeb/Layout/input/flex/flex-column-item-with-percentage-max-width.html new file mode 100644 index 0000000000..be0df9f4fe --- /dev/null +++ b/Tests/LibWeb/Layout/input/flex/flex-column-item-with-percentage-max-width.html @@ -0,0 +1,24 @@ + + +
Hello
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 85ca7ad774..bdfe46902e 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -27,14 +27,14 @@ template return ::max(min, ::min(value, max)); } -CSSPixels FlexFormattingContext::get_pixel_width(Box const& box, AvailableSpace const& available_space, CSS::Size const& size) const +CSSPixels FlexFormattingContext::get_pixel_width(Box const& box, CSS::Size const& size) const { - return calculate_inner_width(box, available_space.width, size).to_px(box); + return calculate_inner_width(box, containing_block_width_as_available_size(box), size).to_px(box); } -CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, AvailableSpace const& available_space, CSS::Size const& size) const +CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, CSS::Size const& size) const { - return calculate_inner_height(box, available_space.height, size).to_px(box); + return calculate_inner_height(box, containing_block_height_as_available_size(box), size).to_px(box); } FlexFormattingContext::FlexFormattingContext(LayoutState& state, Box const& flex_container, FormattingContext* parent) @@ -96,8 +96,8 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c for (auto& item : m_flex_items) { if (!flex_item_is_stretched(item)) continue; - auto item_min_cross_size = has_cross_min_size(item.box) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0; - auto item_max_cross_size = has_cross_max_size(item.box) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : INFINITY; + auto item_min_cross_size = has_cross_min_size(item.box) ? specified_cross_min_size(item.box) : 0; + auto item_max_cross_size = has_cross_max_size(item.box) ? specified_cross_max_size(item.box) : INFINITY; auto item_preferred_outer_cross_size = css_clamp(flex_container_inner_cross_size, item_min_cross_size, item_max_cross_size); auto item_inner_cross_size = item_preferred_outer_cross_size - item.margins.cross_before - item.margins.cross_after - item.padding.cross_before - item.padding.cross_after - item.borders.cross_before - item.borders.cross_after; set_cross_size(item.box, item_inner_cross_size); @@ -352,18 +352,18 @@ bool FlexFormattingContext::has_definite_cross_size(Box const& box) const return is_row_layout() ? used_values.has_definite_height() : used_values.has_definite_width(); } -CSSPixels FlexFormattingContext::specified_main_min_size(Box const& box, AvailableSpace const& available_space) const +CSSPixels FlexFormattingContext::specified_main_min_size(Box const& box) const { return is_row_layout() - ? get_pixel_width(box, available_space, box.computed_values().min_width()) - : get_pixel_height(box, available_space, box.computed_values().min_height()); + ? get_pixel_width(box, box.computed_values().min_width()) + : get_pixel_height(box, box.computed_values().min_height()); } -CSSPixels FlexFormattingContext::specified_cross_min_size(Box const& box, AvailableSpace const& available_space) const +CSSPixels FlexFormattingContext::specified_cross_min_size(Box const& box) const { return is_row_layout() - ? get_pixel_height(box, available_space, box.computed_values().min_height()) - : get_pixel_width(box, available_space, box.computed_values().min_width()); + ? get_pixel_height(box, box.computed_values().min_height()) + : get_pixel_width(box, box.computed_values().min_width()); } bool FlexFormattingContext::has_main_max_size(Box const& box) const @@ -378,18 +378,18 @@ bool FlexFormattingContext::has_cross_max_size(Box const& box) const return !value.is_none(); } -CSSPixels FlexFormattingContext::specified_main_max_size(Box const& box, AvailableSpace const& available_space) const +CSSPixels FlexFormattingContext::specified_main_max_size(Box const& box) const { return is_row_layout() - ? get_pixel_width(box, available_space, box.computed_values().max_width()) - : get_pixel_height(box, available_space, box.computed_values().max_height()); + ? get_pixel_width(box, box.computed_values().max_width()) + : get_pixel_height(box, box.computed_values().max_height()); } -CSSPixels FlexFormattingContext::specified_cross_max_size(Box const& box, AvailableSpace const& available_space) const +CSSPixels FlexFormattingContext::specified_cross_max_size(Box const& box) const { return is_row_layout() - ? get_pixel_height(box, available_space, box.computed_values().max_height()) - : get_pixel_width(box, available_space, box.computed_values().max_width()); + ? get_pixel_height(box, box.computed_values().max_height()) + : get_pixel_width(box, box.computed_values().max_width()); } bool FlexFormattingContext::is_cross_auto(Box const& box) const @@ -608,8 +608,8 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size( if (item.used_flex_basis_is_definite) { auto const& size = item.used_flex_basis->get(); if (is_row_layout()) - return get_pixel_width(child_box, m_available_space_for_items->space, size); - return get_pixel_height(child_box, m_available_space_for_items->space, size); + return get_pixel_width(child_box, size); + return get_pixel_height(child_box, size); } // B. If the flex item has ... @@ -687,8 +687,8 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size( } // The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero). - auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box, m_available_space_for_items->space) : automatic_minimum_size(item); - auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : automatic_minimum_size(item); + auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : NumericLimits::max(); item.hypothetical_main_size = max(CSSPixels(0), css_clamp(item.flex_base_size, clamp_min, clamp_max)); // NOTE: At this point, we set the hypothetical main size as the flex item's *temporary* main size. @@ -721,7 +721,7 @@ Optional FlexFormattingContext::specified_size_suggestion(FlexItem co // then the specified size suggestion is that size. It is otherwise undefined. if (has_definite_main_size(item.box) && !should_treat_main_size_as_auto(item.box)) { // NOTE: We use get_pixel_{width,height} to ensure that CSS box-sizing is respected. - return is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box)); + return is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box)); } return {}; } @@ -781,7 +781,7 @@ CSSPixels FlexFormattingContext::content_based_minimum_size(FlexItem const& item // In all cases, the size is clamped by the maximum main size if it’s definite. if (has_main_max_size(item.box)) { - return min(unclamped_size, specified_main_max_size(item.box, m_available_space_for_items->space)); + return min(unclamped_size, specified_main_max_size(item.box)); } return unclamped_size; } @@ -1036,11 +1036,11 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line) if (item.frozen) continue; auto used_min_main_size = has_main_min_size(item.box) - ? specified_main_min_size(item.box, m_available_space_for_items->space) + ? specified_main_min_size(item.box) : automatic_minimum_size(item); auto used_max_main_size = has_main_max_size(item.box) - ? specified_main_max_size(item.box, m_available_space_for_items->space) + ? specified_main_max_size(item.box) : NumericLimits::max(); auto original_target_main_size = item.target_main_size; @@ -1124,8 +1124,8 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& auto const& computed_min_size = this->computed_cross_min_size(item.box); auto const& computed_max_size = this->computed_cross_max_size(item.box); - auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0; - auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0; + auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max(); // If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is. if (has_definite_cross_size(item.box)) { @@ -1218,8 +1218,8 @@ void FlexFormattingContext::calculate_cross_size_of_each_flex_line() if (is_single_line()) { auto const& computed_min_size = this->computed_cross_min_size(flex_container()); auto const& computed_max_size = this->computed_cross_max_size(flex_container()); - auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container(), m_available_space_for_flex_container->space) : 0; - auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container(), m_available_space_for_flex_container->space) : INFINITY; + auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container()) : 0; + auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container()) : INFINITY; m_flex_lines[0].cross_size = css_clamp(m_flex_lines[0].cross_size, cross_min_size, cross_max_size); } } @@ -1243,8 +1243,8 @@ void FlexFormattingContext::determine_used_cross_size_of_each_flex_item() auto const& computed_min_size = computed_cross_min_size(item.box); auto const& computed_max_size = computed_cross_max_size(item.box); - auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0; - auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : INFINITY; + auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(item.box) : 0; + auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(item.box) : INFINITY; item.cross_size = css_clamp(unclamped_cross_size, cross_min_size, cross_max_size); } else { @@ -1519,8 +1519,8 @@ void FlexFormattingContext::determine_flex_container_used_cross_size() } auto const& computed_min_size = this->computed_cross_min_size(flex_container()); auto const& computed_max_size = this->computed_cross_max_size(flex_container()); - auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container(), m_available_space_for_flex_container->space) : 0; - auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container(), m_available_space_for_flex_container->space) : INFINITY; + auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container()) : 0; + auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container()) : INFINITY; set_cross_size(flex_container(), css_clamp(cross_size, cross_min_size, cross_max_size)); } @@ -1762,8 +1762,8 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container auto const& computed_min_size = this->computed_main_min_size(item.box); auto const& computed_max_size = this->computed_main_max_size(item.box); - auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item); - auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box) : automatic_minimum_size(item); + auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : NumericLimits::max(); result = css_clamp(result, clamp_min, clamp_max); @@ -1865,12 +1865,12 @@ CSSPixels FlexFormattingContext::calculate_main_min_content_contribution(FlexIte auto inner_min_content_size = calculate_min_content_main_size(item); if (computed_main_size(item.box).is_auto()) return inner_min_content_size; - auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box)); + auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box)); return max(inner_min_content_size, inner_preferred_size); }(); - auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item); - auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item); + auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits::max(); auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max); return item.add_main_margin_box_sizes(clamped_inner_size); @@ -1886,12 +1886,12 @@ CSSPixels FlexFormattingContext::calculate_main_max_content_contribution(FlexIte auto inner_max_content_size = calculate_max_content_main_size(item); if (computed_main_size(item.box).is_auto()) return inner_max_content_size; - auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box)); + auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box)); return max(inner_max_content_size, inner_preferred_size); }(); - auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item); - auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item); + auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits::max(); auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max); return item.add_main_margin_box_sizes(clamped_inner_size); @@ -1916,14 +1916,14 @@ CSSPixels FlexFormattingContext::calculate_cross_min_content_contribution(FlexIt auto size = [&] { if (should_treat_cross_size_as_auto(item.box)) return calculate_min_content_cross_size(item); - return !is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_cross_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_cross_size(item.box)); + return !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box)); }(); auto const& computed_min_size = this->computed_cross_min_size(item.box); auto const& computed_max_size = this->computed_cross_max_size(item.box); - auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0; - auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0; + auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max(); auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max); @@ -1935,14 +1935,14 @@ CSSPixels FlexFormattingContext::calculate_cross_max_content_contribution(FlexIt auto size = [&] { if (should_treat_cross_size_as_auto(item.box)) return calculate_max_content_cross_size(item); - return !is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_cross_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_cross_size(item.box)); + return !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box)); }(); auto const& computed_min_size = this->computed_cross_min_size(item.box); auto const& computed_max_size = this->computed_cross_max_size(item.box); - auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0; - auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0; + auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits::max(); auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max); @@ -1953,8 +1953,8 @@ CSSPixels FlexFormattingContext::calculate_clamped_fit_content_width(Box const& { auto const& computed_min_size = box.computed_values().min_width(); auto const& computed_max_size = box.computed_values().max_width(); - auto clamp_min = (!computed_min_size.is_auto() && (!computed_min_size.contains_percentage())) ? specified_cross_min_size(box, m_available_space_for_items->space) : 0; - auto clamp_max = (!computed_max_size.is_none() && (!computed_max_size.contains_percentage())) ? specified_cross_max_size(box, m_available_space_for_items->space) : NumericLimits::max(); + auto clamp_min = (!computed_min_size.is_auto() && (!computed_min_size.contains_percentage())) ? specified_cross_min_size(box) : 0; + auto clamp_max = (!computed_max_size.is_none() && (!computed_max_size.contains_percentage())) ? specified_cross_max_size(box) : NumericLimits::max(); auto size = FormattingContext::calculate_fit_content_width(box, available_space); return css_clamp(size, clamp_min, clamp_max); } diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index 2260b16a53..5a887b8c58 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -124,11 +124,11 @@ private: CSSPixels inner_cross_size(Box const&) const; bool has_main_min_size(Box const&) const; bool has_cross_min_size(Box const&) const; - CSSPixels specified_main_max_size(Box const&, AvailableSpace const&) const; - CSSPixels specified_cross_max_size(Box const&, AvailableSpace const&) const; + CSSPixels specified_main_max_size(Box const&) const; + CSSPixels specified_cross_max_size(Box const&) const; bool is_cross_auto(Box const&) const; - CSSPixels specified_main_min_size(Box const&, AvailableSpace const&) const; - CSSPixels specified_cross_min_size(Box const&, AvailableSpace const&) const; + CSSPixels specified_main_min_size(Box const&) const; + CSSPixels specified_cross_min_size(Box const&) const; bool has_main_max_size(Box const&) const; bool has_cross_max_size(Box const&) const; CSSPixels automatic_minimum_size(FlexItem const&) const; @@ -143,8 +143,8 @@ private: CSS::Size const& computed_cross_min_size(Box const&) const; CSS::Size const& computed_cross_max_size(Box const&) const; - CSSPixels get_pixel_width(Box const&, AvailableSpace const&, CSS::Size const&) const; - CSSPixels get_pixel_height(Box const&, AvailableSpace const&, CSS::Size const&) const; + CSSPixels get_pixel_width(Box const&, CSS::Size const&) const; + CSSPixels get_pixel_height(Box const&, CSS::Size const&) const; bool flex_item_is_stretched(FlexItem const&) const; diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 77af6ecd6d..283bd954a4 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1566,6 +1566,38 @@ CSSPixels FormattingContext::containing_block_height_for(Box const& box) const VERIFY_NOT_REACHED(); } +AvailableSize FormattingContext::containing_block_width_as_available_size(Box const& box) const +{ + auto const& containing_block_state = m_state.get(*box.containing_block()); + auto const& box_state = m_state.get(box); + + switch (box_state.width_constraint) { + case SizeConstraint::MinContent: + return AvailableSize::make_min_content(); + case SizeConstraint::MaxContent: + return AvailableSize::make_max_content(); + case SizeConstraint::None: + return AvailableSize::make_definite(containing_block_state.content_width()); + } + VERIFY_NOT_REACHED(); +} + +AvailableSize FormattingContext::containing_block_height_as_available_size(Box const& box) const +{ + auto const& containing_block_state = m_state.get(*box.containing_block()); + auto const& box_state = m_state.get(box); + + switch (box_state.height_constraint) { + case SizeConstraint::MinContent: + return AvailableSize::make_min_content(); + case SizeConstraint::MaxContent: + return AvailableSize::make_max_content(); + case SizeConstraint::None: + return AvailableSize::make_definite(containing_block_state.content_height()); + } + VERIFY_NOT_REACHED(); +} + // https://drafts.csswg.org/css-sizing-3/#stretch-fit-size CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const { diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index 40b1ed1ea6..12d626cc3e 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -83,6 +83,9 @@ public: [[nodiscard]] CSSPixels containing_block_width_for(Box const&) const; [[nodiscard]] CSSPixels containing_block_height_for(Box const&) const; + [[nodiscard]] AvailableSize containing_block_width_as_available_size(Box const&) const; + [[nodiscard]] AvailableSize containing_block_height_as_available_size(Box const&) const; + [[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const; [[nodiscard]] CSSPixels calculate_stretch_fit_height(Box const&, AvailableSize const&) const;