[LFC][TFC] Layout and position the cell boxes
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Aug 2019 22:21:23 +0000 (22:21 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Aug 2019 22:21:23 +0000 (22:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201192
<rdar://problem/54758638>

Reviewed by Antti Koivisto.

Add a very basic (and faily incomplete) table cell layout logic. This is mostly WIP.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::contentHeightForFormattingContextRoot):
(WebCore::Layout::contentHeightForFormattingContextRoot): Deleted.
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::layout const):
(WebCore::Layout::TableFormattingContext::computedTableWidth const):
* layout/tableformatting/TableFormattingContext.h:
* layout/tableformatting/TableFormattingContextGeometry.cpp: Copied from Source/WebCore/layout/tableformatting/TableFormattingContext.h.
(WebCore::Layout::TableFormattingContext::Geometry::tableCellHeightAndMargin):
* layout/tableformatting/TableGrid.cpp:
(WebCore::Layout::TableGrid::Column::setLogicalLeft):
(WebCore::Layout::TableGrid::Column::logicalLeft const):
* layout/tableformatting/TableGrid.h:
(WebCore::Layout::TableGrid::Column::logicalRight const):
(WebCore::Layout::TableGrid::Row::setLogicalTop):
(WebCore::Layout::TableGrid::Row::logicalTop const):
(WebCore::Layout::TableGrid::Row::setLogicalHeight):
(WebCore::Layout::TableGrid::Row::logicalHeight const):
(WebCore::Layout::TableGrid::Row::logicalBottom const):

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

Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/FormattingContext.h
Source/WebCore/layout/FormattingContextGeometry.cpp
Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
Source/WebCore/layout/tableformatting/TableFormattingContext.h
Source/WebCore/layout/tableformatting/TableFormattingContextGeometry.cpp [new file with mode: 0644]
Source/WebCore/layout/tableformatting/TableGrid.cpp
Source/WebCore/layout/tableformatting/TableGrid.h

index b2c29b1..c8a7c29 100644 (file)
@@ -1,3 +1,36 @@
+2019-08-27  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][TFC] Layout and position the cell boxes
+        https://bugs.webkit.org/show_bug.cgi?id=201192
+        <rdar://problem/54758638>
+
+        Reviewed by Antti Koivisto.
+
+        Add a very basic (and faily incomplete) table cell layout logic. This is mostly WIP.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::contentHeightForFormattingContextRoot):
+        (WebCore::Layout::contentHeightForFormattingContextRoot): Deleted.
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::layout const):
+        (WebCore::Layout::TableFormattingContext::computedTableWidth const):
+        * layout/tableformatting/TableFormattingContext.h:
+        * layout/tableformatting/TableFormattingContextGeometry.cpp: Copied from Source/WebCore/layout/tableformatting/TableFormattingContext.h.
+        (WebCore::Layout::TableFormattingContext::Geometry::tableCellHeightAndMargin):
+        * layout/tableformatting/TableGrid.cpp:
+        (WebCore::Layout::TableGrid::Column::setLogicalLeft):
+        (WebCore::Layout::TableGrid::Column::logicalLeft const):
+        * layout/tableformatting/TableGrid.h:
+        (WebCore::Layout::TableGrid::Column::logicalRight const):
+        (WebCore::Layout::TableGrid::Row::setLogicalTop):
+        (WebCore::Layout::TableGrid::Row::logicalTop const):
+        (WebCore::Layout::TableGrid::Row::setLogicalHeight):
+        (WebCore::Layout::TableGrid::Row::logicalHeight const):
+        (WebCore::Layout::TableGrid::Row::logicalBottom const):
+
 2019-08-27  Mark Lam  <mark.lam@apple.com>
 
         Refactor to use VM& instead of VM* at as many places as possible.
index 8a540d4..1c4c4d0 100644 (file)
@@ -1417,6 +1417,7 @@ layout/layouttree/LayoutContainer.cpp
 layout/layouttree/LayoutReplaced.cpp
 layout/layouttree/LayoutTreeBuilder.cpp
 layout/tableformatting/TableFormattingContext.cpp
+layout/tableformatting/TableFormattingContextGeometry.cpp
 layout/tableformatting/TableFormattingState.cpp
 layout/tableformatting/TableGrid.cpp
 layout/tableformatting/TableInvalidation.cpp
index 88a6b8c..97a90b2 100644 (file)
                11C5F134200527F90001AE60 /* RenderTreeBuilderMathML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderMathML.h; sourceTree = "<group>"; };
                11CB2786203BA570004A1DC9 /* RenderTreeBuilderFullScreen.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderFullScreen.cpp; sourceTree = "<group>"; };
                11CB2787203BA570004A1DC9 /* RenderTreeBuilderFullScreen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderFullScreen.h; sourceTree = "<group>"; };
+               11D19C2E23159BAE008F24D3 /* TableFormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableFormattingContextGeometry.cpp; sourceTree = "<group>"; };
                11E067EB1E62461300162D16 /* SimpleLineLayoutCoverage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutCoverage.cpp; sourceTree = "<group>"; };
                11E067ED1E6246E500162D16 /* SimpleLineLayoutCoverage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutCoverage.h; sourceTree = "<group>"; };
                11FF02D520BA3C810083F25B /* Verification.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Verification.cpp; sourceTree = "<group>"; };
                        children = (
                                6FC5CA9422E3599400B13E11 /* TableFormattingContext.cpp */,
                                6FC5CA9522E3599400B13E11 /* TableFormattingContext.h */,
+                               11D19C2E23159BAE008F24D3 /* TableFormattingContextGeometry.cpp */,
                                6FC5CA9222E3599300B13E11 /* TableFormattingState.cpp */,
                                6FC5CA9622E3599500B13E11 /* TableFormattingState.h */,
                                6F5B7EAA2300A79E0067D9C3 /* TableGrid.cpp */,
                                84730D911248F0B300D3A9C9 /* LightSource.h in Headers */,
                                B22279650D00BF220071B782 /* LinearGradientAttributes.h in Headers */,
                                AB31C91E10AE1B8E000C7B92 /* LineClampValue.h in Headers */,
+                               E484A33E23055325009ADE6A /* LineLayoutInterfaceTextBoxes.h in Headers */,
                                FFEFAB2A18380DA000514534 /* LineLayoutState.h in Headers */,
                                FFDBC047183D27B700407109 /* LineWidth.h in Headers */,
                                CBA9DC0B1DF44DF40005675C /* LinkHeader.h in Headers */,
                                B2C3DA3E0D006C1D00EF6F26 /* TextCodecLatin1.h in Headers */,
                                57EF5E601D20C83900171E60 /* TextCodecReplacement.h in Headers */,
                                B2C3DA400D006C1D00EF6F26 /* TextCodecUserDefined.h in Headers */,
-                               E484A33E23055325009ADE6A /* LineLayoutInterfaceTextBoxes.h in Headers */,
                                B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */,
                                9343CB8212F25E510033C5EE /* TextCodecUTF8.h in Headers */,
                                142B97CA13138943008BEF4B /* TextControlInnerElements.h in Headers */,
index 6d802ab..370b72b 100644 (file)
@@ -112,6 +112,8 @@ protected:
 
         static FormattingContext::IntrinsicWidthConstraints constrainByMinMaxWidth(const Box&, IntrinsicWidthConstraints);
 
+        static LayoutUnit contentHeightForFormattingContextRoot(const LayoutState&, const Box&);
+
     protected:
         enum class HeightType { Min, Max, Normal };
         static Optional<LayoutUnit> computedHeightValue(const LayoutState&, const Box&, HeightType);
index 8e44018..39f6462 100644 (file)
@@ -89,7 +89,7 @@ Optional<LayoutUnit> FormattingContext::Geometry::computedHeightValue(const Layo
     return valueForLength(height, *containingBlockHeightValue);
 }
 
-static LayoutUnit contentHeightForFormattingContextRoot(const LayoutState& layoutState, const Box& layoutBox)
+LayoutUnit FormattingContext::Geometry::contentHeightForFormattingContextRoot(const LayoutState& layoutState, const Box& layoutBox)
 {
     ASSERT(isHeightAuto(layoutBox) && (layoutBox.establishesFormattingContext() || layoutBox.isDocumentBox()));
 
@@ -126,9 +126,9 @@ static LayoutUnit contentHeightForFormattingContextRoot(const LayoutState& layou
     } else if (formattingRootContainer.establishesTableFormattingContext()) {
         auto& rowList = downcast<TableFormattingState>(layoutState.establishedFormattingState(formattingRootContainer)).tableGrid().rows();
         ASSERT(!rowList.isEmpty());
-        top += rowList.first().offset;
+        top += rowList.first().logicalTop();
         auto& lastRow = rowList.last();
-        bottom += lastRow.offset + lastRow.height;
+        bottom += lastRow.logicalBottom();
     } else
         ASSERT_NOT_REACHED();
 
index 3b50bea..7fed0dd 100644 (file)
@@ -45,7 +45,45 @@ TableFormattingContext::TableFormattingContext(const Box& formattingContextRoot,
 
 void TableFormattingContext::layout() const
 {
-    ASSERT(!formattingState().tableGrid().cells().isEmpty());
+    auto& grid = formattingState().tableGrid();
+    auto& cellList = grid.cells();
+    ASSERT(!cellList.isEmpty());
+    // Layout and position each table cell (and compute row height as well).
+    auto& layoutState = this->layoutState();
+    auto& columnList = grid.columnsContext().columns();
+    auto& rowList = grid.rows();
+    for (auto& cell : cellList) {
+        auto& cellLayoutBox = cell->tableCellBox;
+        ASSERT(cellLayoutBox.establishesBlockFormattingContext());
+
+        auto& cellDisplayBox = layoutState.displayBoxForLayoutBox(cellLayoutBox);
+        // FIXME: Add support for column and row spanning.
+        auto cellPosition = cell->position;
+        auto& row = rowList.at(cellPosition.y());
+        auto& column = columnList.at(cellPosition.x());
+        cellDisplayBox.setContentBoxWidth(column.logicalWidth());
+        // FIXME: Do not use blanks.
+        cellDisplayBox.setBorder({ });
+        cellDisplayBox.setPadding({ });
+        cellDisplayBox.setHorizontalMargin({ });
+        cellDisplayBox.setHorizontalComputedMargin({ });
+
+        cellDisplayBox.setTopLeft({ column.logicalLeft(), row.logicalTop() });
+
+        layoutState.createFormattingContext(cellLayoutBox)->layout();
+
+        // FIXME: This requires a 2 pass layout.
+        auto heightAndMargin = Geometry::tableCellHeightAndMargin(layoutState, cellLayoutBox);
+        cellDisplayBox.setContentBoxHeight(heightAndMargin.height);
+        cellDisplayBox.setVerticalMargin({ heightAndMargin.nonCollapsedMargin, { } });
+
+        row.setLogicalHeight(std::max(row.logicalHeight(), heightAndMargin.height));
+        // FIXME: This also requires spanning support/check.
+        if (!cellPosition.x() && cellPosition.y()) {
+            auto& previousRow = rowList.at(cellPosition.y() - 1);
+            row.setLogicalTop(previousRow.logicalBottom());
+        }
+    }
 }
 
 FormattingContext::IntrinsicWidthConstraints TableFormattingContext::computedIntrinsicWidthConstraints() const
@@ -163,7 +201,13 @@ LayoutUnit TableFormattingContext::computedTableWidth() const
             distributeAvailableWidth(*width - tableWidthConstraints.minimum);
         }
     }
-
+    // FIXME: This should also deal with collapsing borders etc.
+    LayoutUnit columnLogicalLeft;
+    auto& columns = columnsContext.columns();
+    for (auto& column : columns) {
+        column.setLogicalLeft(columnLogicalLeft);
+        columnLogicalLeft += column.logicalWidth();
+    }
     return usedWidth;
 }
 
index 1ea2242..576b035 100644 (file)
@@ -43,6 +43,11 @@ public:
     void layout() const override;
 
 private:
+    class Geometry : public FormattingContext::Geometry {
+    public:
+        static HeightAndMargin tableCellHeightAndMargin(const LayoutState&, const Box&);
+    };
+
     IntrinsicWidthConstraints computedIntrinsicWidthConstraints() const override;
     LayoutUnit computedTableWidth() const;
 
diff --git a/Source/WebCore/layout/tableformatting/TableFormattingContextGeometry.cpp b/Source/WebCore/layout/tableformatting/TableFormattingContextGeometry.cpp
new file mode 100644 (file)
index 0000000..440985c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 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 "TableFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FormattingContext.h"
+#include "LayoutBox.h"
+#include "LayoutState.h"
+
+namespace WebCore {
+namespace Layout {
+
+HeightAndMargin TableFormattingContext::Geometry::tableCellHeightAndMargin(const LayoutState& layoutState, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isInFlow());
+
+    auto height = computedHeightValue(layoutState, layoutBox, HeightType::Normal);
+    if (!height)
+        height = Geometry::contentHeightForFormattingContextRoot(layoutState, layoutBox);
+
+    // FIXME: Compute vertical margin values.
+    return HeightAndMargin { *height, { } };
+}
+
+}
+}
+
+#endif
index 3e6bdf3..21411be 100644 (file)
@@ -63,6 +63,20 @@ LayoutUnit TableGrid::Column::logicalWidth() const
     return m_computedLogicalWidth;
 }
 
+void TableGrid::Column::setLogicalLeft(LayoutUnit computedLogicalLeft)
+{
+#ifndef NDEBUG
+    m_hasComputedLeft = true;
+#endif
+    m_computedLogicalLeft = computedLogicalLeft;
+}
+
+LayoutUnit TableGrid::Column::logicalLeft() const
+{
+    ASSERT(m_hasComputedLeft);
+    return m_computedLogicalLeft;
+}
+
 void TableGrid::ColumnsContext::addColumn()
 {
     m_columns.append({ });
index 6bdeb78..8168d6c 100644 (file)
@@ -71,15 +71,22 @@ public:
         void setLogicalWidth(LayoutUnit);
         LayoutUnit logicalWidth() const;
 
+        void setLogicalLeft(LayoutUnit);
+        LayoutUnit logicalLeft() const;
+
+        LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
+
     private:
         friend class ColumnsContext;
         Column() = default;
 
         FormattingContext::IntrinsicWidthConstraints m_widthConstraints;
         LayoutUnit m_computedLogicalWidth;
+        LayoutUnit m_computedLogicalLeft;
 #ifndef NDEBUG
         bool m_hasWidthConstraints { false };
         bool m_hasComputedWidth { false };
+        bool m_hasComputedLeft { false };
 #endif
     };
 
@@ -101,8 +108,18 @@ public:
     ColumnsContext& columnsContext() { return m_columnsContext; }
 
     struct Row {
-        LayoutUnit offset;
-        LayoutUnit height;
+    public:
+        void setLogicalTop(LayoutUnit logicalTop) { m_logicalTop = logicalTop; }
+        LayoutUnit logicalTop() const { return m_logicalTop; }
+
+        void setLogicalHeight(LayoutUnit logicalHeight) { m_logicalHeight = logicalHeight; }
+        LayoutUnit logicalHeight() const { return m_logicalHeight; }
+
+        LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
+
+    private:
+        LayoutUnit m_logicalTop;
+        LayoutUnit m_logicalHeight;
     };
     using RowList = WTF::Vector<Row>;
     RowList& rows() { return m_rows; }