diff options
author | Andreas Kling <kling@serenityos.org> | 2021-10-13 21:49:28 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-13 23:56:26 +0200 |
commit | 3375953918ac63767fd4495b757ab39ec670633b (patch) | |
tree | 94a7c481bee883fb6f584feaf03b6520095e9d21 /Userland | |
parent | c19358e1576514c6006756cff31190ae2488c5c0 (diff) | |
download | serenity-3375953918ac63767fd4495b757ab39ec670633b.zip |
LibWeb: Move FFC layout algorithm step 3 to a separate function
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp | 167 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h | 3 |
2 files changed, 90 insertions, 80 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 383c6602ee..3b5f7d52b6 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -72,40 +72,6 @@ void FlexFormattingContext::run(Box& flex_container, LayoutMode) bool is_row = is_row_layout(); - auto layout_for_maximum_main_size = [&](Box& box) { - bool main_constrained = false; - if (is_row) { - if (!box.computed_values().width().is_undefined_or_auto() || !box.computed_values().min_width().is_undefined_or_auto()) { - main_constrained = true; - } - } else { - if (!box.computed_values().height().is_undefined_or_auto() || !box.computed_values().min_height().is_undefined_or_auto()) { - main_constrained = true; - } - } - - if (!main_constrained && box.children_are_inline()) { - auto& block_container = verify_cast<BlockContainer>(box); - BlockFormattingContext bfc(block_container, this); - bfc.run(box, LayoutMode::Default); - InlineFormattingContext ifc(block_container, &bfc); - - if (is_row) { - ifc.run(box, LayoutMode::OnlyRequiredLineBreaks); - return box.width(); - } else { - ifc.run(box, LayoutMode::AllPossibleLineBreaks); - return box.height(); - } - } - if (is_row) { - layout_inside(box, LayoutMode::OnlyRequiredLineBreaks); - return box.width(); - } else { - return BlockFormattingContext::compute_theoretical_height(box); - } - }; - auto calculate_hypothetical_cross_size = [&is_row, this](Box& box) { bool cross_constrained = false; if (is_row) { @@ -157,52 +123,7 @@ void FlexFormattingContext::run(Box& flex_container, LayoutMode) // 3. Determine the flex base size and hypothetical main size of each item for (auto& flex_item : flex_items) { - auto& child_box = flex_item.box; - auto flex_basis = child_box.computed_values().flex_basis(); - if (flex_basis.type == CSS::FlexBasis::Length) { - // A - auto specified_base_size = get_pixel_size(child_box, flex_basis.length); - if (specified_base_size == 0) - flex_item.flex_base_size = calculated_main_size(flex_item.box); - else - flex_item.flex_base_size = specified_base_size; - } else if (flex_basis.type == CSS::FlexBasis::Content - && has_definite_cross_size(child_box) - // FIXME: && has intrinsic aspect ratio. - && false) { - // B - TODO(); - // flex_base_size is calculated from definite cross size and intrinsic aspect ratio - } else if (flex_basis.type == CSS::FlexBasis::Content - // FIXME: && sized under min-content or max-content contstraints - && false) { - // C - TODO(); - // Size child_box under the constraints, flex_base_size is then the resulting main_size. - } else if (flex_basis.type == CSS::FlexBasis::Content - // FIXME: && main_size is infinite && inline axis is parallel to the main axis - && false && false) { - // D - TODO(); - // Use rules for a flex_container in orthogonal flow - } else { - // E - // FIXME: This is probably too naive. - // FIXME: Care about FlexBasis::Auto - if (has_definite_main_size(child_box)) { - flex_item.flex_base_size = specified_main_size_of_child_box(flex_container, child_box); - } else { - flex_item.flex_base_size = layout_for_maximum_main_size(child_box); - } - } - auto clamp_min = has_main_min_size(child_box) - ? specified_main_min_size(child_box) - : 0; - auto clamp_max = has_main_max_size(child_box) - ? specified_main_max_size(child_box) - : NumericLimits<float>::max(); - - flex_item.hypothetical_main_size = clamp(flex_item.flex_base_size, clamp_min, clamp_max); + determine_flex_base_size_and_hypothetical_main_size(flex_container, flex_item); } // 4. Determine the main size of the flex container @@ -908,4 +829,90 @@ FlexFormattingContext::AvailableSpace FlexFormattingContext::determine_available return AvailableSpace { .main = main_available_space, .cross = cross_available_space }; } +float FlexFormattingContext::layout_for_maximum_main_size(Box& box) +{ + bool main_constrained = false; + if (is_row_layout()) { + if (!box.computed_values().width().is_undefined_or_auto() || !box.computed_values().min_width().is_undefined_or_auto()) { + main_constrained = true; + } + } else { + if (!box.computed_values().height().is_undefined_or_auto() || !box.computed_values().min_height().is_undefined_or_auto()) { + main_constrained = true; + } + } + + if (!main_constrained && box.children_are_inline()) { + auto& block_container = verify_cast<BlockContainer>(box); + BlockFormattingContext bfc(block_container, this); + bfc.run(box, LayoutMode::Default); + InlineFormattingContext ifc(block_container, &bfc); + + if (is_row_layout()) { + ifc.run(box, LayoutMode::OnlyRequiredLineBreaks); + return box.width(); + } else { + ifc.run(box, LayoutMode::AllPossibleLineBreaks); + return box.height(); + } + } + if (is_row_layout()) { + layout_inside(box, LayoutMode::OnlyRequiredLineBreaks); + return box.width(); + } else { + return BlockFormattingContext::compute_theoretical_height(box); + } +} + +// https://www.w3.org/TR/css-flexbox-1/#algo-main-item +void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(Box const& flex_container, FlexItem& flex_item) +{ + auto& child_box = flex_item.box; + auto const& flex_basis = child_box.computed_values().flex_basis(); + if (flex_basis.type == CSS::FlexBasis::Length) { + // A + auto specified_base_size = get_pixel_size(child_box, flex_basis.length); + if (specified_base_size == 0) + flex_item.flex_base_size = calculated_main_size(flex_item.box); + else + flex_item.flex_base_size = specified_base_size; + } else if (flex_basis.type == CSS::FlexBasis::Content + && has_definite_cross_size(child_box) + // FIXME: && has intrinsic aspect ratio. + && false) { + // B + TODO(); + // flex_base_size is calculated from definite cross size and intrinsic aspect ratio + } else if (flex_basis.type == CSS::FlexBasis::Content + // FIXME: && sized under min-content or max-content contstraints + && false) { + // C + TODO(); + // Size child_box under the constraints, flex_base_size is then the resulting main_size. + } else if (flex_basis.type == CSS::FlexBasis::Content + // FIXME: && main_size is infinite && inline axis is parallel to the main axis + && false && false) { + // D + TODO(); + // Use rules for a flex_container in orthogonal flow + } else { + // E + // FIXME: This is probably too naive. + // FIXME: Care about FlexBasis::Auto + if (has_definite_main_size(child_box)) { + flex_item.flex_base_size = specified_main_size_of_child_box(flex_container, child_box); + } else { + flex_item.flex_base_size = layout_for_maximum_main_size(child_box); + } + } + auto clamp_min = has_main_min_size(child_box) + ? specified_main_min_size(child_box) + : 0; + auto clamp_max = has_main_max_size(child_box) + ? specified_main_max_size(child_box) + : NumericLimits<float>::max(); + + flex_item.hypothetical_main_size = clamp(flex_item.flex_base_size, clamp_min, clamp_max); +} + } diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index 9a4a864d3f..ff6c1ac76e 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -56,6 +56,9 @@ private: }; AvailableSpace determine_available_main_and_cross_space(Box const& flex_container, bool& main_size_is_infinite, bool& main_is_constrained, bool& cross_is_constrained, float& main_min_size, float& main_max_size, float& cross_min_size, float& cross_max_size) const; + float layout_for_maximum_main_size(Box&); + void determine_flex_base_size_and_hypothetical_main_size(Box const& flex_container, FlexItem&); + bool is_row_layout() const { return m_flex_direction == CSS::FlexDirection::Row || m_flex_direction == CSS::FlexDirection::RowReverse; } CSS::FlexDirection m_flex_direction {}; |