diff options
author | Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com> | 2022-12-25 17:13:21 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-12-30 14:21:19 +0100 |
commit | fe8304d5dec3b2684ca5c77a31c7dea5384f86a7 (patch) | |
tree | c600793d001a0c4217c190df5610d3323d9988f5 /Userland/Libraries/LibWeb/Layout/FormattingContext.cpp | |
parent | e3d5b67eaf6518810f960e77bde92eec6b648eb7 (diff) | |
download | serenity-fe8304d5dec3b2684ca5c77a31c7dea5384f86a7.zip |
LibWeb: Introduce structure that maintains collapsible margins in BFC
Previously y position of boxes in block formatting context
was calculated by looking at y position of previous in-flow
sibling and adding collapsed margin of "collapse through"
boxes lying between box currently being laid out and it's
previous in-flow sibling.
Here introduced BlockMarginState structure that maintains
array of currently collapsible margins hence we no longer
need to look at previous sibling to calculate y position
of a box.
Diffstat (limited to 'Userland/Libraries/LibWeb/Layout/FormattingContext.cpp')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FormattingContext.cpp | 67 |
1 files changed, 1 insertions, 66 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 55774d67a4..9d7d685aa4 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -927,7 +927,7 @@ Gfx::FloatPoint FormattingContext::calculate_static_position(Box const& box) con } else { x = m_state.get(box).margin_box_left(); // We're among block siblings, Y can be calculated easily. - y = compute_box_y_position_with_respect_to_siblings(box); + y = m_state.get(box).margin_box_top(); } auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block(), m_state); return offset_to_static_parent.location().translated(x, y); @@ -1364,71 +1364,6 @@ float FormattingContext::containing_block_height_for(Box const& box, LayoutState VERIFY_NOT_REACHED(); } -static Box const* previous_block_level_sibling(Box const& box) -{ - for (auto* sibling = box.previous_sibling_of_type<Box>(); sibling; sibling = sibling->previous_sibling_of_type<Box>()) { - if (sibling->display().is_block_outside()) - return sibling; - } - return nullptr; -} - -float FormattingContext::compute_box_y_position_with_respect_to_siblings(Box const& box) const -{ - auto const& box_state = m_state.get(box); - float y = box_state.border_box_top(); - - Vector<float> collapsible_margins; - - auto* relevant_sibling = previous_block_level_sibling(box); - while (relevant_sibling != nullptr) { - if (!relevant_sibling->is_absolutely_positioned() && !relevant_sibling->is_floating()) { - auto const& relevant_sibling_state = m_state.get(*relevant_sibling); - collapsible_margins.append(relevant_sibling_state.margin_bottom); - // NOTE: Empty (0-height) preceding siblings have their margins collapsed with *their* preceding sibling, etc. - if (relevant_sibling_state.border_box_height() > 0) - break; - collapsible_margins.append(relevant_sibling_state.margin_top); - } - relevant_sibling = previous_block_level_sibling(*relevant_sibling); - } - - if (relevant_sibling) { - // Collapse top margin with the collapsed margin(s) of preceding siblings. - collapsible_margins.append(box_state.margin_top); - - float smallest_margin = 0; - float largest_margin = 0; - size_t negative_margin_count = 0; - for (auto margin : collapsible_margins) { - if (margin < 0) - ++negative_margin_count; - largest_margin = max(largest_margin, margin); - smallest_margin = min(smallest_margin, margin); - } - - float collapsed_margin = 0; - if (negative_margin_count == collapsible_margins.size()) { - // When all margins are negative, the size of the collapsed margin is the smallest (most negative) margin. - collapsed_margin = smallest_margin; - } else if (negative_margin_count > 0) { - // When negative margins are involved, the size of the collapsed margin is the sum of the largest positive margin and the smallest (most negative) negative margin. - collapsed_margin = largest_margin + smallest_margin; - } else { - // Otherwise, collapse all the adjacent margins by using only the largest one. - collapsed_margin = largest_margin; - } - - auto const& relevant_sibling_state = m_state.get(*relevant_sibling); - return y + relevant_sibling_state.offset.y() - + relevant_sibling_state.content_height() - + relevant_sibling_state.border_box_bottom() - + collapsed_margin; - } else { - return y + box_state.margin_top; - } -} - // https://drafts.csswg.org/css-sizing-3/#stretch-fit-size float FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const { |