[LFC][BFC] Introduce VerticalMargin and HorizontalMargin types.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Dec 2018 15:22:02 +0000 (15:22 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Dec 2018 15:22:02 +0000 (15:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192692

Reviewed by Antti Koivisto.

This is in preparation for completing block margin collapsing.

* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue):
(WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue):
* layout/LayoutState.cpp:
(WebCore::Layout::LayoutState::LayoutState):
* layout/LayoutUnits.h:
(WebCore::Layout::HeightAndMargin::usedMarginValues const): Deleted.
* layout/MarginTypes.h: Added.
(WebCore::Layout::VerticalMargin::nonCollapsedValues const):
(WebCore::Layout::VerticalMargin::collapsedValues const):
(WebCore::Layout::VerticalMargin::setCollapsedValues):
(WebCore::Layout::VerticalMargin::VerticalMargin):
(WebCore::Layout::VerticalMargin::usedValues const):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
* layout/blockformatting/BlockFormattingContextQuirks.cpp:
(WebCore::Layout::BlockFormattingContext::Quirks::stretchedHeight):
* layout/displaytree/DisplayBox.cpp:
(WebCore::Display::Box::Box):
* layout/displaytree/DisplayBox.h:
(WebCore::Display::Box::setHorizontalMargin):
(WebCore::Display::Box::setVerticalMargin):
(WebCore::Display::Box::setHorizontalNonComputedMargin):
(WebCore::Display::Box::verticalMargin const):
(WebCore::Display::Box::marginTop const):
(WebCore::Display::Box::marginLeft const):
(WebCore::Display::Box::marginBottom const):
(WebCore::Display::Box::marginRight const):
(WebCore::Display::Box::nonCollapsedMarginTop const):
(WebCore::Display::Box::nonCollapsedMarginBottom const):
(WebCore::Display::Box::setVerticalNonCollapsedMargin): Deleted.
* layout/floats/FloatingContext.cpp:
(WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeHeightAndMargin const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239205 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/FormattingContext.cpp
Source/WebCore/layout/FormattingContext.h
Source/WebCore/layout/FormattingContextGeometry.cpp
Source/WebCore/layout/LayoutState.cpp
Source/WebCore/layout/LayoutUnits.h
Source/WebCore/layout/MarginTypes.h [new file with mode: 0644]
Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp
Source/WebCore/layout/displaytree/DisplayBox.cpp
Source/WebCore/layout/displaytree/DisplayBox.h
Source/WebCore/layout/floats/FloatingContext.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

index 955671a..3bb109f 100644 (file)
@@ -1,3 +1,59 @@
+2018-12-14  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Introduce VerticalMargin and HorizontalMargin types.
+        https://bugs.webkit.org/show_bug.cgi?id=192692
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for completing block margin collapsing.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue):
+        (WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue):
+        * layout/LayoutState.cpp:
+        (WebCore::Layout::LayoutState::LayoutState):
+        * layout/LayoutUnits.h:
+        (WebCore::Layout::HeightAndMargin::usedMarginValues const): Deleted.
+        * layout/MarginTypes.h: Added.
+        (WebCore::Layout::VerticalMargin::nonCollapsedValues const):
+        (WebCore::Layout::VerticalMargin::collapsedValues const):
+        (WebCore::Layout::VerticalMargin::setCollapsedValues):
+        (WebCore::Layout::VerticalMargin::VerticalMargin):
+        (WebCore::Layout::VerticalMargin::usedValues const):
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+        * layout/blockformatting/BlockFormattingContextQuirks.cpp:
+        (WebCore::Layout::BlockFormattingContext::Quirks::stretchedHeight):
+        * layout/displaytree/DisplayBox.cpp:
+        (WebCore::Display::Box::Box):
+        * layout/displaytree/DisplayBox.h:
+        (WebCore::Display::Box::setHorizontalMargin):
+        (WebCore::Display::Box::setVerticalMargin):
+        (WebCore::Display::Box::setHorizontalNonComputedMargin):
+        (WebCore::Display::Box::verticalMargin const):
+        (WebCore::Display::Box::marginTop const):
+        (WebCore::Display::Box::marginLeft const):
+        (WebCore::Display::Box::marginBottom const):
+        (WebCore::Display::Box::marginRight const):
+        (WebCore::Display::Box::nonCollapsedMarginTop const):
+        (WebCore::Display::Box::nonCollapsedMarginBottom const):
+        (WebCore::Display::Box::setVerticalNonCollapsedMargin): Deleted.
+        * layout/floats/FloatingContext.cpp:
+        (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeHeightAndMargin const):
+
 2018-12-14  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [Win][Clang] Fix compilation warnings under Source/WebCore/platform/win
index edeb4a8..ea4e41b 100644 (file)
                6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingContextGeometry.cpp; sourceTree = "<group>"; };
                6FE198132178397B00446F08 /* InlineLineBreaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineBreaker.cpp; sourceTree = "<group>"; };
                6FE198152178397C00446F08 /* InlineLineBreaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineBreaker.h; sourceTree = "<group>"; };
+               6FE7AA2621C37B6300296DCD /* MarginTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MarginTypes.h; sourceTree = "<group>"; };
                6FE7CFA02177EEF1005B1573 /* InlineItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineItem.h; sourceTree = "<group>"; };
                6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutLineBreakBox.h; sourceTree = "<group>"; };
                6FE7CFA52177F069005B1573 /* LayoutLineBreakBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutLineBreakBox.cpp; sourceTree = "<group>"; };
                                6F7CA3C5208C2956002F29AB /* LayoutState.cpp */,
                                6F7CA3C4208C2956002F29AB /* LayoutState.h */,
                                6F73918C2106CEDD006AF262 /* LayoutUnits.h */,
+                               6FE7AA2621C37B6300296DCD /* MarginTypes.h */,
                                11FF02D520BA3C810083F25B /* Verification.cpp */,
                        );
                        path = layout;
                                D0D8648E21B70676003C983C /* WebGPUBuffer.idl */,
                                D0D8648221B61727003C983C /* WebGPUBufferDescriptor.h */,
                                D0D8648321B61727003C983C /* WebGPUBufferDescriptor.idl */,
-                               D063AE4E21C0810A000E6A35 /* WebGPUBufferUsage.h */,
                                D063AE3F21C05DDD000E6A35 /* WebGPUBufferUsage.h */,
-                               D063AE4C21C07AB5000E6A35 /* WebGPUBufferUsage.idl */,
                                D063AE4021C05DDD000E6A35 /* WebGPUBufferUsage.idl */,
                                D001D9AC21B0C81A0023B9BC /* WebGPUColor.h */,
                                D001D9AD21B0C81A0023B9BC /* WebGPUColor.idl */,
index d33d37e..81dda8c 100644 (file)
@@ -116,12 +116,11 @@ void FormattingContext::computeOutOfFlowVerticalGeometry(const Box& layoutBox) c
 
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     // Margins of absolutely positioned boxes do not collapse
-    ASSERT(!verticalGeometry.heightAndMargin.collapsedMargin);
-    auto nonCollapsedVerticalMargins = verticalGeometry.heightAndMargin.usedMarginValues();
+    ASSERT(!verticalGeometry.heightAndMargin.margin.collapsedValues());
+    auto nonCollapsedVerticalMargins = verticalGeometry.heightAndMargin.margin.nonCollapsedValues();
     displayBox.setTop(verticalGeometry.top + nonCollapsedVerticalMargins.top);
     displayBox.setContentBoxHeight(verticalGeometry.heightAndMargin.height);
-    displayBox.setVerticalMargin(nonCollapsedVerticalMargins);
-    displayBox.setVerticalNonCollapsedMargin(nonCollapsedVerticalMargins);
+    displayBox.setVerticalMargin(verticalGeometry.heightAndMargin.margin);
 }
 
 void FormattingContext::computeBorderAndPadding(const Box& layoutBox) const
index 4f65e56..50b3863 100644 (file)
@@ -96,8 +96,8 @@ protected:
         static Edges computedBorder(const LayoutState&, const Box&);
         static std::optional<Edges> computedPadding(const LayoutState&, const Box&);
 
-        static HorizontalEdges computedNonCollapsedHorizontalMarginValue(const LayoutState&, const Box&);
-        static VerticalEdges computedNonCollapsedVerticalMarginValue(const LayoutState&, const Box&);
+        static HorizontalMargin computedNonCollapsedHorizontalMarginValue(const LayoutState&, const Box&);
+        static VerticalMargin::ComputedValues computedNonCollapsedVerticalMarginValue(const LayoutState&, const Box&);
 
         static std::optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth);
         static std::optional<LayoutUnit> fixedValue(const Length& geometryProperty);
index c99071e..d1fe88e 100644 (file)
@@ -356,7 +356,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeomet
     ASSERT(marginBottom);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << *marginTop << "px, "  << *marginBottom << "px) layoutBox(" << &layoutBox << ")");
-    return { *top, *bottom, { *height, { *marginTop, *marginBottom }, { } } };
+    return { *top, *bottom, { *height, { { *marginTop, *marginBottom }, { } } } };
 }
 
 HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedWidth)
@@ -571,7 +571,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(
         bottom = containingBlockHeight - (*top + *marginTop + borderTop + paddingTop + height + paddingBottom + borderBottom + *marginBottom); 
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << *marginTop << "px, "  << *marginBottom << "px) layoutBox(" << &layoutBox << ")");
-    return { *top, *bottom, { height, { *marginTop, *marginBottom }, { } } };
+    return { *top, *bottom, { height, { { *marginTop, *marginBottom }, { } } } };
 }
 
 HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedWidth)
@@ -710,7 +710,7 @@ HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutState&
     ASSERT(marginBottom);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating non-replaced -> height(" << *height << "px) margin(" << *marginTop << "px, " << *marginBottom << "px) -> layoutBox(" << &layoutBox << ")");
-    return HeightAndMargin { *height, { *marginTop, *marginBottom }, { } };
+    return HeightAndMargin { *height, { { *marginTop, *marginBottom }, { } } };
 }
 
 WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedWidth)
@@ -838,7 +838,7 @@ HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const
     ASSERT(height);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow replaced -> height(" << *height << "px) margin(" << margin.top << "px, " << margin.bottom << "px) -> layoutBox(" << &layoutBox << ")");
-    return { *height, margin, { } };
+    return { *height, { margin, { } } };
 }
 
 WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const LayoutState& layoutState, const Box& layoutBox,
@@ -1020,7 +1020,7 @@ std::optional<Edges> FormattingContext::Geometry::computedPadding(const LayoutSt
     };
 }
 
-HorizontalEdges FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue(const LayoutState& layoutState, const Box& layoutBox)
+HorizontalMargin FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue(const LayoutState& layoutState, const Box& layoutBox)
 {
     auto& style = layoutBox.style();
     auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
@@ -1032,7 +1032,7 @@ HorizontalEdges FormattingContext::Geometry::computedNonCollapsedHorizontalMargi
     return { marginLeft, marginRight };
 }
 
-VerticalEdges FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(const LayoutState& layoutState, const Box& layoutBox)
+VerticalMargin::ComputedValues FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(const LayoutState& layoutState, const Box& layoutBox)
 {
     auto& style = layoutBox.style();
     auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
index 832f4e8..cc1dbc0 100644 (file)
@@ -56,7 +56,6 @@ LayoutState::LayoutState(const Container& initialContainingBlock, const LayoutSi
     displayBox.setHorizontalMargin({ });
     displayBox.setHorizontalNonComputedMargin({ });
     displayBox.setVerticalMargin({ });
-    displayBox.setVerticalNonCollapsedMargin({ });
     displayBox.setBorder({ });
     displayBox.setPadding({ });
     displayBox.setTopLeft({ });
index 3e1d844..d76b6a3 100644 (file)
@@ -30,6 +30,7 @@
 #include "LayoutUnit.h"
 #include "LayoutPoint.h"
 #include "LayoutRect.h"
+#include "MarginTypes.h"
 #include <wtf/Optional.h>
 
 namespace WebCore {
@@ -102,16 +103,14 @@ struct Edges {
 
 struct WidthAndMargin {
     LayoutUnit width;
-    HorizontalEdges margin;
-    HorizontalEdges nonComputedMargin;
+    HorizontalMargin margin;
+    // FIXME: Figure out if we really really need this.
+    HorizontalMargin nonComputedMargin;
 };
 
 struct HeightAndMargin {
-    VerticalEdges usedMarginValues() const { return collapsedMargin.value_or(nonCollapsedMargin); }
-
     LayoutUnit height;
-    VerticalEdges nonCollapsedMargin;
-    std::optional<VerticalEdges> collapsedMargin;
+    VerticalMargin margin;
 };
 
 struct HorizontalGeometry {
diff --git a/Source/WebCore/layout/MarginTypes.h b/Source/WebCore/layout/MarginTypes.h
new file mode 100644 (file)
index 0000000..7146e22
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include <wtf/Optional.h>
+
+namespace WebCore {
+namespace Layout {
+
+struct VerticalMargin {
+    struct ComputedValues {
+        LayoutUnit top;
+        LayoutUnit bottom;
+    };
+    ComputedValues usedValues() const;
+    ComputedValues nonCollapsedValues() const { return m_nonCollapsed; }
+    
+    struct CollapsedValues {
+        std::optional<LayoutUnit> top;
+        std::optional<LayoutUnit> bottom;
+    };
+    std::optional<CollapsedValues> collapsedValues() const { return m_collapsed; }
+    void setCollapsedValues(CollapsedValues collapsedValues) { m_collapsed = collapsedValues; }
+
+    VerticalMargin(ComputedValues nonCollapsed, std::optional<CollapsedValues>);
+
+    VerticalMargin() = default;
+    ~VerticalMargin() = default;
+private:
+    ComputedValues m_nonCollapsed;
+    std::optional<CollapsedValues> m_collapsed;
+};
+
+struct HorizontalMargin {
+    LayoutUnit left;
+    LayoutUnit right;
+};
+
+struct PositiveAndNegativeVerticalMargin {
+    struct Values {
+        std::optional<LayoutUnit> positive;
+        std::optional<LayoutUnit> negative;
+    };
+    Values top;
+    Values bottom;
+};
+
+inline VerticalMargin::VerticalMargin(VerticalMargin::ComputedValues nonCollapsed, std::optional<VerticalMargin::CollapsedValues> collapsed)
+    : m_nonCollapsed(nonCollapsed)
+    , m_collapsed(collapsed)
+{
+}
+
+inline VerticalMargin::ComputedValues VerticalMargin::usedValues() const
+{
+    if (!m_collapsed)
+        return m_nonCollapsed;
+    return { m_collapsed->top.value_or(m_nonCollapsed.top),
+        m_collapsed->bottom.value_or(m_nonCollapsed.bottom) };
+}
+
+}
+}
+#endif
index a12d10f..1e36cba 100644 (file)
@@ -358,7 +358,7 @@ void BlockFormattingContext::computeHeightAndMargin(const Box& layoutBox) const
             auto maxHeightAndMargin = compute(maxHeight);
             // Used height should remain the same.
             ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.height == *maxHeight);
-            heightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin, maxHeightAndMargin.collapsedMargin };
+            heightAndMargin = { *maxHeight, maxHeightAndMargin.margin };
         }
     }
 
@@ -367,18 +367,17 @@ void BlockFormattingContext::computeHeightAndMargin(const Box& layoutBox) const
             auto minHeightAndMargin = compute(minHeight);
             // Used height should remain the same.
             ASSERT((layoutState.inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.height == *minHeight);
-            heightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin, minHeightAndMargin.collapsedMargin };
+            heightAndMargin = { *minHeight, minHeightAndMargin.margin };
         }
     }
 
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     displayBox.setContentBoxHeight(heightAndMargin.height);
-    displayBox.setVerticalNonCollapsedMargin(heightAndMargin.nonCollapsedMargin);
-    displayBox.setVerticalMargin(heightAndMargin.usedMarginValues());
+    displayBox.setVerticalMargin(heightAndMargin.margin);
 
     // If this box has already been moved by the estimated vertical margin, no need to move it again.
     if (layoutBox.isFloatingPositioned() || !displayBox.estimatedMarginTop())
-        displayBox.moveVertically(heightAndMargin.usedMarginValues().top);
+        displayBox.moveVertically(heightAndMargin.margin.usedValues().top);
 }
 
 FormattingContext::InstrinsicWidthConstraints BlockFormattingContext::instrinsicWidthConstraints() const
index 3b09f30..ebe1a22 100644 (file)
@@ -61,24 +61,24 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg
         auto containingBlockWidth = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
         auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
 
-        VerticalEdges nonCollapsedMargin = { computedValueIfNotAuto(style.marginTop(), containingBlockWidth).value_or(0),
+        auto nonCollapsedMargin = VerticalMargin::ComputedValues { computedValueIfNotAuto(style.marginTop(), containingBlockWidth).value_or(0),
             computedValueIfNotAuto(style.marginBottom(), containingBlockWidth).value_or(0) }; 
-        VerticalEdges collapsedMargin = { MarginCollapse::marginTop(layoutState, layoutBox), MarginCollapse::marginBottom(layoutState, layoutBox) };
+        auto collapsedMargin = VerticalMargin::CollapsedValues { MarginCollapse::marginTop(layoutState, layoutBox), MarginCollapse::marginBottom(layoutState, layoutBox) };
         auto borderAndPaddingTop = displayBox.borderTop() + displayBox.paddingTop().value_or(0);
-        
+
         auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
         if (height)
-            return { height.value(), nonCollapsedMargin, collapsedMargin };
+            return { height.value(), { nonCollapsedMargin, collapsedMargin } };
 
         if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
-            return { 0, nonCollapsedMargin, collapsedMargin };
+            return { 0, { nonCollapsedMargin, collapsedMargin } };
 
         // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
         if (layoutBox.establishesInlineFormattingContext()) {
             // This is temp and will be replaced by the correct display box once inline runs move over to the display tree.
             auto& inlineRuns = downcast<InlineFormattingState>(layoutState.establishedFormattingState(layoutBox)).inlineRuns();
             auto bottomEdge = inlineRuns.isEmpty() ? LayoutUnit() : inlineRuns.last().logicalBottom();
-            return { bottomEdge, nonCollapsedMargin, collapsedMargin };
+            return { bottomEdge, { nonCollapsedMargin, collapsedMargin } };
         }
 
         // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
@@ -86,7 +86,7 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg
         ASSERT(lastInFlowChild);
         if (!MarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
             auto& lastInFlowDisplayBox = layoutState.displayBoxForLayoutBox(*lastInFlowChild);
-            return { lastInFlowDisplayBox.bottom() + lastInFlowDisplayBox.marginBottom() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
+            return { lastInFlowDisplayBox.bottom() + lastInFlowDisplayBox.marginBottom() - borderAndPaddingTop, { nonCollapsedMargin, collapsedMargin } };
         }
 
         // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
@@ -95,16 +95,16 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg
             inFlowChild = inFlowChild->previousInFlowSibling();
         if (inFlowChild) {
             auto& inFlowDisplayBox = layoutState.displayBoxForLayoutBox(*inFlowChild);
-            return { inFlowDisplayBox.top() + inFlowDisplayBox.borderBox().height() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
+            return { inFlowDisplayBox.top() + inFlowDisplayBox.borderBox().height() - borderAndPaddingTop, { nonCollapsedMargin, collapsedMargin } };
         }
 
         // 4. zero, otherwise
-        return { 0, nonCollapsedMargin, collapsedMargin };
+        return { 0, { nonCollapsedMargin, collapsedMargin } };
     };
 
     auto heightAndMargin = compute();
 
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.usedMarginValues().top << "px, " << heightAndMargin.usedMarginValues().bottom << "px) -> layoutBox(" << &layoutBox << ")");
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.usedValues().top << "px, " << heightAndMargin.margin.usedValues().bottom << "px) -> layoutBox(" << &layoutBox << ")");
     return heightAndMargin;
 }
 
@@ -263,7 +263,7 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const La
 
     heightAndMargin = Quirks::stretchedHeight(layoutState, layoutBox, heightAndMargin);
 
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.usedMarginValues().top << "px, " << heightAndMargin.usedMarginValues().bottom << "px) -> layoutBox(" << &layoutBox << ")");
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.usedValues().top << "px, " << heightAndMargin.margin.usedValues().bottom << "px) -> layoutBox(" << &layoutBox << ")");
     return heightAndMargin;
 }
 
index b8f018a..a19a608 100644 (file)
@@ -80,9 +80,9 @@ HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutStat
 
     LayoutUnit totalVerticalMargins;
     if (layoutBox.isDocumentBox()) {
-        auto verticalMargins = heightAndMargin.usedMarginValues();
+        auto verticalMargins = heightAndMargin.margin.usedValues();
         // Document box's margins do not collapse.
-        ASSERT(!heightAndMargin.collapsedMargin);
+        ASSERT(!heightAndMargin.margin.collapsedValues());
         totalVerticalMargins = verticalMargins.top + verticalMargins.bottom;
     } else if (layoutBox.isBodyBox()) {
         // Here is the quirky part for body box:
@@ -93,7 +93,7 @@ HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutStat
 
         // This quirk happens when the body height is 0 which means its vertical margins collapse through (top and bottom margins are adjoining).
         // However now that we stretch the body they don't collapse through anymore, so we need to use the non-collapsed values instead.
-        auto bodyBoxVerticalMargins = heightAndMargin.height ? heightAndMargin.usedMarginValues() : heightAndMargin.nonCollapsedMargin;
+        auto bodyBoxVerticalMargins = heightAndMargin.height ? heightAndMargin.margin.usedValues() : heightAndMargin.margin.nonCollapsedValues();
         totalVerticalMargins = bodyBoxVerticalMargins.top + bodyBoxVerticalMargins.bottom;
     }
 
index 1534793..65bc0f0 100644 (file)
@@ -57,8 +57,8 @@ Box::Box(const Box& other)
     , m_topLeft(other.m_topLeft)
     , m_contentWidth(other.m_contentWidth)
     , m_contentHeight(other.m_contentHeight)
-    , m_margin(other.m_margin)
-    , m_verticalNonCollapsedMargin(other.m_verticalNonCollapsedMargin)
+    , m_horizontalMargin(other.m_horizontalMargin)
+    , m_verticalMargin(other.m_verticalMargin)
     , m_horizontalNonComputedMargin(other.m_horizontalNonComputedMargin)
     , m_estimatedMarginTop(other.m_estimatedMarginTop)
     , m_border(other.m_border)
index 62a3992..e49de3c 100644 (file)
@@ -138,6 +138,7 @@ public:
     Rect rect() const { return { top(), left(), width(), height() }; }
     Rect rectWithMargin() const { return { top() - marginTop(), left() - marginLeft(), marginLeft() + width() + marginRight(), marginTop() + height() + marginBottom() }; }
 
+    Layout::VerticalMargin verticalMargin() const;
     LayoutUnit marginTop() const;
     LayoutUnit marginLeft() const;
     LayoutUnit marginBottom() const;
@@ -190,10 +191,9 @@ private:
     void setContentBoxHeight(LayoutUnit);
     void setContentBoxWidth(LayoutUnit);
 
-    void setHorizontalMargin(Layout::HorizontalEdges);
-    void setVerticalMargin(Layout::VerticalEdges);
-    void setVerticalNonCollapsedMargin(Layout::VerticalEdges);
-    void setHorizontalNonComputedMargin(Layout::HorizontalEdges);
+    void setHorizontalMargin(Layout::HorizontalMargin);
+    void setVerticalMargin(Layout::VerticalMargin);
+    void setHorizontalNonComputedMargin(Layout::HorizontalMargin);
     void setEstimatedMarginTop(LayoutUnit marginTop) { m_estimatedMarginTop = marginTop; }
 
     void setBorder(Layout::Edges);
@@ -224,9 +224,9 @@ private:
     LayoutUnit m_contentWidth;
     LayoutUnit m_contentHeight;
 
-    Layout::Edges m_margin;
-    Layout::VerticalEdges m_verticalNonCollapsedMargin;
-    Layout::HorizontalEdges m_horizontalNonComputedMargin;
+    Layout::HorizontalMargin m_horizontalMargin;
+    Layout::VerticalMargin m_verticalMargin;
+    Layout::HorizontalMargin m_horizontalNonComputedMargin;
     std::optional<LayoutUnit> m_estimatedMarginTop;
 
     Layout::Edges m_border;
@@ -507,32 +507,25 @@ inline LayoutUnit Box::contentBoxWidth() const
     return m_contentWidth;
 }
 
-inline void Box::setHorizontalMargin(Layout::HorizontalEdges margin)
+inline void Box::setHorizontalMargin(Layout::HorizontalMargin margin)
 {
 #if !ASSERT_DISABLED
     setHasValidHorizontalMargin();
 #endif
-    m_margin.horizontal = margin;
+    m_horizontalMargin = margin;
 }
 
-inline void Box::setVerticalMargin(Layout::VerticalEdges margin)
+inline void Box::setVerticalMargin(Layout::VerticalMargin margin)
 {
 #if !ASSERT_DISABLED
     setHasValidVerticalMargin();
-#endif
-    ASSERT(!m_estimatedMarginTop || *m_estimatedMarginTop == margin.top);
-    m_margin.vertical = margin;
-}
-
-inline void Box::setVerticalNonCollapsedMargin(Layout::VerticalEdges margin)
-{
-#if !ASSERT_DISABLED
     setHasValidVerticalNonCollapsedMargin();
 #endif
-    m_verticalNonCollapsedMargin = margin;
+    ASSERT(!m_estimatedMarginTop || *m_estimatedMarginTop == margin.usedValues().top);
+    m_verticalMargin = margin;
 }
 
-inline void Box::setHorizontalNonComputedMargin(Layout::HorizontalEdges margin)
+inline void Box::setHorizontalNonComputedMargin(Layout::HorizontalMargin margin)
 {
 #if !ASSERT_DISABLED
     setHasValidHorizontalNonComputedMargin();
@@ -556,40 +549,46 @@ inline void Box::setPadding(std::optional<Layout::Edges> padding)
     m_padding = padding;
 }
 
+inline Layout::VerticalMargin Box::verticalMargin() const
+{
+    ASSERT(m_hasValidVerticalMargin);
+    return m_verticalMargin;
+}
+
 inline LayoutUnit Box::marginTop() const
 {
     ASSERT(m_hasValidVerticalMargin);
-    return m_margin.vertical.top;
+    return m_verticalMargin.usedValues().top;
 }
 
 inline LayoutUnit Box::marginLeft() const
 {
     ASSERT(m_hasValidHorizontalMargin);
-    return m_margin.horizontal.left;
+    return m_horizontalMargin.left;
 }
 
 inline LayoutUnit Box::marginBottom() const
 {
     ASSERT(m_hasValidVerticalMargin);
-    return m_margin.vertical.bottom;
+    return m_verticalMargin.usedValues().bottom;
 }
 
 inline LayoutUnit Box::marginRight() const
 {
     ASSERT(m_hasValidHorizontalMargin);
-    return m_margin.horizontal.right;
+    return m_horizontalMargin.right;
 }
 
 inline LayoutUnit Box::nonCollapsedMarginTop() const
 {
     ASSERT(m_hasValidVerticalNonCollapsedMargin);
-    return m_verticalNonCollapsedMargin.top;
+    return m_verticalMargin.nonCollapsedValues().top;
 }
 
 inline LayoutUnit Box::nonCollapsedMarginBottom() const
 {
     ASSERT(m_hasValidVerticalNonCollapsedMargin);
-    return m_verticalNonCollapsedMargin.bottom;
+    return m_verticalMargin.nonCollapsedValues().bottom;
 }
 
 inline LayoutUnit Box::nonComputedMarginLeft() const
index 8142342..2753194 100644 (file)
@@ -192,8 +192,17 @@ std::optional<Position> FloatingContext::verticalPositionWithClearance(const Box
             auto collapsedMargin = displayBox.marginTop();
 
             // Reset previous bottom and current top margins to non-collapsing.
-            previousInFlowDisplayBox.setVerticalMargin({ previousInFlowDisplayBox.marginTop(), previousInFlowDisplayBox.nonCollapsedMarginBottom() });
-            displayBox.setVerticalMargin({ displayBox.nonCollapsedMarginTop(), displayBox.marginBottom() });
+            auto previousVerticalMargin = previousInFlowDisplayBox.verticalMargin();
+            if (previousVerticalMargin.collapsedValues() && previousVerticalMargin.collapsedValues()->bottom) {
+                previousVerticalMargin.setCollapsedValues({ previousVerticalMargin.collapsedValues()->top, { } });
+                previousInFlowDisplayBox.setVerticalMargin(previousVerticalMargin);
+            }
+            // FIXME: check if collapsing through has anything to do with this.
+            auto verticalMargin = displayBox.verticalMargin();
+            if (verticalMargin.collapsedValues() && verticalMargin.collapsedValues()->top) {
+                verticalMargin.setCollapsedValues({ { }, verticalMargin.collapsedValues()->bottom });
+                displayBox.setVerticalMargin(verticalMargin);
+            }
 
             auto nonCollapsedMargin = previousInFlowDisplayBox.marginBottom() + displayBox.marginTop();
             auto marginOffset = nonCollapsedMargin - collapsedMargin;
index f872527..c7ad9c5 100644 (file)
@@ -362,8 +362,7 @@ void InlineFormattingContext::computeHeightAndMargin(const Box& layoutBox) const
 
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     displayBox.setContentBoxHeight(heightAndMargin.height);
-    displayBox.setVerticalNonCollapsedMargin(heightAndMargin.nonCollapsedMargin);
-    displayBox.setVerticalMargin(heightAndMargin.usedMarginValues());
+    displayBox.setVerticalMargin(heightAndMargin.margin);
 }
 
 void InlineFormattingContext::layoutFormattingContextRoot(const Box& root) const