Title: [278294] trunk/Source/WebCore
Revision
278294
Author
za...@apple.com
Date
2021-05-31 21:31:04 -0700 (Mon, 31 May 2021)

Log Message

[LFC][TFC] Decouple stretching and final cell layouts
https://bugs.webkit.org/show_bug.cgi?id=226452

Reviewed by Antti Koivisto.

Stretching layout is slightly different from the final cell layout.

* layout/formattingContexts/table/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
(WebCore::Layout::TableFormattingContext::computeAndDistributeExtraSpace):
(WebCore::Layout::TableFormattingContext::layoutCell): Deleted.
* layout/formattingContexts/table/TableFormattingContext.h:
* layout/formattingContexts/table/TableFormattingGeometry.cpp:
(WebCore::Layout::TableFormattingGeometry::horizontalSpaceForCellContent const):
(WebCore::Layout::TableFormattingGeometry::verticalSpaceForCellContent const):
* layout/formattingContexts/table/TableFormattingGeometry.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (278293 => 278294)


--- trunk/Source/WebCore/ChangeLog	2021-06-01 02:55:58 UTC (rev 278293)
+++ trunk/Source/WebCore/ChangeLog	2021-06-01 04:31:04 UTC (rev 278294)
@@ -1,5 +1,24 @@
 2021-05-31  Alan Bujtas  <za...@apple.com>
 
+        [LFC][TFC] Decouple stretching and final cell layouts
+        https://bugs.webkit.org/show_bug.cgi?id=226452
+
+        Reviewed by Antti Koivisto.
+
+        Stretching layout is slightly different from the final cell layout.
+
+        * layout/formattingContexts/table/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
+        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraSpace):
+        (WebCore::Layout::TableFormattingContext::layoutCell): Deleted.
+        * layout/formattingContexts/table/TableFormattingContext.h:
+        * layout/formattingContexts/table/TableFormattingGeometry.cpp:
+        (WebCore::Layout::TableFormattingGeometry::horizontalSpaceForCellContent const):
+        (WebCore::Layout::TableFormattingGeometry::verticalSpaceForCellContent const):
+        * layout/formattingContexts/table/TableFormattingGeometry.h:
+
+2021-05-31  Alan Bujtas  <za...@apple.com>
+
         [LFC] Tighten the constraint classes (ConstraintsForInFlowContent/ConstraintsForOutOfFlowContent)
         https://bugs.webkit.org/show_bug.cgi?id=226435
 

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp (278293 => 278294)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp	2021-06-01 02:55:58 UTC (rev 278293)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp	2021-06-01 04:31:04 UTC (rev 278294)
@@ -81,6 +81,7 @@
     auto& grid = formattingState().tableGrid();
     auto& columnList = grid.columns().list();
     auto& rowList = grid.rows().list();
+    auto& formattingGeometry = this->formattingGeometry();
     // Final table cell layout. At this point all percentage values can be resolved.
     auto sectionOffset = LayoutUnit { };
     auto* currentSection = &rowList.first().box().parent();
@@ -93,16 +94,30 @@
             // While the grid is a continuous flow of rows, in the display tree they are relative to their sections.
             sectionOffset = rowList[cell->startRow()].logicalTop();
         }
+        // Internal table elements do not have margins.
+        cellBoxGeometry.setHorizontalMargin({ });
+        cellBoxGeometry.setVerticalMargin({ });
+
+        cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(*cell));
+        cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
         cellBoxGeometry.setLogicalTop(rowList[cell->startRow()].logicalTop() - sectionOffset);
         cellBoxGeometry.setLogicalLeft(columnList[cell->startColumn()].logicalLeft());
+        cellBoxGeometry.setContentBoxWidth(formattingGeometry.horizontalSpaceForCellContent(*cell));
 
-        auto availableVerticalSpace = rowList[cell->startRow()].logicalHeight();
-        for (size_t rowIndex = cell->startRow() + 1; rowIndex < cell->endRow(); ++rowIndex)
-            availableVerticalSpace += rowList[rowIndex].logicalHeight();
-        availableVerticalSpace += (cell->rowSpan() - 1) * grid.verticalSpacing();
-        layoutCell(*cell, availableHorizontalSpace);
+        if (cellBox.hasInFlowOrFloatingChild()) {
+            auto invalidationState = InvalidationState { };
+            // FIXME: This should probably be part of the invalidation state to indicate when we re-layout the cell multiple times as part of the multi-pass table algorithm.
+            auto& floatingStateForCellContent = layoutState().ensureBlockFormattingState(cellBox).floatingState();
+            floatingStateForCellContent.clear();
+            LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, formattingGeometry.constraintsForInFlowContent(cellBox));
+        }
+        cellBoxGeometry.setContentBoxHeight(formattingGeometry.verticalSpaceForCellContent(*cell));
 
         auto computeIntrinsicVerticalPaddingForCell = [&] {
+            auto cellLogicalHeight = rowList[cell->startRow()].logicalHeight();
+            for (size_t rowIndex = cell->startRow() + 1; rowIndex < cell->endRow(); ++rowIndex)
+                cellLogicalHeight += rowList[rowIndex].logicalHeight();
+            cellLogicalHeight += (cell->rowSpan() - 1) * grid.verticalSpacing();
             // Intrinsic padding is the extra padding for the cell box when it is shorter than the row. Cell boxes have to
             // fill the available vertical space
             // e.g <td height=100px></td><td height=1px></td>
@@ -117,7 +132,7 @@
 
             switch (cellBox.style().verticalAlign()) {
             case VerticalAlign::Middle: {
-                auto intrinsicVerticalPadding = std::max(0_lu, availableVerticalSpace - cellBoxGeometry.verticalMarginBorderAndPadding() - cellBoxGeometry.contentBoxHeight());
+                auto intrinsicVerticalPadding = std::max(0_lu, cellLogicalHeight - cellBoxGeometry.verticalMarginBorderAndPadding() - cellBoxGeometry.contentBoxHeight());
                 intrinsicPaddingTop = intrinsicVerticalPadding / 2;
                 intrinsicPaddingBottom = intrinsicVerticalPadding / 2;
                 break;
@@ -126,7 +141,7 @@
                 auto rowBaseline = LayoutUnit { rowList[cell->startRow()].baseline() };
                 auto cellBaseline = LayoutUnit { cell->baseline() };
                 intrinsicPaddingTop = std::max(0_lu, rowBaseline - cellBaseline - cellBoxGeometry.borderTop());
-                intrinsicPaddingBottom = std::max(0_lu, availableVerticalSpace - cellBoxGeometry.verticalMarginBorderAndPadding() - intrinsicPaddingTop - cellBoxGeometry.contentBoxHeight());
+                intrinsicPaddingBottom = std::max(0_lu, cellLogicalHeight - cellBoxGeometry.verticalMarginBorderAndPadding() - intrinsicPaddingTop - cellBoxGeometry.contentBoxHeight());
                 break;
             }
             default:
@@ -278,50 +293,6 @@
     }
 }
 
-void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, LayoutUnit availableHorizontalSpace)
-{
-    ASSERT(cell.box().establishesBlockFormattingContext());
-
-    auto& formattingGeometry = this->formattingGeometry();
-    auto& grid = formattingState().tableGrid();
-    auto& cellBox = cell.box();
-    auto& cellBoxGeometry = formattingState().boxGeometry(cellBox);
-
-    cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(cell));
-    cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
-    // Internal table elements do not have margins.
-    cellBoxGeometry.setHorizontalMargin({ });
-    cellBoxGeometry.setVerticalMargin({ });
-
-    auto availableSpaceForContent = [&] {
-        auto& columnList = grid.columns().list();
-        auto logicalWidth = LayoutUnit { };
-        for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
-            logicalWidth += columnList.at(columnIndex).logicalWidth();
-        // No column spacing when spanning.
-        logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
-        return logicalWidth - cellBoxGeometry.horizontalMarginBorderAndPadding();
-    }();
-    cellBoxGeometry.setContentBoxWidth(availableSpaceForContent);
-
-    if (cellBox.hasInFlowOrFloatingChild()) {
-        auto constraintsForCellContent = formattingGeometry.constraintsForInFlowContent(cellBox);
-        auto invalidationState = InvalidationState { };
-        // FIXME: This should probably be part of the invalidation state to indicate when we re-layout the cell multiple times as part of the multi-pass table algorithm.
-        auto& floatingStateForCellContent = layoutState().ensureBlockFormattingState(cellBox).floatingState();
-        floatingStateForCellContent.clear();
-        LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, constraintsForCellContent);
-    }
-    auto contentBoxHeight = formattingGeometry.cellBoxContentHeight(cellBox);
-    if (auto computedHeight = formattingGeometry.computedHeight(cellBox)) {
-        auto heightUsesBorderBox = layoutState().inQuirksMode() || cellBox.style().boxSizing() == BoxSizing::BorderBox;
-        if (heightUsesBorderBox)
-            *computedHeight -= cellBoxGeometry.verticalMarginBorderAndPadding();
-        contentBoxHeight = std::max(contentBoxHeight, *computedHeight);
-    }
-    cellBoxGeometry.setContentBoxHeight(contentBoxHeight);
-}
-
 IntrinsicWidthConstraints TableFormattingContext::computedIntrinsicWidthConstraints()
 {
     ASSERT(!root().isSizeContainmentBox());
@@ -454,6 +425,7 @@
         columnLogicalLeft += distributedHorizontalSpaces[columnIndex] + grid.horizontalSpacing();
     }
 
+    auto& formattingGeometry = this->formattingGeometry();
     // Rows second.
     auto& rows = grid.rows().list();
     for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
@@ -461,13 +433,26 @@
             auto& slot = *grid.slot({ columnIndex, rowIndex });
             if (slot.isRowSpanned())
                 continue;
-            layoutCell(slot.cell(), availableHorizontalSpace);
+            auto layoutCellContent = [&](auto& cell) {
+                auto& cellBox = cell.box();
+                auto& cellBoxGeometry = formattingState().boxGeometry(cellBox);
+                cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(cell));
+                cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
+                cellBoxGeometry.setContentBoxWidth(formattingGeometry.horizontalSpaceForCellContent(cell));
+
+                if (cellBox.hasInFlowOrFloatingChild()) {
+                    auto invalidationState = InvalidationState { };
+                    LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, formattingGeometry.constraintsForInFlowContent(cellBox));
+                }
+                cellBoxGeometry.setContentBoxHeight(formattingGeometry.verticalSpaceForCellContent(cell));
+            };
+            layoutCellContent(slot.cell());
             if (slot.hasRowSpan())
                 continue;
             // The minimum height of a row (without spanning-related height distribution) is defined as the height of an hypothetical
             // linebox containing the cells originating in the row.
             auto& cell = slot.cell();
-            cell.setBaseline(formattingGeometry().usedBaselineForCell(cell.box()));
+            cell.setBaseline(formattingGeometry.usedBaselineForCell(cell.box()));
         }
     }
 

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.h (278293 => 278294)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.h	2021-06-01 02:55:58 UTC (rev 278293)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.h	2021-06-01 04:31:04 UTC (rev 278294)
@@ -72,7 +72,6 @@
     TableFormattingContext::TableLayout tableLayout() const { return TableLayout(*this, formattingState().tableGrid()); }
 
     IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
-    void layoutCell(const TableGrid::Cell&, LayoutUnit availableHorizontalSpace);
     void setUsedGeometryForCells(LayoutUnit availableHorizontalSpace);
     void setUsedGeometryForRows(LayoutUnit availableHorizontalSpace);
     void setUsedGeometryForSections(const ConstraintsForInFlowContent&);

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp (278293 => 278294)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp	2021-06-01 02:55:58 UTC (rev 278293)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp	2021-06-01 04:31:04 UTC (rev 278294)
@@ -166,7 +166,36 @@
     return formattingContext().geometryForBox(cellBox).contentBoxBottom();
 }
 
+LayoutUnit TableFormattingGeometry::horizontalSpaceForCellContent(const TableGrid::Cell& cell) const
+{
+    auto& grid = formattingContext().formattingState().tableGrid();
+    auto& columnList = grid.columns().list();
+    auto logicalWidth = LayoutUnit { };
+    for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
+        logicalWidth += columnList.at(columnIndex).logicalWidth();
+    // No column spacing when spanning.
+    logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
+    auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
+    logicalWidth -= (cellBoxGeometry.horizontalBorder() + cellBoxGeometry.horizontalPadding().value_or(0));
+    return logicalWidth;
 }
+
+LayoutUnit TableFormattingGeometry::verticalSpaceForCellContent(const TableGrid::Cell& cell) const
+{
+    auto& cellBox = cell.box();
+    auto contentHeight = cellBoxContentHeight(cellBox);
+    auto computedHeight = this->computedHeight(cellBox);
+    if (!computedHeight)
+        return contentHeight;
+    auto heightUsesBorderBox = layoutState().inQuirksMode() || cellBox.style().boxSizing() == BoxSizing::BorderBox;
+    if (heightUsesBorderBox) {
+        auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
+        *computedHeight -= (cellBoxGeometry.verticalBorder() + cellBoxGeometry.verticalPadding().value_or(0));
+    }
+    return std::max(contentHeight, *computedHeight);
 }
 
+}
+}
+
 #endif

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h (278293 => 278294)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h	2021-06-01 02:55:58 UTC (rev 278293)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h	2021-06-01 04:31:04 UTC (rev 278294)
@@ -44,6 +44,8 @@
     std::optional<LayoutUnit> computedColumnWidth(const ContainerBox& columnBox) const;
     IntrinsicWidthConstraints intrinsicWidthConstraintsForCell(const TableGrid::Cell&) const;
     InlineLayoutUnit usedBaselineForCell(const ContainerBox& cellBox) const;
+    LayoutUnit horizontalSpaceForCellContent(const TableGrid::Cell&) const;
+    LayoutUnit verticalSpaceForCellContent(const TableGrid::Cell&) const;
 
 private:
     const TableFormattingContext& formattingContext() const { return downcast<TableFormattingContext>(FormattingGeometry::formattingContext()); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to