Browse Source

LibWeb/Layout: Simplified margin collapsing

Rather than accumulating margins into a vector, and then looping through
them when resolving the margin, it's much simpler to just update two
fields, and sum them when resolving.
Jeremia Dominguez 9 months ago
parent
commit
eafa70331d

+ 1 - 23
Libraries/LibWeb/Layout/BlockFormattingContext.cpp

@@ -864,29 +864,7 @@ void BlockFormattingContext::resolve_vertical_box_model_metrics(Box const& box,
 
 
 CSSPixels BlockFormattingContext::BlockMarginState::current_collapsed_margin() const
 CSSPixels BlockFormattingContext::BlockMarginState::current_collapsed_margin() const
 {
 {
-    CSSPixels smallest_margin = 0;
-    CSSPixels largest_margin = 0;
-    size_t negative_margin_count = 0;
-    for (auto margin : current_collapsible_margins) {
-        if (margin < 0)
-            ++negative_margin_count;
-        largest_margin = max(largest_margin, margin);
-        smallest_margin = min(smallest_margin, margin);
-    }
-
-    CSSPixels collapsed_margin = 0;
-    if (negative_margin_count == current_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;
-    }
-
-    return collapsed_margin;
+    return current_positive_collapsible_margin + current_negative_collapsible_margin;
 }
 }
 
 
 BlockFormattingContext::DidIntroduceClearance BlockFormattingContext::clear_floating_boxes(Node const& child_box, Optional<InlineFormattingContext&> inline_formatting_context)
 BlockFormattingContext::DidIntroduceClearance BlockFormattingContext::clear_floating_boxes(Node const& child_box, Optional<InlineFormattingContext&> inline_formatting_context)

+ 9 - 3
Libraries/LibWeb/Layout/BlockFormattingContext.h

@@ -126,13 +126,18 @@ private:
     };
     };
 
 
     struct BlockMarginState {
     struct BlockMarginState {
-        Vector<CSSPixels> current_collapsible_margins;
+        CSSPixels current_positive_collapsible_margin;
+        CSSPixels current_negative_collapsible_margin;
         Function<void(CSSPixels)> block_container_y_position_update_callback;
         Function<void(CSSPixels)> block_container_y_position_update_callback;
         bool box_last_in_flow_child_margin_bottom_collapsed { false };
         bool box_last_in_flow_child_margin_bottom_collapsed { false };
 
 
         void add_margin(CSSPixels margin)
         void add_margin(CSSPixels margin)
         {
         {
-            current_collapsible_margins.append(margin);
+            if (margin < 0) {
+                current_negative_collapsible_margin = min(margin, current_negative_collapsible_margin);
+            } else {
+                current_positive_collapsible_margin = max(margin, current_positive_collapsible_margin);
+            }
         }
         }
 
 
         void register_block_container_y_position_update_callback(ESCAPING Function<void(CSSPixels)> callback)
         void register_block_container_y_position_update_callback(ESCAPING Function<void(CSSPixels)> callback)
@@ -158,7 +163,8 @@ private:
         void reset()
         void reset()
         {
         {
             block_container_y_position_update_callback = {};
             block_container_y_position_update_callback = {};
-            current_collapsible_margins.clear();
+            current_negative_collapsible_margin = 0;
+            current_positive_collapsible_margin = 0;
         }
         }
     };
     };