Title: [232114] trunk/Source/WebCore
Revision
232114
Author
[email protected]
Date
2018-05-23 09:56:12 -0700 (Wed, 23 May 2018)

Log Message

[LFC] Move sizing/positioning logic to helper classes
https://bugs.webkit.org/show_bug.cgi?id=185898

Reviewed by Antti Koivisto.

The idea here is to move all the sizing and positioning logic to helper classes so that
the formatting context code stays lean.
This is similar to the dedicated BlockMarginCollapse class for the collapsing logic.
The helper classes have only static functions. These static functions do not mutate the associated DisplayBoxes,
but instead they simply retun the computed values.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowPosition const):
(WebCore::Layout::FormattingContext::computeOutOfFlowWidth const):
(WebCore::Layout::FormattingContext::computeFloatingWidth const):
(WebCore::Layout::FormattingContext::computeOutOfFlowHeight const):
(WebCore::Layout::FormattingContext::computeFloatingHeight const):
(WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedHeight const): Deleted.
(WebCore::Layout::FormattingContext::computeFloatingNonReplacedHeight const): Deleted.
(WebCore::Layout::FormattingContext::computeReplacedHeight const): Deleted.
(WebCore::Layout::FormattingContext::computeReplacedWidth const): Deleted.
(WebCore::Layout::FormattingContext::contentHeightForFormattingContextRoot const): Deleted.
(WebCore::Layout::FormattingContext::computeFloatingNonReplacedWidth const): Deleted.
(WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedWidth const): Deleted.
(WebCore::Layout::FormattingContext::computeOutOfFlowReplacedHeight const): Deleted.
(WebCore::Layout::FormattingContext::computeOutOfFlowReplacedWidth const): Deleted.
(WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedPosition const): Deleted.
(WebCore::Layout::FormattingContext::computeOutOfFlowReplacedPosition const): Deleted.
(WebCore::Layout::FormattingContext::shrinkToFitWidth const): Deleted.
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp: Copied from Source/WebCore/layout/FormattingContext.cpp.
(WebCore::Layout::contentHeightForFormattingContextRoot):
(WebCore::Layout::shrinkToFitWidth):
(WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedHeight):
(WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedWidth):
(WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedHeight):
(WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedWidth):
(WebCore::Layout::FormattingContextGeometry::floatingNonReplacedHeight):
(WebCore::Layout::FormattingContextGeometry::floatingNonReplacedWidth):
(WebCore::Layout::FormattingContextGeometry::floatingReplacedHeight):
(WebCore::Layout::FormattingContextGeometry::floatingReplacedWidth):
(WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedPosition):
(WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedPosition):
(WebCore::Layout::FormattingContextGeometry::replacedHeight):
(WebCore::Layout::FormattingContextGeometry::replacedWidth):
* layout/FormattingContextGeometry.h: Copied from Source/WebCore/layout/blockformatting/BlockFormattingContext.h.
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeStaticPosition const):
(WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
(WebCore::Layout::BlockFormattingContext::computeInFlowWidth const):
(WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedWidth const): Deleted.
(WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const): Deleted.
* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockFormattingContextGeometry.cpp: Added.
(WebCore::Layout::BlockFormattingContextGeometry::inFlowNonReplacedHeight):
(WebCore::Layout::BlockFormattingContextGeometry::inFlowNonReplacedWidth):
(WebCore::Layout::BlockFormattingContextGeometry::inFlowReplacedHeight):
(WebCore::Layout::BlockFormattingContextGeometry::inFlowReplacedWidth):
(WebCore::Layout::BlockFormattingContextGeometry::staticPosition):
* layout/blockformatting/BlockFormattingContextGeometry.h: Copied from Source/WebCore/layout/blockformatting/BlockFormattingContext.h.
* layout/displaytree/DisplayBox.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (232113 => 232114)


--- trunk/Source/WebCore/ChangeLog	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/ChangeLog	2018-05-23 16:56:12 UTC (rev 232114)
@@ -1,3 +1,69 @@
+2018-05-23  Zalan Bujtas  <[email protected]>
+
+        [LFC] Move sizing/positioning logic to helper classes
+        https://bugs.webkit.org/show_bug.cgi?id=185898
+
+        Reviewed by Antti Koivisto.
+
+        The idea here is to move all the sizing and positioning logic to helper classes so that
+        the formatting context code stays lean.
+        This is similar to the dedicated BlockMarginCollapse class for the collapsing logic.
+        The helper classes have only static functions. These static functions do not mutate the associated DisplayBoxes,
+        but instead they simply retun the computed values.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const):
+        (WebCore::Layout::FormattingContext::computeOutOfFlowWidth const):
+        (WebCore::Layout::FormattingContext::computeFloatingWidth const):
+        (WebCore::Layout::FormattingContext::computeOutOfFlowHeight const):
+        (WebCore::Layout::FormattingContext::computeFloatingHeight const):
+        (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedHeight const): Deleted.
+        (WebCore::Layout::FormattingContext::computeFloatingNonReplacedHeight const): Deleted.
+        (WebCore::Layout::FormattingContext::computeReplacedHeight const): Deleted.
+        (WebCore::Layout::FormattingContext::computeReplacedWidth const): Deleted.
+        (WebCore::Layout::FormattingContext::contentHeightForFormattingContextRoot const): Deleted.
+        (WebCore::Layout::FormattingContext::computeFloatingNonReplacedWidth const): Deleted.
+        (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedWidth const): Deleted.
+        (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedHeight const): Deleted.
+        (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedWidth const): Deleted.
+        (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedPosition const): Deleted.
+        (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedPosition const): Deleted.
+        (WebCore::Layout::FormattingContext::shrinkToFitWidth const): Deleted.
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp: Copied from Source/WebCore/layout/FormattingContext.cpp.
+        (WebCore::Layout::contentHeightForFormattingContextRoot):
+        (WebCore::Layout::shrinkToFitWidth):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedHeight):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedWidth):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedHeight):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedWidth):
+        (WebCore::Layout::FormattingContextGeometry::floatingNonReplacedHeight):
+        (WebCore::Layout::FormattingContextGeometry::floatingNonReplacedWidth):
+        (WebCore::Layout::FormattingContextGeometry::floatingReplacedHeight):
+        (WebCore::Layout::FormattingContextGeometry::floatingReplacedWidth):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowNonReplacedPosition):
+        (WebCore::Layout::FormattingContextGeometry::outOfFlowReplacedPosition):
+        (WebCore::Layout::FormattingContextGeometry::replacedHeight):
+        (WebCore::Layout::FormattingContextGeometry::replacedWidth):
+        * layout/FormattingContextGeometry.h: Copied from Source/WebCore/layout/blockformatting/BlockFormattingContext.h.
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeStaticPosition const):
+        (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
+        (WebCore::Layout::BlockFormattingContext::computeInFlowWidth const):
+        (WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedWidth const): Deleted.
+        (WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const): Deleted.
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp: Added.
+        (WebCore::Layout::BlockFormattingContextGeometry::inFlowNonReplacedHeight):
+        (WebCore::Layout::BlockFormattingContextGeometry::inFlowNonReplacedWidth):
+        (WebCore::Layout::BlockFormattingContextGeometry::inFlowReplacedHeight):
+        (WebCore::Layout::BlockFormattingContextGeometry::inFlowReplacedWidth):
+        (WebCore::Layout::BlockFormattingContextGeometry::staticPosition):
+        * layout/blockformatting/BlockFormattingContextGeometry.h: Copied from Source/WebCore/layout/blockformatting/BlockFormattingContext.h.
+        * layout/displaytree/DisplayBox.h:
+
 2018-05-23  Antti Koivisto  <[email protected]>
 
         Page keeps reloading when viewing photos in google drive (due to too high canvas memory limits)

Modified: trunk/Source/WebCore/Sources.txt (232113 => 232114)


--- trunk/Source/WebCore/Sources.txt	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/Sources.txt	2018-05-23 16:56:12 UTC (rev 232114)
@@ -1216,9 +1216,11 @@
 layout/FloatingContext.cpp
 layout/FloatingState.cpp
 layout/FormattingContext.cpp
+layout/FormattingContextGeometry.cpp
 layout/FormattingState.cpp
 layout/LayoutContext.cpp
 layout/blockformatting/BlockFormattingContext.cpp
+layout/blockformatting/BlockFormattingContextGeometry.cpp
 layout/blockformatting/BlockFormattingState.cpp
 layout/blockformatting/BlockMarginCollapse.cpp
 layout/blockformatting/BlockInvalidation.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (232113 => 232114)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-05-23 16:56:12 UTC (rev 232114)
@@ -8886,6 +8886,7 @@
 		6ED8C378183BFF8C009E53BD /* BoxShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoxShape.h; sourceTree = "<group>"; };
 		6EE8A77010F803F3005A4A24 /* JSWebGLContextAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLContextAttributes.cpp; sourceTree = "<group>"; };
 		6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLContextAttributes.h; sourceTree = "<group>"; };
+		6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BlockFormattingContextGeometry.cpp; sourceTree = "<group>"; };
 		6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
 		6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLVertexArrayObjectBase.cpp; sourceTree = "<group>"; };
 		6F7CA3C4208C2956002F29AB /* LayoutContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutContext.h; sourceTree = "<group>"; };
@@ -8917,6 +8918,7 @@
 		6F995A2E1A70833700A735F4 /* JSWebGLTransformFeedback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLTransformFeedback.h; sourceTree = "<group>"; };
 		6F995A2F1A70833700A735F4 /* JSWebGLVertexArrayObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLVertexArrayObject.cpp; sourceTree = "<group>"; };
 		6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLVertexArrayObject.h; sourceTree = "<group>"; };
+		6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingContextGeometry.cpp; sourceTree = "<group>"; };
 		709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleFetchFailureKind.h; sourceTree = "<group>"; };
 		71004B9D1DC1398800A52A38 /* playback-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "playback-support.js"; sourceTree = "<group>"; };
 		71025EC21F99F096004A250C /* WebAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAnimation.h; sourceTree = "<group>"; };
@@ -15678,6 +15680,7 @@
 				115CFA80208B8EDA001E6991 /* FloatingState.h */,
 				115CFA69208AF7D0001E6991 /* FormattingContext.cpp */,
 				115CFA68208AF7D0001E6991 /* FormattingContext.h */,
+				6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */,
 				115CFA75208AFE30001E6991 /* FormattingState.cpp */,
 				115CFA74208AFE30001E6991 /* FormattingState.h */,
 				115F7805209CBCBD00739C13 /* Invalidation.h */,
@@ -15717,6 +15720,7 @@
 			children = (
 				115CFA6D208AFAB6001E6991 /* BlockFormattingContext.cpp */,
 				115CFA6C208AFAB6001E6991 /* BlockFormattingContext.h */,
+				6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */,
 				115CFA79208B8D9D001E6991 /* BlockFormattingState.cpp */,
 				115CFA78208B8D9D001E6991 /* BlockFormattingState.h */,
 				1123AFDA209ABB2000736ACC /* BlockInvalidation.cpp */,

Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (232113 => 232114)


--- trunk/Source/WebCore/layout/FormattingContext.cpp	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp	2018-05-23 16:56:12 UTC (rev 232114)
@@ -59,11 +59,14 @@
 
 void FormattingContext::computeOutOfFlowPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeOutOfFlowNonReplacedPosition(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeOutOfFlowReplacedPosition(layoutContext, layoutBox, displayBox);
+    LayoutPoint computedTopLeft;
+
+    if (layoutBox.replaced())
+        computedTopLeft = Geometry::outOfFlowReplacedPosition(layoutContext, layoutBox);
+    else
+        computedTopLeft = Geometry::outOfFlowNonReplacedPosition(layoutContext, layoutBox);
+
+    displayBox.setTopLeft(computedTopLeft);
 }
 
 void FormattingContext::computeWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
@@ -86,38 +89,50 @@
 
 void FormattingContext::computeOutOfFlowWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeOutOfFlowNonReplacedWidth(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeOutOfFlowReplacedWidth(layoutContext, layoutBox, displayBox);
+    LayoutUnit computedWidth;
+
+    if (layoutBox.replaced())
+        computedWidth = Geometry::outOfFlowReplacedWidth(layoutContext, layoutBox);
+    else 
+        computedWidth = Geometry::outOfFlowNonReplacedWidth(layoutContext, layoutBox);
+
+    displayBox.setWidth(computedWidth);
 }
 
 void FormattingContext::computeFloatingWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeFloatingNonReplacedWidth(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeReplacedWidth(layoutContext, layoutBox, displayBox);
+    LayoutUnit computedWidth;
+
+    if (layoutBox.replaced())
+        computedWidth = Geometry::floatingReplacedWidth(layoutContext, layoutBox);
+    else
+        computedWidth = Geometry::floatingNonReplacedWidth(layoutContext, layoutBox);
+
+    displayBox.setWidth(computedWidth);
 }
 
 void FormattingContext::computeOutOfFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeOutOfFlowNonReplacedHeight(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeOutOfFlowReplacedHeight(layoutContext, layoutBox, displayBox);
+    LayoutUnit computedHeight;
+
+    if (layoutBox.replaced())
+        computedHeight = Geometry::outOfFlowReplacedHeight(layoutContext, layoutBox);
+    else
+        computedHeight = Geometry::outOfFlowNonReplacedHeight(layoutContext, layoutBox);
+
+    displayBox.setHeight(computedHeight);
 }
 
 void FormattingContext::computeFloatingHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeFloatingNonReplacedHeight(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeReplacedHeight(layoutContext, layoutBox, displayBox);
+    LayoutUnit computedHeight;
+
+    if (layoutBox.replaced())
+        computedHeight = Geometry::floatingReplacedHeight(layoutContext, layoutBox);
+    else
+        computedHeight = Geometry::floatingNonReplacedHeight(layoutContext, layoutBox);
+
+    displayBox.setHeight(computedHeight);
 }
 
 LayoutUnit FormattingContext::marginTop(const Box&) const
@@ -168,476 +183,6 @@
     }
 }
 
-void FormattingContext::computeOutOfFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
-
-    // 10.6.4 Absolutely positioned, non-replaced elements
-    //
-    // For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:
-    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
-    // = height of containing block
-
-    // If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.
-
-    // If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra
-    // constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto', solve the equation for that value.
-    // If the values are over-constrained, ignore the value for 'bottom' and solve for that value.
-
-    // Otherwise, pick the one of the following six rules that applies.
-
-    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
-    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
-    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
-    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
-    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
-    auto& style = layoutBox.style();
-    auto top = style.logicalTop();
-    auto bottom = style.logicalBottom();
-    auto height = style.logicalHeight(); 
-
-    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
-    LayoutUnit computedHeightValue;
-
-    if ((top.isAuto() && height.isAuto() && bottom.isAuto())
-        || (top.isAuto() && height.isAuto() && !bottom.isAuto())
-        || (!top.isAuto() && height.isAuto() && bottom.isAuto())) {
-        // All auto (#3), #1 and #3
-        computedHeightValue = contentHeightForFormattingContextRoot(layoutContext, layoutBox);
-    } else if (!top.isAuto() && height.isAuto() && !bottom.isAuto()) {
-        // #5
-        auto marginTop = displayBox.marginTop();
-        auto marginBottom = displayBox.marginBottom();
-    
-        auto paddingTop = displayBox.paddingTop();
-        auto paddingBottom = displayBox.paddingBottom();
-
-        auto borderTop = displayBox.borderTop();
-        auto borderBottom = displayBox.borderBottom();
-
-        computedHeightValue = containingBlockHeight - (top.value() + marginTop + borderTop + paddingTop + paddingBottom + borderBottom + marginBottom + bottom.value());
-    } else if (!height.isAuto())
-        computedHeightValue = valueForLength(height, containingBlockHeight);
-    else
-        ASSERT_NOT_REACHED();
-
-    displayBox.setHeight(computedHeightValue);
-}
-
-void FormattingContext::computeFloatingNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.replaced());
-    // 10.6.6 Complicated cases
-    //
-    // Floating, non-replaced elements.
-    //
-    // If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
-    auto height = layoutBox.style().logicalHeight();
-    displayBox.setHeight(height.isAuto() ? contentHeightForFormattingContextRoot(layoutContext, layoutBox) : LayoutUnit(height.value()));
-}
-
-void FormattingContext::computeReplacedHeight(LayoutContext&, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
-    // 10.6.5 Absolutely positioned, replaced elements. The used value of 'height' is determined as for inline replaced elements.
-
-    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
-    //
-    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
-    //
-    // 2. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is:
-    //    (used width) / (intrinsic ratio)
-    //
-    // 3. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
-    //
-    // 4. Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to
-    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
-    auto& style = layoutBox.style();
-    auto width = style.logicalWidth();
-    auto height = style.logicalHeight();
-
-    LayoutUnit computedHeightValue;
-    auto replaced = layoutBox.replaced();
-    ASSERT(replaced);
-
-    if (height.isAuto()) {
-        if (width.isAuto() && replaced->hasIntrinsicHeight()) {
-            // #1
-            computedHeightValue = replaced->intrinsicHeight();
-        } else if (replaced->hasIntrinsicRatio()) {
-            // #2
-            computedHeightValue = width.value() / replaced->intrinsicRatio();
-        } else if (replaced->hasIntrinsicHeight()) {
-            // #3
-            computedHeightValue = replaced->intrinsicHeight();
-        } else {
-            // #4
-            computedHeightValue = 150;
-        }
-    } else
-        computedHeightValue = height.value();
-
-    displayBox.setHeight(computedHeightValue);
-}
-
-void FormattingContext::computeReplacedWidth(LayoutContext&, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
-
-    // 10.3.4 Block-level, replaced elements in normal flow: The used value of 'width' is determined as for inline replaced elements.
-    // 10.3.6 Floating, replaced elements: The used value of 'width' is determined as for inline replaced elements.
-    // 10.3.8 Absolutely positioned, replaced elements: The used value of 'width' is determined as for inline replaced elements.
-
-    // 10.3.2 Inline, replaced elements
-    //
-    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
-    //
-    // 2. If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio; 
-    //    or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio;
-    //    then the used value of 'width' is: (used height) * (intrinsic ratio)
-    //
-    // 3. If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
-    //    then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself depend on the replaced 
-    //    element's width, then the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
-    //
-    // 4. Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
-    // 
-    // 5. Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. 
-    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
-    auto& style = layoutBox.style();
-    auto width = style.logicalWidth();
-    auto height = style.logicalHeight();
-
-    LayoutUnit computedWidthValue;
-    auto replaced = layoutBox.replaced();
-    ASSERT(replaced);
-
-    if (width.isAuto() && height.isAuto() && replaced->hasIntrinsicWidth()) {
-        // #1
-        computedWidthValue = replaced->intrinsicWidth();
-    } else if (width.isAuto() && (height.isCalculated() || replaced->hasIntrinsicHeight()) && replaced->hasIntrinsicRatio()) {
-        // #2
-        auto usedHeight = height.isCalculated() ? LayoutUnit(height.value()) : replaced->intrinsicHeight();   
-        computedWidthValue = usedHeight * replaced->intrinsicRatio();
-    } else if (width.isAuto() && height.isAuto() && replaced->hasIntrinsicRatio()) {
-        // #3
-        // FIXME: undefined but surely doable.
-        ASSERT_NOT_IMPLEMENTED_YET();
-    } else if (width.isAuto() && replaced->hasIntrinsicWidth()) {
-        // #4
-        computedWidthValue = replaced->intrinsicWidth();
-    } else {
-        // #5
-        computedWidthValue = 300;
-    }
-
-    displayBox.setWidth(computedWidthValue);
-}
-
-LayoutUnit FormattingContext::contentHeightForFormattingContextRoot(LayoutContext& layoutContext, const Box& layoutBox) const
-{
-    ASSERT(layoutBox.style().logicalHeight().isAuto() && layoutBox.establishesFormattingContext());
-    // 10.6.7 'Auto' heights for block formatting context roots
-
-    // If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.
-    // If it has block-level children, the height is the distance between the top margin-edge of the topmost block-level
-    // child box and the bottom margin-edge of the bottommost block-level child box.
-
-    // In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge,
-    // then the height is increased to include those edges. Only floats that participate in this block formatting context are taken
-    // into account, e.g., floats inside absolutely positioned descendants or other floats are not.
-    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
-        return 0;
-
-    auto& formattingRootContainer = downcast<Container>(layoutBox);
-    if (formattingRootContainer.establishesInlineFormattingContext())
-        return 0;
-
-    auto* firstDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
-    auto* lastDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
-
-    auto top = firstDisplayBox->marginBox().y();
-    auto bottom = lastDisplayBox->marginBox().maxY();
-    // FIXME: add floating support.
-    return bottom - top;
-}
-
-void FormattingContext::computeFloatingNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.replaced());
-    // 10.3.5 Floating, non-replaced elements
-
-    // If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
-    auto width = layoutBox.style().logicalWidth();
-    displayBox.setWidth(width.isAuto() ? shrinkToFitWidth(layoutContext, layoutBox) : LayoutUnit(width.value()));
-}
-
-void FormattingContext::computeOutOfFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
-    
-    // 10.3.7 Absolutely positioned, non-replaced elements
-    //
-    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
-    // = width of containing block
-
-    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
-    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
-    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
-
-    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
-    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
-    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
-    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
-    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
-    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
-    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
-    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
-    auto& style = layoutBox.style();
-    auto left = style.logicalLeft();
-    auto right = style.logicalRight();
-    auto width = style.logicalWidth();
-
-    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
-    LayoutUnit computedWidthValue;
-
-    if ((left.isAuto() && width.isAuto() && right.isAuto())
-        || (left.isAuto() && width.isAuto() && !right.isAuto())
-        || (!left.isAuto() && width.isAuto() && right.isAuto())) {
-        // All auto (#1), #1 and #3
-        computedWidthValue = shrinkToFitWidth(layoutContext, layoutBox);
-    } else if (!left.isAuto() && width.isAuto() && !right.isAuto()) {
-        // #5
-        auto marginLeft = displayBox.marginLeft();
-        auto marginRight = displayBox.marginRight();
-    
-        auto paddingLeft = displayBox.paddingLeft();
-        auto paddingRight = displayBox.paddingRight();
-
-        auto borderLeft = displayBox.borderLeft();
-        auto borderRight = displayBox.borderRight();
-
-        computedWidthValue = containingBlockWidth - (left.value() + marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight + right.value());
-    } else if (!width.isAuto())
-        computedWidthValue = valueForLength(width, containingBlockWidth);
-    else
-        ASSERT_NOT_REACHED();
-
-    displayBox.setWidth(computedWidthValue);
-}
-
-void FormattingContext::computeOutOfFlowReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
-    // 10.6.5 Absolutely positioned, replaced elements
-    //
-    // The used value of 'height' is determined as for inline replaced elements.
-    computeReplacedHeight(layoutContext, layoutBox, displayBox);
-}
-
-void FormattingContext::computeOutOfFlowReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
-    // 10.3.8 Absolutely positioned, replaced elements
-    //
-    // The used value of 'width' is determined as for inline replaced elements.
-    computeReplacedWidth(layoutContext, layoutBox, displayBox);
-}
-
-void FormattingContext::computeOutOfFlowNonReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    // 10.3.7 Absolutely positioned, non-replaced elements (left/right)
-    // 10.6.4 Absolutely positioned, non-replaced elements (top/bottom)
-
-    // At this point we've the size computed.
-    auto size = displayBox.size();
-    auto& style = layoutBox.style();
-
-    // 10.6.4 Absolutely positioned, non-replaced elements
-    auto top = style.logicalTop();
-    auto bottom = style.logicalBottom();
-    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
-
-    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
-    // = height of containing block
-    //
-    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
-    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
-    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
-    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
-    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
-    LayoutUnit computedTopValue;
-    if (top.isAuto() && !bottom.isAuto()) {
-        // #1 #4
-        auto marginTop = displayBox.marginTop();
-        auto marginBottom = displayBox.marginBottom();
-    
-        auto paddingTop = displayBox.paddingTop();
-        auto paddingBottom = displayBox.paddingBottom();
-
-        auto borderTop = displayBox.borderTop();
-        auto borderBottom = displayBox.borderBottom();
-
-        computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value());
-    } else if (top.isAuto() && bottom.isAuto()) {
-        // #2
-        // Already computed as part of the computeStaticPosition();
-        computedTopValue = displayBox.top();
-    } else {
-        // #3 #5 #6 have top != auto
-        computedTopValue = valueForLength(top, containingBlockHeight);
-    }
-
-    displayBox.setTop(computedTopValue);
-
-    // 10.3.7 Absolutely positioned, non-replaced elements
-    auto left = style.logicalLeft();
-    auto right = style.logicalRight();
-    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
-
-    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
-    // = width of containing block
-    //
-    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
-    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
-    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
-
-    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
-    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
-    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
-    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
-    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
-    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
-    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
-    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
-    LayoutUnit computedLeftValue;
-    if (left.isAuto() && !right.isAuto()) {
-        // #1 #4
-        auto marginLeft = displayBox.marginLeft();
-        auto marginRight = displayBox.marginRight();
-    
-        auto paddingLeft = displayBox.paddingLeft();
-        auto paddingRight = displayBox.paddingRight();
-
-        auto borderLeft = displayBox.borderLeft();
-        auto borderRight = displayBox.borderRight();
-
-        computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value());
-    } else if (left.isAuto() && right.isAuto()) {
-        // #2
-        // FIXME: rtl
-        computedLeftValue = displayBox.left();
-    } else {
-        // #3 #5 #6 have left != auto
-        computedLeftValue = valueForLength(left, containingBlockWidth);
-    }
-
-    displayBox.setLeft(computedLeftValue);
-}
-
-void FormattingContext::computeOutOfFlowReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    // 10.6.5 Absolutely positioned, replaced elements (top/bottom)
-    // 10.3.8 Absolutely positioned, replaced elements (left/right)
-
-    // At this point we've the size computed.
-    auto size = displayBox.size();
-    auto& style = layoutBox.style();
-
-    // 10.6.5 Absolutely positioned, replaced elements
-    //
-    // This situation is similar to the previous one, except that the element has an intrinsic height. The sequence of substitutions is now:
-    // The used value of 'height' is determined as for inline replaced elements. If 'margin-top' or 'margin-bottom' is specified as 'auto'
-    // its used value is determined by the rules below.
-    //
-    // 1. If both 'top' and 'bottom' have the value 'auto', replace 'top' with the element's static position.
-    // 2. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or 'margin-bottom' with '0'.
-    // 3. If at this point both 'margin-top' and 'margin-bottom' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values.
-    // 4. If at this point there is only one 'auto' left, solve the equation for that value.
-    // 5. If at this point the values are over-constrained, ignore the value for 'bottom' and solve for that value.
-    auto top = style.logicalTop();
-    auto bottom = style.logicalBottom();
-    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
-    LayoutUnit computedTopValue;
-
-    if (!top.isAuto())
-        computedTopValue = valueForLength(top, containingBlockHeight);
-    else if (bottom.isAuto()) {
-        // #1
-        computedTopValue = displayBox.top();
-    } else {
-        // #4
-        auto marginTop = displayBox.marginTop();
-        auto marginBottom = displayBox.marginBottom();
-
-        auto paddingTop = displayBox.paddingTop();
-        auto paddingBottom = displayBox.paddingBottom();
-
-        auto borderTop = displayBox.borderTop();
-        auto borderBottom = displayBox.borderBottom();
-
-        computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value());
-    }
-
-    displayBox.setTop(computedTopValue);
-
-
-    // 10.3.8 Absolutely positioned, replaced elements
-    //
-    // In this case, section 10.3.7 applies up through and including the constraint equation, but the rest of section 10.3.7 is replaced by the following rules:
-    //
-    // The used value of 'width' is determined as for inline replaced elements. 
-    //
-    // 1. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
-    // 2. If both 'left' and 'right' have the value 'auto', then if the 'direction' property of the element establishing the
-    //    static-position containing block is 'ltr', set 'left' to the static position; else if 'direction' is 'rtl', set 'right' to the static position.
-    // 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' or 'margin-right' with '0'.
-    // 4. If at this point both 'margin-left' and 'margin-right' are still 'auto', solve the equation under the extra constraint
-    //    that the two margins must get equal values, unless this would make them negative, in which case when the direction of
-    //    the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left').
-    // 5. If at this point there is an 'auto' left, solve the equation for that value.
-    // 6. If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction'
-    //    property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
-    auto left = style.logicalLeft();
-    auto right = style.logicalRight();
-    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
-    LayoutUnit computedLeftValue;
-
-    if (!left.isAuto())   
-        computedLeftValue = valueForLength(left, containingBlockWidth);
-    else if (right.isAuto()) {
-        // FIXME: take direction into account
-        computedLeftValue = displayBox.left();
-    } else {
-        // #5
-        auto marginLeft = displayBox.marginLeft();
-        auto marginRight = displayBox.marginRight();
-    
-        auto paddingLeft = displayBox.paddingLeft();
-        auto paddingRight = displayBox.paddingRight();
-
-        auto borderLeft = displayBox.borderLeft();
-        auto borderRight = displayBox.borderRight();
-
-        computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value());
-    }
-
-    displayBox.setLeft(computedLeftValue);
-}
-
-LayoutUnit FormattingContext::shrinkToFitWidth(LayoutContext&, const Box&) const
-{
-    return 0;
-}
-
 #ifndef NDEBUG
 void FormattingContext::validateGeometryConstraintsAfterLayout(const LayoutContext& layoutContext) const
 {

Modified: trunk/Source/WebCore/layout/FormattingContext.h (232113 => 232114)


--- trunk/Source/WebCore/layout/FormattingContext.h	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2018-05-23 16:56:12 UTC (rev 232114)
@@ -28,12 +28,14 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "FloatingState.h"
-#include "LayoutUnit.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
+class LayoutPoint;
+class LayoutUnit;
+
 namespace Display {
 class Box;
 }
@@ -87,28 +89,33 @@
     void placeInFlowPositionedChildren(const Container&) const;
     void layoutOutOfFlowDescendants(LayoutContext&s) const;
 
-    void computeReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
-    void computeReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
-
 #ifndef NDEBUG
     virtual void validateGeometryConstraintsAfterLayout(const LayoutContext&) const;
 #endif
 
-private:
-    void computeOutOfFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
-    void computeOutOfFlowNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
-    void computeOutOfFlowReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
-    void computeOutOfFlowReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
+    // This class implements generic positioning and sizing.
+    class Geometry {
+    public:
+        static LayoutUnit outOfFlowNonReplacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit outOfFlowNonReplacedWidth(LayoutContext&, const Box&);
 
-    void computeOutOfFlowNonReplacedPosition(LayoutContext&, const Box&, Display::Box&) const;
-    void computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const;
+        static LayoutUnit outOfFlowReplacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit outOfFlowReplacedWidth(LayoutContext&, const Box&);
 
-    void computeFloatingNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
-    void computeFloatingNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
+        static LayoutUnit floatingNonReplacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit floatingNonReplacedWidth(LayoutContext&, const Box&);
 
-    LayoutUnit contentHeightForFormattingContextRoot(LayoutContext&, const Box&) const;
-    LayoutUnit shrinkToFitWidth(LayoutContext&, const Box&) const;
+        static LayoutUnit floatingReplacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit floatingReplacedWidth(LayoutContext&, const Box&);
 
+        static LayoutPoint outOfFlowNonReplacedPosition(LayoutContext&, const Box&);
+        static LayoutPoint outOfFlowReplacedPosition(LayoutContext&, const Box&);
+
+        static LayoutUnit replacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit replacedWidth(LayoutContext&, const Box&);
+    };
+
+private:
     WeakPtr<Box> m_root;
 };
 

Copied: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (from rev 232113, trunk/Source/WebCore/layout/FormattingContext.cpp) (0 => 232114)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-05-23 16:56:12 UTC (rev 232114)
@@ -0,0 +1,530 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "FormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+static LayoutUnit contentHeightForFormattingContextRoot(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.style().logicalHeight().isAuto() && layoutBox.establishesFormattingContext());
+    // 10.6.7 'Auto' heights for block formatting context roots
+
+    // If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.
+    // If it has block-level children, the height is the distance between the top margin-edge of the topmost block-level
+    // child box and the bottom margin-edge of the bottommost block-level child box.
+
+    // In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge,
+    // then the height is increased to include those edges. Only floats that participate in this block formatting context are taken
+    // into account, e.g., floats inside absolutely positioned descendants or other floats are not.
+    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
+        return 0;
+
+    auto& formattingRootContainer = downcast<Container>(layoutBox);
+    if (formattingRootContainer.establishesInlineFormattingContext())
+        return 0;
+
+    auto* firstDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
+    auto* lastDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
+
+    auto top = firstDisplayBox->marginBox().y();
+    auto bottom = lastDisplayBox->marginBox().maxY();
+    // FIXME: add floating support.
+    return bottom - top;
+}
+
+static LayoutUnit shrinkToFitWidth(LayoutContext&, const Box&)
+{
+    return { };
+}
+
+LayoutUnit FormattingContext::Geometry::outOfFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
+
+    // 10.6.4 Absolutely positioned, non-replaced elements
+    //
+    // For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:
+    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
+    // = height of containing block
+
+    // If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.
+
+    // If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra
+    // constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto', solve the equation for that value.
+    // If the values are over-constrained, ignore the value for 'bottom' and solve for that value.
+
+    // Otherwise, pick the one of the following six rules that applies.
+
+    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
+    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
+    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
+    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
+    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
+    auto& style = layoutBox.style();
+    auto top = style.logicalTop();
+    auto bottom = style.logicalBottom();
+    auto height = style.logicalHeight(); 
+
+    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
+    LayoutUnit computedHeightValue;
+
+    if (!height.isAuto())
+        computedHeightValue = valueForLength(height, containingBlockHeight);
+    else if ((top.isAuto() && bottom.isAuto())
+        || (top.isAuto() && !bottom.isAuto())
+        || (!top.isAuto() && bottom.isAuto())) {
+        // All auto (#3), #1 and #3
+        computedHeightValue = contentHeightForFormattingContextRoot(layoutContext, layoutBox);
+    } else if (!top.isAuto() && !bottom.isAuto()) {
+        // #5
+        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+
+        auto marginTop = displayBox.marginTop();
+        auto marginBottom = displayBox.marginBottom();
+    
+        auto paddingTop = displayBox.paddingTop();
+        auto paddingBottom = displayBox.paddingBottom();
+
+        auto borderTop = displayBox.borderTop();
+        auto borderBottom = displayBox.borderBottom();
+
+        computedHeightValue = containingBlockHeight - (top.value() + marginTop + borderTop + paddingTop + paddingBottom + borderBottom + marginBottom + bottom.value());
+    } else {
+        // #2 #4 #6 have height != auto
+        ASSERT_NOT_REACHED();
+    }
+
+    return computedHeightValue;
+}
+
+LayoutUnit FormattingContext::Geometry::outOfFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
+    
+    // 10.3.7 Absolutely positioned, non-replaced elements
+    //
+    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
+    // = width of containing block
+
+    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
+    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
+    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
+
+    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
+    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
+    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
+    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
+    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
+    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
+    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
+    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
+    auto& style = layoutBox.style();
+    auto left = style.logicalLeft();
+    auto right = style.logicalRight();
+    auto width = style.logicalWidth();
+
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+    LayoutUnit computedWidthValue;
+
+    if (!width.isAuto())
+        computedWidthValue = valueForLength(width, containingBlockWidth);
+    else if ((left.isAuto() && right.isAuto())
+        || (left.isAuto() && !right.isAuto())
+        || (!left.isAuto() && right.isAuto())) {
+        // All auto (#1), #1 and #3
+        computedWidthValue = shrinkToFitWidth(layoutContext, layoutBox);
+    } else if (!left.isAuto() && !right.isAuto()) {
+        // #5
+        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+
+        auto marginLeft = displayBox.marginLeft();
+        auto marginRight = displayBox.marginRight();
+    
+        auto paddingLeft = displayBox.paddingLeft();
+        auto paddingRight = displayBox.paddingRight();
+
+        auto borderLeft = displayBox.borderLeft();
+        auto borderRight = displayBox.borderRight();
+
+        computedWidthValue = containingBlockWidth - (left.value() + marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight + right.value());
+    } else {
+        // #2 #4 #6 have width != auto
+        ASSERT_NOT_REACHED();
+    }
+
+    return computedWidthValue;
+}
+
+LayoutUnit FormattingContext::Geometry::outOfFlowReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
+    // 10.6.5 Absolutely positioned, replaced elements
+    //
+    // The used value of 'height' is determined as for inline replaced elements.
+    return replacedHeight(layoutContext, layoutBox);
+}
+
+LayoutUnit FormattingContext::Geometry::outOfFlowReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
+    // 10.3.8 Absolutely positioned, replaced elements
+    //
+    // The used value of 'width' is determined as for inline replaced elements.
+    return replacedWidth(layoutContext, layoutBox);
+}
+
+LayoutUnit FormattingContext::Geometry::floatingNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.replaced());
+    // 10.6.6 Complicated cases
+    //
+    // Floating, non-replaced elements.
+    //
+    // If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
+    auto height = layoutBox.style().logicalHeight();
+    return height.isAuto() ? contentHeightForFormattingContextRoot(layoutContext, layoutBox) : LayoutUnit(height.value());
+}
+
+LayoutUnit FormattingContext::Geometry::floatingNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.replaced());
+    // 10.3.5 Floating, non-replaced elements
+
+    // If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
+    auto width = layoutBox.style().logicalWidth();
+    return width.isAuto() ? shrinkToFitWidth(layoutContext, layoutBox) : LayoutUnit(width.value());
+}
+
+LayoutUnit FormattingContext::Geometry::floatingReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isFloatingPositioned() && layoutBox.replaced());
+    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
+    // replaced elements in normal flow and floating replaced elements
+    return replacedHeight(layoutContext, layoutBox);
+}
+
+LayoutUnit FormattingContext::Geometry::floatingReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isFloatingPositioned() && layoutBox.replaced());
+    // 10.3.6 Floating, replaced elements
+    //
+    // The used value of 'width' is determined as for inline replaced elements.
+    return replacedWidth(layoutContext, layoutBox);
+}
+
+LayoutPoint FormattingContext::Geometry::outOfFlowNonReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    // 10.3.7 Absolutely positioned, non-replaced elements (left/right)
+    // 10.6.4 Absolutely positioned, non-replaced elements (top/bottom)
+
+    // At this point we've the size computed.
+    auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+    auto size = displayBox.size();
+    auto& style = layoutBox.style();
+
+    // 10.6.4 Absolutely positioned, non-replaced elements
+    auto top = style.logicalTop();
+    auto bottom = style.logicalBottom();
+    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
+
+    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
+    // = height of containing block
+    //
+    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
+    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
+    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
+    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
+    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
+    LayoutUnit computedTopValue;
+    if (top.isAuto() && !bottom.isAuto()) {
+        // #1 #4
+        auto marginTop = displayBox.marginTop();
+        auto marginBottom = displayBox.marginBottom();
+    
+        auto paddingTop = displayBox.paddingTop();
+        auto paddingBottom = displayBox.paddingBottom();
+
+        auto borderTop = displayBox.borderTop();
+        auto borderBottom = displayBox.borderBottom();
+
+        computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value());
+    } else if (top.isAuto() && bottom.isAuto()) {
+        // #2
+        // Already computed as part of the computeStaticPosition();
+        computedTopValue = displayBox.top();
+    } else {
+        // #3 #5 #6 have top != auto
+        computedTopValue = valueForLength(top, containingBlockHeight);
+    }
+
+
+    // 10.3.7 Absolutely positioned, non-replaced elements
+    auto left = style.logicalLeft();
+    auto right = style.logicalRight();
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+
+    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
+    // = width of containing block
+    //
+    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
+    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
+    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
+
+    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
+    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
+    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
+    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
+    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
+    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
+    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
+    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
+    LayoutUnit computedLeftValue;
+    if (left.isAuto() && !right.isAuto()) {
+        // #1 #4
+        auto marginLeft = displayBox.marginLeft();
+        auto marginRight = displayBox.marginRight();
+    
+        auto paddingLeft = displayBox.paddingLeft();
+        auto paddingRight = displayBox.paddingRight();
+
+        auto borderLeft = displayBox.borderLeft();
+        auto borderRight = displayBox.borderRight();
+
+        computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value());
+    } else if (left.isAuto() && right.isAuto()) {
+        // #2
+        // FIXME: rtl
+        computedLeftValue = displayBox.left();
+    } else {
+        // #3 #5 #6 have left != auto
+        computedLeftValue = valueForLength(left, containingBlockWidth);
+    }
+
+    return { computedLeftValue, computedTopValue };
+}
+
+LayoutPoint FormattingContext::Geometry::outOfFlowReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    // 10.6.5 Absolutely positioned, replaced elements (top/bottom)
+    // 10.3.8 Absolutely positioned, replaced elements (left/right)
+
+    // At this point we've the size computed.
+    auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+    auto size = displayBox.size();
+    auto& style = layoutBox.style();
+
+    // 10.6.5 Absolutely positioned, replaced elements
+    //
+    // This situation is similar to the previous one, except that the element has an intrinsic height. The sequence of substitutions is now:
+    // The used value of 'height' is determined as for inline replaced elements. If 'margin-top' or 'margin-bottom' is specified as 'auto'
+    // its used value is determined by the rules below.
+    //
+    // 1. If both 'top' and 'bottom' have the value 'auto', replace 'top' with the element's static position.
+    // 2. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or 'margin-bottom' with '0'.
+    // 3. If at this point both 'margin-top' and 'margin-bottom' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values.
+    // 4. If at this point there is only one 'auto' left, solve the equation for that value.
+    // 5. If at this point the values are over-constrained, ignore the value for 'bottom' and solve for that value.
+    auto top = style.logicalTop();
+    auto bottom = style.logicalBottom();
+    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
+    LayoutUnit computedTopValue;
+
+    if (!top.isAuto())
+        computedTopValue = valueForLength(top, containingBlockHeight);
+    else if (bottom.isAuto()) {
+        // #1
+        computedTopValue = displayBox.top();
+    } else {
+        // #4
+        auto marginTop = displayBox.marginTop();
+        auto marginBottom = displayBox.marginBottom();
+
+        auto paddingTop = displayBox.paddingTop();
+        auto paddingBottom = displayBox.paddingBottom();
+
+        auto borderTop = displayBox.borderTop();
+        auto borderBottom = displayBox.borderBottom();
+
+        computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value());
+    }
+
+
+    // 10.3.8 Absolutely positioned, replaced elements
+    //
+    // In this case, section 10.3.7 applies up through and including the constraint equation, but the rest of section 10.3.7 is replaced by the following rules:
+    //
+    // The used value of 'width' is determined as for inline replaced elements. 
+    //
+    // 1. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
+    // 2. If both 'left' and 'right' have the value 'auto', then if the 'direction' property of the element establishing the
+    //    static-position containing block is 'ltr', set 'left' to the static position; else if 'direction' is 'rtl', set 'right' to the static position.
+    // 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' or 'margin-right' with '0'.
+    // 4. If at this point both 'margin-left' and 'margin-right' are still 'auto', solve the equation under the extra constraint
+    //    that the two margins must get equal values, unless this would make them negative, in which case when the direction of
+    //    the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left').
+    // 5. If at this point there is an 'auto' left, solve the equation for that value.
+    // 6. If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction'
+    //    property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
+    auto left = style.logicalLeft();
+    auto right = style.logicalRight();
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+    LayoutUnit computedLeftValue;
+
+    if (!left.isAuto())   
+        computedLeftValue = valueForLength(left, containingBlockWidth);
+    else if (right.isAuto()) {
+        // FIXME: take direction into account
+        computedLeftValue = displayBox.left();
+    } else {
+        // #5
+        auto marginLeft = displayBox.marginLeft();
+        auto marginRight = displayBox.marginRight();
+    
+        auto paddingLeft = displayBox.paddingLeft();
+        auto paddingRight = displayBox.paddingRight();
+
+        auto borderLeft = displayBox.borderLeft();
+        auto borderRight = displayBox.borderRight();
+
+        computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value());
+    }
+
+    return { computedLeftValue, computedTopValue };
+}
+
+LayoutUnit FormattingContext::Geometry::replacedHeight(LayoutContext&, const Box& layoutBox)
+{
+    ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
+    // 10.6.5 Absolutely positioned, replaced elements. The used value of 'height' is determined as for inline replaced elements.
+
+    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
+    //
+    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
+    //
+    // 2. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is:
+    //    (used width) / (intrinsic ratio)
+    //
+    // 3. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
+    //
+    // 4. Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to
+    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
+    auto& style = layoutBox.style();
+    auto width = style.logicalWidth();
+    auto height = style.logicalHeight();
+
+    LayoutUnit computedHeightValue;
+    auto replaced = layoutBox.replaced();
+    ASSERT(replaced);
+
+    if (height.isAuto()) {
+        if (width.isAuto() && replaced->hasIntrinsicHeight()) {
+            // #1
+            computedHeightValue = replaced->intrinsicHeight();
+        } else if (replaced->hasIntrinsicRatio()) {
+            // #2
+            computedHeightValue = width.value() / replaced->intrinsicRatio();
+        } else if (replaced->hasIntrinsicHeight()) {
+            // #3
+            computedHeightValue = replaced->intrinsicHeight();
+        } else {
+            // #4
+            computedHeightValue = 150;
+        }
+    } else
+        computedHeightValue = height.value();
+
+    return computedHeightValue;
+}
+
+LayoutUnit FormattingContext::Geometry::replacedWidth(LayoutContext&, const Box& layoutBox)
+{
+    ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
+
+    // 10.3.4 Block-level, replaced elements in normal flow: The used value of 'width' is determined as for inline replaced elements.
+    // 10.3.6 Floating, replaced elements: The used value of 'width' is determined as for inline replaced elements.
+    // 10.3.8 Absolutely positioned, replaced elements: The used value of 'width' is determined as for inline replaced elements.
+
+    // 10.3.2 Inline, replaced elements
+    //
+    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
+    //
+    // 2. If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
+    //    or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio;
+    //    then the used value of 'width' is: (used height) * (intrinsic ratio)
+    //
+    // 3. If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
+    //    then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself depend on the replaced
+    //    element's width, then the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
+    //
+    // 4. Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
+    //
+    // 5. Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px.
+    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
+    auto& style = layoutBox.style();
+    auto width = style.logicalWidth();
+    auto height = style.logicalHeight();
+
+    LayoutUnit computedWidthValue;
+    auto replaced = layoutBox.replaced();
+    ASSERT(replaced);
+
+    if (width.isAuto() && height.isAuto() && replaced->hasIntrinsicWidth()) {
+        // #1
+        computedWidthValue = replaced->intrinsicWidth();
+    } else if (width.isAuto() && (height.isCalculated() || replaced->hasIntrinsicHeight()) && replaced->hasIntrinsicRatio()) {
+        // #2
+        auto usedHeight = height.isCalculated() ? LayoutUnit(height.value()) : replaced->intrinsicHeight();
+        computedWidthValue = usedHeight * replaced->intrinsicRatio();
+    } else if (width.isAuto() && height.isAuto() && replaced->hasIntrinsicRatio()) {
+        // #3
+        // FIXME: undefined but surely doable.
+        ASSERT_NOT_IMPLEMENTED_YET();
+    } else if (width.isAuto() && replaced->hasIntrinsicWidth()) {
+        // #4
+        computedWidthValue = replaced->intrinsicWidth();
+    } else {
+        // #5
+        computedWidthValue = 300;
+    }
+
+    return computedWidthValue;
+}
+
+}
+}
+#endif

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (232113 => 232114)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-05-23 16:56:12 UTC (rev 232114)
@@ -130,71 +130,38 @@
 
 void BlockFormattingContext::computeStaticPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    // https://www.w3.org/TR/CSS22/visuren.html#block-formatting
-    // In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
-    // The vertical distance between two sibling boxes is determined by the 'margin' properties.
-    // Vertical margins between adjacent block-level boxes in a block formatting context collapse.
-    // In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
-    auto containingBlockContentBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBox();
-    // Start from the top of the container's content box.
-    auto top = containingBlockContentBox.y();
-    auto left = containingBlockContentBox.x();
-    if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling())
-        top = layoutContext.displayBoxForLayoutBox(*previousInFlowSibling)->bottom() + marginBottom(*previousInFlowSibling);
-    LayoutPoint topLeft = { top, left };
-    topLeft.moveBy({ marginLeft(layoutBox), marginTop(layoutBox) });
+    auto topLeft = Geometry::staticPosition(layoutContext, layoutBox);
     displayBox.setTopLeft(topLeft);
 }
 
-void BlockFormattingContext::computeInFlowWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
+void BlockFormattingContext::computeInFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    if (!layoutBox.replaced()) {
-        computeInFlowNonReplacedWidth(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeReplacedWidth(layoutContext, layoutBox, displayBox);
+    LayoutUnit computedHeight;
+
+    if (layoutBox.replaced()) {
+        // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
+        // replaced elements in normal flow and floating replaced elements
+        computedHeight = FormattingContext::Geometry::replacedHeight(layoutContext, layoutBox);
+    } else
+        computedHeight = Geometry::inFlowNonReplacedHeight(layoutContext, layoutBox);
+
+    displayBox.setHeight(computedHeight);
 }
 
-void BlockFormattingContext::computeInFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
+void BlockFormattingContext::computeInFlowWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
-    ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
+    LayoutUnit computedWidth;
 
-    // 10.3.3 Block-level, non-replaced elements in normal flow
-    // The following constraints must hold among the used values of the other properties:
-    // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
-
-    // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
-    auto& style = layoutBox.style();
-    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
-
-    LayoutUnit computedWidthValue;
-    auto width = style.logicalWidth();
-    if (width.isAuto()) {
-        auto marginLeft = displayBox.marginLeft();
-        auto marginRight = displayBox.marginRight();
-
-        auto paddingLeft = displayBox.paddingLeft();
-        auto paddingRight = displayBox.paddingRight();
-
-        auto borderLeft = displayBox.borderLeft();
-        auto borderRight = displayBox.borderRight();
-
-        computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
+    if (layoutBox.replaced()) {
+        // 10.3.4 Block-level, replaced elements in normal flow
+        // The used value of 'width' is determined as for inline replaced elements
+        computedWidth = FormattingContext::Geometry::replacedWidth(layoutContext, layoutBox);
     } else
-        computedWidthValue = valueForLength(width, containingBlockWidth);
+        computedWidth = Geometry::inFlowNonReplacedWidth(layoutContext, layoutBox);
 
-    displayBox.setWidth(computedWidthValue);
+    displayBox.setWidth(computedWidth);
 }
 
-void BlockFormattingContext::computeInFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    if (!layoutBox.replaced()) {
-        computeInFlowNonReplacedHeight(layoutContext, layoutBox, displayBox);
-        return;
-    }
-    computeReplacedHeight(layoutContext, layoutBox, displayBox);
-}
-
 LayoutUnit BlockFormattingContext::marginTop(const Box& layoutBox) const
 {
     return BlockMarginCollapse::marginTop(layoutBox);
@@ -205,64 +172,7 @@
     return BlockMarginCollapse::marginBottom(layoutBox);
 }
 
-void BlockFormattingContext::computeInFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
-{
-    ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
-
-    // https://www.w3.org/TR/CSS22/visudet.html
-    // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
-    // The element's height is the distance from its top content edge to the first applicable of the following:
-    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
-    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
-    //    does not collapse with the element's bottom margin
-    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
-    // 4. zero, otherwise
-    // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
-    // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
-    if (!layoutBox.style().logicalHeight().isAuto()) {
-        // FIXME: Only fixed values yet.
-        displayBox.setHeight(layoutBox.style().logicalHeight().value());
-        return;
-    }
-
-    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild()) {
-        displayBox.setHeight(0);
-        return;
-    }
-
-    // 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()) {
-        // height = lastLineBox().bottom();
-        displayBox.setHeight(0);
-        return;
-    }
-
-    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
-    auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
-    ASSERT(lastInFlowChild);
-    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
-        auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
-        ASSERT(lastInFlowDisplayBox);
-        displayBox.setHeight(lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom());
-        return;
-    }
-
-    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
-    auto* inFlowChild = lastInFlowChild;
-    while (inFlowChild && BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
-        inFlowChild = inFlowChild->previousInFlowSibling();
-    if (inFlowChild) {
-        auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
-        ASSERT(inFlowDisplayBox);
-        displayBox.setHeight(inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height());
-        return;
-    }
-
-    // 4. zero, otherwise
-    displayBox.setHeight(0);
 }
-
 }
-}
 
 #endif

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (232113 => 232114)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-05-23 16:56:12 UTC (rev 232114)
@@ -28,11 +28,12 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "FormattingContext.h"
-#include "LayoutUnit.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
 
+class LayoutUnit;
+
 namespace Layout {
 
 class BlockFormattingState;
@@ -51,18 +52,22 @@
 
 private:
     void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override;
-
     void computeInFlowWidth(LayoutContext&, const Box&, Display::Box&) const override;
-    void computeInFlowNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
-
     void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override;
-    void computeInFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
 
     LayoutUnit marginTop(const Box&) const override;
     LayoutUnit marginBottom(const Box&) const override;
+    
+    // This class implements positioning and sizing for boxes participating in a block formatting context.
+    class Geometry {
+    public:
+        static LayoutUnit inFlowNonReplacedHeight(LayoutContext&, const Box&);
+        static LayoutUnit inFlowNonReplacedWidth(LayoutContext&, const Box&);
+
+        static LayoutPoint staticPosition(LayoutContext&, const Box&);
+    };
 };
 
 }
 }
 #endif
-

Added: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (0 => 232114)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	2018-05-23 16:56:12 UTC (rev 232114)
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "BlockFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FormattingContext.h"
+
+namespace WebCore {
+namespace Layout {
+
+LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
+
+    // https://www.w3.org/TR/CSS22/visudet.html
+    // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
+    // The element's height is the distance from its top content edge to the first applicable of the following:
+    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
+    //    does not collapse with the element's bottom margin
+    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+    // 4. zero, otherwise
+    // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
+    // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
+    if (!layoutBox.style().logicalHeight().isAuto()) {
+        // FIXME: Only fixed values yet.
+        return layoutBox.style().logicalHeight().value();
+    }
+
+    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
+        return 0;
+
+    // 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()) {
+        // height = lastLineBox().bottom();
+        return 0;
+    }
+
+    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
+    auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
+    ASSERT(lastInFlowChild);
+    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
+        auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
+        ASSERT(lastInFlowDisplayBox);
+        return lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom();
+    }
+
+    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+    auto* inFlowChild = lastInFlowChild;
+    while (inFlowChild && BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
+        inFlowChild = inFlowChild->previousInFlowSibling();
+    if (inFlowChild) {
+        auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
+        ASSERT(inFlowDisplayBox);
+        return inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height();
+    }
+
+    // 4. zero, otherwise
+    return 0;
+}
+
+LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
+
+    // 10.3.3 Block-level, non-replaced elements in normal flow
+    // The following constraints must hold among the used values of the other properties:
+    // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
+
+    // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
+    auto& style = layoutBox.style();
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+
+    LayoutUnit computedWidthValue;
+    auto width = style.logicalWidth();
+    if (width.isAuto()) {
+        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+        auto marginLeft = displayBox.marginLeft();
+        auto marginRight = displayBox.marginRight();
+
+        auto paddingLeft = displayBox.paddingLeft();
+        auto paddingRight = displayBox.paddingRight();
+
+        auto borderLeft = displayBox.borderLeft();
+        auto borderRight = displayBox.borderRight();
+
+        computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
+    } else
+        computedWidthValue = valueForLength(width, containingBlockWidth);
+
+    return computedWidthValue;
+}
+
+LayoutPoint BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox)
+{
+    // https://www.w3.org/TR/CSS22/visuren.html#block-formatting
+    // In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
+    // The vertical distance between two sibling boxes is determined by the 'margin' properties.
+    // Vertical margins between adjacent block-level boxes in a block formatting context collapse.
+    // In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
+    auto containingBlockContentBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBox();
+    // Start from the top of the container's content box.
+    auto top = containingBlockContentBox.y();
+    auto left = containingBlockContentBox.x();
+    if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
+        auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+        top = previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
+    }
+    auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+    LayoutPoint topLeft = { top, left };
+    topLeft.moveBy({ displayBox.marginLeft(), displayBox.marginTop() });
+    return topLeft;
+}
+
+}
+}
+
+#endif

Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.h (232113 => 232114)


--- trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2018-05-23 16:09:54 UTC (rev 232113)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2018-05-23 16:56:12 UTC (rev 232114)
@@ -48,9 +48,9 @@
 class Box {
     WTF_MAKE_ISO_ALLOCATED(Box);
 public:
+    friend class Layout::BlockFormattingContext;
+    friend class Layout::FormattingContext;
     friend class Layout::LayoutContext;
-    friend class Layout::FormattingContext;
-    friend class Layout::BlockFormattingContext;
 
     ~Box();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to