Title: [261793] trunk/Source/WebCore
Revision
261793
Author
[email protected]
Date
2020-05-17 09:17:45 -0700 (Sun, 17 May 2020)

Log Message

[LFC][BFC] Introduce TableWrapperBlockFormattingContext
https://bugs.webkit.org/show_bug.cgi?id=211996

Reviewed by Antti Koivisto.

Table wrapper box establishes a special BFC with only captions and the actual table box in it.
It mostly behaves like a normal BFC but the table box requires some special handing when it comes
to padding/border and width/height computation.
This patch moves the table box specific code from generic BFC to this new subclass.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingContext.h:
* layout/LayoutContext.cpp:
(WebCore::Layout::LayoutContext::createFormattingContext):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin):
* layout/blockformatting/BlockFormattingContext.h:
(): Deleted.
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp: Added.
(WebCore::Layout::TableWrapperBlockFormattingContext::TableWrapperBlockFormattingContext):
(WebCore::Layout::TableWrapperBlockFormattingContext::layoutInFlowContent):
(WebCore::Layout::TableWrapperBlockFormattingContext::layoutTableBox):
(WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
(WebCore::Layout::TableWrapperBlockFormattingContext::computeHeightAndMarginForTableBox):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (261792 => 261793)


--- trunk/Source/WebCore/CMakeLists.txt	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/CMakeLists.txt	2020-05-17 16:17:45 UTC (rev 261793)
@@ -100,6 +100,7 @@
     "${WEBCORE_DIR}/inspector/agents/worker"
     "${WEBCORE_DIR}/layout"
     "${WEBCORE_DIR}/layout/blockformatting"
+    "${WEBCORE_DIR}/layout/blockformatting/tablewrapper"
     "${WEBCORE_DIR}/layout/displaytree"
     "${WEBCORE_DIR}/layout/floats"
     "${WEBCORE_DIR}/layout/inlineformatting"

Modified: trunk/Source/WebCore/ChangeLog (261792 => 261793)


--- trunk/Source/WebCore/ChangeLog	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/ChangeLog	2020-05-17 16:17:45 UTC (rev 261793)
@@ -1,3 +1,34 @@
+2020-05-17  Zalan Bujtas  <[email protected]>
+
+        [LFC][BFC] Introduce TableWrapperBlockFormattingContext
+        https://bugs.webkit.org/show_bug.cgi?id=211996
+
+        Reviewed by Antti Koivisto.
+
+        Table wrapper box establishes a special BFC with only captions and the actual table box in it.
+        It mostly behaves like a normal BFC but the table box requires some special handing when it comes
+        to padding/border and width/height computation.
+        This patch moves the table box specific code from generic BFC to this new subclass. 
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingContext.h:
+        * layout/LayoutContext.cpp:
+        (WebCore::Layout::LayoutContext::createFormattingContext):
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin):
+        * layout/blockformatting/BlockFormattingContext.h:
+        (): Deleted.
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
+        * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp: Added.
+        (WebCore::Layout::TableWrapperBlockFormattingContext::TableWrapperBlockFormattingContext):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::layoutTableBox):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::computeHeightAndMarginForTableBox):
+        * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h: Added.
+
 2020-05-17  Carlos Garcia Campos  <[email protected]>
 
         [GTK] Move to new Pasteboard API

Modified: trunk/Source/WebCore/Sources.txt (261792 => 261793)


--- trunk/Source/WebCore/Sources.txt	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/Sources.txt	2020-05-17 16:17:45 UTC (rev 261793)
@@ -1462,6 +1462,7 @@
 layout/blockformatting/BlockFormattingState.cpp
 layout/blockformatting/BlockMarginCollapse.cpp
 layout/blockformatting/PrecomputedBlockMarginCollapse.cpp
+layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp
 layout/displaytree/DisplayBox.cpp
 layout/displaytree/DisplayInlineContent.cpp
 layout/displaytree/DisplayPainter.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (261792 => 261793)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-05-17 16:17:45 UTC (rev 261793)
@@ -2049,6 +2049,7 @@
 		6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */; };
 		6F0B98B523F268EC00EEC2F2 /* LayoutInlineTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0B98B323F268EB00EEC2F2 /* LayoutInlineTextBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F0CD695229ED32700C5994E /* InlineLineBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0CD694229ED32700C5994E /* InlineLineBuilder.h */; };
+		6F17264F2470C60B00518C96 /* TableWrapperBlockFormattingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F1CC1DE225F8B4900720AD2 /* InlineTextItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F26BB6C23343E6F002F2BEA /* LayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26BB6B23343E5B002F2BEA /* LayoutContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F26EB48234004A5006906E2 /* LineLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26EB46234004A5006906E2 /* LineLayoutContext.h */; };
@@ -9417,6 +9418,8 @@
 		6F0CD692229ED31900C5994E /* InlineLineBuilder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineBuilder.cpp; sourceTree = "<group>"; };
 		6F0CD694229ED32700C5994E /* InlineLineBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineBuilder.h; sourceTree = "<group>"; };
 		6F10B08622B8568D0090E69C /* InlineFormattingContextQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFormattingContextQuirks.cpp; sourceTree = "<group>"; };
+		6F17264C2470C5F700518C96 /* TableWrapperBlockFormattingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableWrapperBlockFormattingContext.cpp; sourceTree = "<group>"; };
+		6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableWrapperBlockFormattingContext.h; sourceTree = "<group>"; };
 		6F1CC1DC225F8B4100720AD2 /* InlineTextItem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineTextItem.cpp; sourceTree = "<group>"; };
 		6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlineTextItem.h; sourceTree = "<group>"; };
 		6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
@@ -17073,6 +17076,7 @@
 		115CFA99208BC09A001E6991 /* blockformatting */ = {
 			isa = PBXGroup;
 			children = (
+				6FD4FE3E2470B3AD007374CC /* tablewrapper */,
 				115CFA6D208AFAB6001E6991 /* BlockFormattingContext.cpp */,
 				115CFA6C208AFAB6001E6991 /* BlockFormattingContext.h */,
 				6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */,
@@ -21292,6 +21296,15 @@
 			path = floats;
 			sourceTree = "<group>";
 		};
+		6FD4FE3E2470B3AD007374CC /* tablewrapper */ = {
+			isa = PBXGroup;
+			children = (
+				6F17264C2470C5F700518C96 /* TableWrapperBlockFormattingContext.cpp */,
+				6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */,
+			);
+			path = tablewrapper;
+			sourceTree = "<group>";
+		};
 		6FE7DDDD20EC6E8B008B5B4E /* text */ = {
 			isa = PBXGroup;
 			children = (
@@ -33280,6 +33293,7 @@
 				0F03C0741884695E00A5F8CA /* SystemMemory.h in Headers */,
 				5D5975B319635F1100D00878 /* SystemVersion.h in Headers */,
 				A8CFF0510A154F09000A4234 /* TableLayout.h in Headers */,
+				6F17264F2470C60B00518C96 /* TableWrapperBlockFormattingContext.h in Headers */,
 				3BB6B81122A7D313003A2A69 /* TabSize.h in Headers */,
 				463EB6231B8789E00096ED51 /* TagCollection.h in Headers */,
 				9B0ABCAE236BB43100B45085 /* TaskSource.h in Headers */,

Modified: trunk/Source/WebCore/layout/FormattingContext.h (261792 => 261793)


--- trunk/Source/WebCore/layout/FormattingContext.h	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2020-05-17 16:17:45 UTC (rev 261793)
@@ -160,13 +160,13 @@
         ConstraintsForOutOfFlowContent constraintsForOutOfFlowContent(const ContainerBox&);
         ConstraintsForInFlowContent constraintsForInFlowContent(const ContainerBox&, Optional<EscapeReason> = WTF::nullopt);
 
+        Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
+        Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth) const;
+
     protected:
         friend class FormattingContext;
         Geometry(const FormattingContext&);
 
-        Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
-        Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth) const;
-
         const LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
         LayoutState& layoutState() { return m_formattingContext.layoutState(); }
         const FormattingContext& formattingContext() const { return m_formattingContext; }

Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (261792 => 261793)


--- trunk/Source/WebCore/layout/LayoutContext.cpp	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp	2020-05-17 16:17:45 UTC (rev 261793)
@@ -45,6 +45,7 @@
 #include "RuntimeEnabledFeatures.h"
 #include "TableFormattingContext.h"
 #include "TableFormattingState.h"
+#include "TableWrapperBlockFormattingContext.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -124,6 +125,8 @@
     if (formattingContextRoot.establishesBlockFormattingContext()) {
         ASSERT(!formattingContextRoot.establishesInlineFormattingContext());
         auto& blockFormattingState = layoutState.ensureBlockFormattingState(formattingContextRoot);
+        if (formattingContextRoot.isTableWrapperBox())
+            return makeUnique<TableWrapperBlockFormattingContext>(formattingContextRoot, blockFormattingState);
         return makeUnique<BlockFormattingContext>(formattingContextRoot, blockFormattingState);
     }
 

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (261792 => 261793)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2020-05-17 16:17:45 UTC (rev 261793)
@@ -372,34 +372,23 @@
         return { };
     };
 
-    auto usedHeightValue = Optional<LayoutUnit> { };
-    auto ignoreMinMaxHeightCompute = false;
-    if (layoutBox.establishesTableFormattingContext()) {
-        // Table is a special BFC content. Its height is mainly driven by the content. Computed height, min-height and max-height are all
-        // already been taken into account during the TFC layout.
-        usedHeightValue = geometry().contentHeightForFormattingContextRoot(downcast<ContainerBox>(layoutBox));
-        ignoreMinMaxHeightCompute = true;
+    auto contentHeightAndMargin = compute({ });
+    if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
+        if (contentHeightAndMargin.contentHeight > *maxHeight) {
+            auto maxHeightAndMargin = compute(maxHeight);
+            // Used height should remain the same.
+            ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.contentHeight == *maxHeight);
+            contentHeightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin };
+        }
     }
 
-    auto contentHeightAndMargin = compute({ usedHeightValue });
-    if (!ignoreMinMaxHeightCompute) {
-        if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
-            if (contentHeightAndMargin.contentHeight > *maxHeight) {
-                auto maxHeightAndMargin = compute(maxHeight);
-                // Used height should remain the same.
-                ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.contentHeight == *maxHeight);
-                contentHeightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin };
-            }
+    if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
+        if (contentHeightAndMargin.contentHeight < *minHeight) {
+            auto minHeightAndMargin = compute(minHeight);
+            // Used height should remain the same.
+            ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.contentHeight == *minHeight);
+            contentHeightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin };
         }
-
-        if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
-            if (contentHeightAndMargin.contentHeight < *minHeight) {
-                auto minHeightAndMargin = compute(minHeight);
-                // Used height should remain the same.
-                ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.contentHeight == *minHeight);
-                contentHeightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin };
-            }
-        }
     }
 
     // 1. Compute collapsed margins.

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (261792 => 261793)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2020-05-17 16:17:45 UTC (rev 261793)
@@ -43,7 +43,7 @@
 
 // This class implements the layout logic for block formatting contexts.
 // https://www.w3.org/TR/CSS22/visuren.html#block-formatting
-class BlockFormattingContext final : public FormattingContext {
+class BlockFormattingContext : public FormattingContext {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingContext);
 public:
     BlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState&);
@@ -50,8 +50,7 @@
 
     void layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent&) override;
 
-private:
-
+protected:
     struct ConstraintsPair {
         const ConstraintsForInFlowContent formattingContextRoot;
         const ConstraintsForInFlowContent containingBlock;
@@ -75,6 +74,8 @@
     // This class implements positioning and sizing for boxes participating in a block formatting context.
     class Geometry : public FormattingContext::Geometry {
     public:
+        Geometry(const BlockFormattingContext&);
+
         ContentHeightAndMargin inFlowHeightAndMargin(const Box&, const HorizontalConstraints&, const OverrideVerticalValues&);
         ContentWidthAndMargin inFlowWidthAndMargin(const Box&, const HorizontalConstraints&, const OverrideHorizontalValues&);
 
@@ -85,13 +86,9 @@
         IntrinsicWidthConstraints intrinsicWidthConstraints(const Box&);
 
     private:
-        friend class BlockFormattingContext;
-        Geometry(const BlockFormattingContext&);
-
         ContentHeightAndMargin inFlowNonReplacedHeightAndMargin(const Box&, const HorizontalConstraints&, const OverrideVerticalValues&);
         ContentWidthAndMargin inFlowNonReplacedWidthAndMargin(const Box&, const HorizontalConstraints&, const OverrideHorizontalValues&) const;
         ContentWidthAndMargin inFlowReplacedWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverrideHorizontalValues&) const;
-        Point staticPositionForOutOfFlowPositioned(const Box&) const;
 
         const BlockFormattingContext& formattingContext() const { return downcast<BlockFormattingContext>(FormattingContext::Geometry::formattingContext()); }
     };

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (261792 => 261793)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	2020-05-17 16:17:45 UTC (rev 261793)
@@ -278,32 +278,8 @@
 {
     ASSERT(layoutBox.isInFlow());
 
-    if (!layoutBox.isReplacedBox()) {
-        if (!layoutBox.establishesTableFormattingContext())
-            return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, overrideHorizontalValues);
-        // This is a special table "fit-content size" behavior handling. Not in the spec though.
-        // Table returns its final width as min/max. Use this final width value to computed horizontal margins etc.
-        if (overrideHorizontalValues.width)
-            return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, OverrideHorizontalValues { overrideHorizontalValues.width, overrideHorizontalValues.margin });
-
-        auto& tableBox = downcast<ContainerBox>(layoutBox);
-        auto& formattingStateForTableBox = layoutState().ensureFormattingState(tableBox);
-        auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
-        if (auto precomputedIntrinsicWidthConstraints = formattingStateForTableBox.intrinsicWidthConstraints())
-            intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
-        else
-            intrinsicWidthConstraints = LayoutContext::createFormattingContext(tableBox, layoutState())->computedIntrinsicWidthConstraints();
-        auto computedTableWidth = computedWidth(tableBox, horizontalConstraints.logicalWidth);
-        auto usedWidth = computedTableWidth;
-        if (computedTableWidth && intrinsicWidthConstraints.minimum > computedTableWidth) {
-            // Table content needs more space than the table has.
-            usedWidth = intrinsicWidthConstraints.minimum;
-        } else if (!computedTableWidth) {
-            // Use the generic shrink-to-fit-width logic.
-            usedWidth = std::min(std::max(intrinsicWidthConstraints.minimum, horizontalConstraints.logicalWidth), intrinsicWidthConstraints.maximum);
-        }
-        return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, OverrideHorizontalValues { usedWidth, overrideHorizontalValues.margin });
-    }
+    if (!layoutBox.isReplacedBox())
+        return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, overrideHorizontalValues);
     return inFlowReplacedWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overrideHorizontalValues);
 }
 

Added: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp (0 => 261793)


--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp	2020-05-17 16:17:45 UTC (rev 261793)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 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 "TableWrapperBlockFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(TableWrapperBlockFormattingContext);
+
+TableWrapperBlockFormattingContext::TableWrapperBlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState& formattingState)
+    : BlockFormattingContext(formattingContextRoot, formattingState)
+{
+}
+
+void TableWrapperBlockFormattingContext::layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent& constraints)
+{
+    // The table generates a principal block container box called the table wrapper box that contains the table box itself and any caption boxes
+    // (in document order). The table box is a block-level box that contains the table's internal table boxes.
+    // The caption boxes are principal block-level boxes that retain their own content, padding, margin, and border areas, and are rendered
+    // as normal block boxes inside the table wrapper box. Whether the caption boxes are placed before or after the table box is decided by
+    // the 'caption-side' property, as described below.
+    for (auto& child : childrenOfType<ContainerBox>(root())) {
+        if (child.isTableBox())
+            layoutTableBox(child, constraints);
+        else if (child.isTableCaption())
+            ASSERT_NOT_IMPLEMENTED_YET();
+        else
+            ASSERT_NOT_REACHED();
+    }
+}
+
+void TableWrapperBlockFormattingContext::layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+    computeBorderAndPadding(tableBox, constraints.horizontal);
+    computeStaticVerticalPosition(tableBox, constraints.vertical);
+    computeWidthAndMarginForTableBox(tableBox, constraints);
+    computeStaticHorizontalPosition(tableBox, constraints.horizontal);
+
+    auto invalidationState = InvalidationState { };
+    LayoutContext::createFormattingContext(tableBox, layoutState())->layoutInFlowContent(invalidationState, geometry().constraintsForInFlowContent(tableBox));
+
+    computeHeightAndMarginForTableBox(tableBox, constraints);
+}
+
+void TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+    ASSERT(tableBox.isTableBox());
+    // This is a special table "fit-content size" behavior handling. Not in the spec though.
+    // Table returns its final width as min/max. Use this final width value to computed horizontal margins etc.
+    auto& formattingStateForTableBox = layoutState().ensureFormattingState(tableBox);
+    auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
+    if (auto precomputedIntrinsicWidthConstraints = formattingStateForTableBox.intrinsicWidthConstraints())
+        intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
+    else
+        intrinsicWidthConstraints = LayoutContext::createFormattingContext(tableBox, layoutState())->computedIntrinsicWidthConstraints();
+    auto computedTableWidth = geometry().computedWidth(tableBox, constraints.horizontal.logicalWidth);
+    auto usedWidth = computedTableWidth;
+    if (computedTableWidth && intrinsicWidthConstraints.minimum > computedTableWidth) {
+        // Table content needs more space than the table has.
+        usedWidth = intrinsicWidthConstraints.minimum;
+    } else if (!computedTableWidth) {
+        // Use the generic shrink-to-fit-width logic.
+        usedWidth = std::min(std::max(intrinsicWidthConstraints.minimum, constraints.horizontal.logicalWidth), intrinsicWidthConstraints.maximum);
+    }
+    auto contentWidthAndMargin = geometry().inFlowWidthAndMargin(tableBox, constraints.horizontal, OverrideHorizontalValues { usedWidth, { } });
+
+    auto& displayBox = formattingState().displayBox(tableBox);
+    displayBox.setContentBoxWidth(contentWidthAndMargin.contentWidth);
+    displayBox.setHorizontalMargin(contentWidthAndMargin.usedMargin);
+    displayBox.setHorizontalComputedMargin(contentWidthAndMargin.computedMargin);
+}
+
+void TableWrapperBlockFormattingContext::computeHeightAndMarginForTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+    ASSERT(tableBox.isTableBox());
+    // Table is a special BFC content. Its height is mainly driven by the content. Computed height, min-height and max-height are all
+    // already been taken into account during the TFC layout.
+    auto usedHeight = geometry().contentHeightForFormattingContextRoot(tableBox);
+    auto heightAndMargin = geometry().inFlowHeightAndMargin(tableBox, constraints.horizontal, { usedHeight });
+
+    auto marginCollapse = this->marginCollapse();
+    auto collapsedAndPositiveNegativeValues = marginCollapse.collapsedVerticalValues(tableBox, heightAndMargin.nonCollapsedMargin);
+    // Cache the computed positive and negative margin value pair.
+    formattingState().setPositiveAndNegativeVerticalMargin(tableBox, collapsedAndPositiveNegativeValues.positiveAndNegativeVerticalValues);
+    auto verticalMargin = UsedVerticalMargin { heightAndMargin.nonCollapsedMargin, collapsedAndPositiveNegativeValues.collapsedValues };
+
+    auto& displayBox = formattingState().displayBox(tableBox);
+    displayBox.setTop(verticalPositionWithMargin(tableBox, verticalMargin, constraints.vertical));
+    displayBox.setContentBoxHeight(heightAndMargin.contentHeight);
+    displayBox.setVerticalMargin(verticalMargin);
+    // Adjust the previous sibling's margin bottom now that this box's vertical margin is computed.
+    MarginCollapse::updateMarginAfterForPreviousSibling(*this, marginCollapse, tableBox);
+}
+
+}
+}
+
+#endif

Added: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h (0 => 261793)


--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h	2020-05-17 16:17:45 UTC (rev 261793)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "BlockFormattingContext.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+namespace Layout {
+
+// This class implements the special block formatting context layout logic for the table wrapper.
+// https://www.w3.org/TR/CSS22/tables.html#model
+class TableWrapperBlockFormattingContext final : public BlockFormattingContext {
+    WTF_MAKE_ISO_ALLOCATED(TableWrapperBlockFormattingContext);
+public:
+    TableWrapperBlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState&);
+
+    void layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent&) final;
+
+private:
+    void layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent&);
+
+    void computeWidthAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
+    void computeHeightAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
+};
+
+}
+}
+
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to