diff options
author | Andreas Kling <kling@serenityos.org> | 2022-07-07 15:31:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-07-11 18:57:44 +0200 |
commit | 1690d888874bde788dcd9dd2b8f26316968558dc (patch) | |
tree | ca3edc4823b77d240dba2c85b8ffd748ad239624 /Userland | |
parent | 0bba2a4415a5cb7f43c16793f887bc34df62678c (diff) | |
download | serenity-1690d888874bde788dcd9dd2b8f26316968558dc.zip |
LibWeb: Clamp intrinsic flex item main size contributions to min/max
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index ba915137ef..8f03965073 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -1456,40 +1456,78 @@ float FlexFormattingContext::calculate_intrinsic_cross_size_of_flex_container(La return sum_of_flex_line_cross_sizes; } -float FlexFormattingContext::calculate_main_min_content_contribution(FlexItem const& flex_item) const +// https://drafts.csswg.org/css-flexbox-1/#intrinsic-item-contributions +float FlexFormattingContext::calculate_main_min_content_contribution(FlexItem const& item) const { - auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(flex_item.box); - auto const& box_state = m_state.get(flex_item.box); - if (is_row_layout()) - return box_state.margin_box_left() + intrinsic_sizes.min_content_size.width() + box_state.margin_box_right(); - return box_state.margin_box_top() + intrinsic_sizes.min_content_size.height() + box_state.margin_box_bottom(); + // The main-size min-content contribution of a flex item is + // the larger of its outer min-content size and outer preferred size if that is not auto, + // clamped by its min/max main size. + auto outer_min_content_size = [&]() -> float { + auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(item.box); + auto inner_main_size = is_row_layout() ? intrinsic_sizes.min_content_size.width() : intrinsic_sizes.min_content_size.height(); + auto outer_main_size = inner_main_size + + item.margins.main_before + item.margins.main_after + + item.borders.main_before + item.borders.main_after + + item.padding.main_before + item.padding.main_after; + return outer_main_size; + }(); + + if (!has_definite_main_size(item.box)) { + return outer_min_content_size; + } + + auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : 0; + auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max(); + auto unclamped_preferred_size = resolved_definite_main_size(item.box); + auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max); + return max(outer_min_content_size, clamped_preferred_size); } -float FlexFormattingContext::calculate_main_max_content_contribution(FlexItem const& flex_item) const +// https://drafts.csswg.org/css-flexbox-1/#intrinsic-item-contributions +float FlexFormattingContext::calculate_main_max_content_contribution(FlexItem const& item) const { - auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(flex_item.box); - auto const& box_state = m_state.get(flex_item.box); - if (is_row_layout()) - return box_state.margin_box_left() + intrinsic_sizes.max_content_size.width() + box_state.margin_box_right(); - return box_state.margin_box_top() + intrinsic_sizes.max_content_size.height() + box_state.margin_box_bottom(); + // The main-size max-content contribution of a flex item is the larger of its outer max-content size and outer preferred size if that is not auto, clamped by its min/max main size. + auto outer_max_content_size = [&]() -> float { + auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(item.box); + auto inner_main_size = is_row_layout() ? intrinsic_sizes.max_content_size.width() : intrinsic_sizes.max_content_size.height(); + auto outer_main_size = inner_main_size + + item.margins.main_before + item.margins.main_after + + item.borders.main_before + item.borders.main_after + + item.padding.main_before + item.padding.main_after; + return outer_main_size; + }(); + + if (!has_definite_main_size(item.box)) { + return outer_max_content_size; + } + + auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : 0; + auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max(); + auto unclamped_preferred_size = resolved_definite_main_size(item.box); + auto clamped_preferred_size = css_clamp(unclamped_preferred_size, clamp_min, clamp_max); + return max(outer_max_content_size, clamped_preferred_size); } float FlexFormattingContext::calculate_cross_min_content_contribution(FlexItem const& flex_item) const { auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(flex_item.box); - auto const& box_state = m_state.get(flex_item.box); - if (is_row_layout()) - return box_state.margin_box_top() + intrinsic_sizes.min_content_size.height() + box_state.margin_box_bottom(); - return box_state.margin_box_left() + intrinsic_sizes.min_content_size.width() + box_state.margin_box_right(); + auto inner_cross_size = is_row_layout() ? intrinsic_sizes.min_content_size.height() : intrinsic_sizes.min_content_size.width(); + auto outer_cross_size = inner_cross_size + + flex_item.margins.cross_before + flex_item.margins.cross_after + + flex_item.borders.cross_before + flex_item.borders.cross_after + + flex_item.padding.cross_before + flex_item.padding.cross_after; + return outer_cross_size; } float FlexFormattingContext::calculate_cross_max_content_contribution(FlexItem const& flex_item) const { auto intrinsic_sizes = FormattingContext::calculate_intrinsic_sizes(flex_item.box); - auto const& box_state = m_state.get(flex_item.box); - if (is_row_layout()) - return box_state.margin_box_top() + intrinsic_sizes.max_content_size.height() + box_state.margin_box_bottom(); - return box_state.margin_box_left() + intrinsic_sizes.max_content_size.width() + box_state.margin_box_right(); + auto inner_cross_size = is_row_layout() ? intrinsic_sizes.max_content_size.height() : intrinsic_sizes.max_content_size.width(); + auto outer_cross_size = inner_cross_size + + flex_item.margins.cross_before + flex_item.margins.cross_after + + flex_item.borders.cross_before + flex_item.borders.cross_after + + flex_item.padding.cross_before + flex_item.padding.cross_after; + return outer_cross_size; } } |