Title: [260510] trunk/Source/WebCore
Revision
260510
Author
[email protected]
Date
2020-04-22 07:42:38 -0700 (Wed, 22 Apr 2020)

Log Message

[LFC][TFC] Introduce TableFormattingContext::computeAndDistributeExtraVerticalSpace
https://bugs.webkit.org/show_bug.cgi?id=210830

Reviewed by Antti Koivisto.

Add a dedicated function to compute preferred heights for the table rows.
This is in preparation for the 2 pass layout required to finalize row height.

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeBorderAndPadding):
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedPadding const):
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::layoutInFlowContent):
(WebCore::Layout::TableFormattingContext::layoutCell):
(WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
(WebCore::Layout::TableFormattingContext::setComputedGeometryForRows):
(WebCore::Layout::TableFormattingContext::setComputedGeometryForSections):
(WebCore::Layout::TableFormattingContext::positionTableCells): Deleted.
* layout/tableformatting/TableFormattingContext.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (260509 => 260510)


--- trunk/Source/WebCore/ChangeLog	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/ChangeLog	2020-04-22 14:42:38 UTC (rev 260510)
@@ -1,3 +1,27 @@
+2020-04-22  Zalan Bujtas  <[email protected]>
+
+        [LFC][TFC] Introduce TableFormattingContext::computeAndDistributeExtraVerticalSpace
+        https://bugs.webkit.org/show_bug.cgi?id=210830
+
+        Reviewed by Antti Koivisto.
+
+        Add a dedicated function to compute preferred heights for the table rows.
+        This is in preparation for the 2 pass layout required to finalize row height. 
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeBorderAndPadding):
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedPadding const):
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::TableFormattingContext::layoutCell):
+        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
+        (WebCore::Layout::TableFormattingContext::setComputedGeometryForRows):
+        (WebCore::Layout::TableFormattingContext::setComputedGeometryForSections):
+        (WebCore::Layout::TableFormattingContext::positionTableCells): Deleted.
+        * layout/tableformatting/TableFormattingContext.h:
+
 2020-04-22  Claudio Saavedra  <[email protected]>
 
         [GTK4] Several fixes to GdkEvent APIs for GTK4

Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (260509 => 260510)


--- trunk/Source/WebCore/layout/FormattingContext.cpp	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp	2020-04-22 14:42:38 UTC (rev 260510)
@@ -130,7 +130,7 @@
 {
     auto& displayBox = formattingState().displayBox(layoutBox);
     displayBox.setBorder(geometry().computedBorder(layoutBox));
-    displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint));
+    displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint.logicalWidth));
 }
 
 void FormattingContext::layoutOutOfFlowContent(InvalidationState& invalidationState, const OutOfFlowHorizontalConstraints& rootHorizontalConstraints, const VerticalConstraints& rootVerticalConstraints)

Modified: trunk/Source/WebCore/layout/FormattingContext.h (260509 => 260510)


--- trunk/Source/WebCore/layout/FormattingContext.h	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2020-04-22 14:42:38 UTC (rev 260510)
@@ -128,7 +128,7 @@
         LayoutUnit shrinkToFitWidth(const Box&, LayoutUnit availableWidth);
 
         Edges computedBorder(const Box&) const;
-        Optional<Edges> computedPadding(const Box&, const HorizontalConstraints&) const;
+        Optional<Edges> computedPadding(const Box&, LayoutUnit containingBlockWidth) const;
 
         ComputedHorizontalMargin computedHorizontalMargin(const Box&, const HorizontalConstraints&) const;
         ComputedVerticalMargin computedVerticalMargin(const Box&, const HorizontalConstraints&) const;

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (260509 => 260510)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2020-04-22 14:42:38 UTC (rev 260510)
@@ -1049,13 +1049,12 @@
     };
 }
 
-Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const LayoutUnit containingBlockWidth) const
 {
     if (!layoutBox.isPaddingApplicable())
         return WTF::nullopt;
 
     auto& style = layoutBox.style();
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
     return Edges {
         { valueForLength(style.paddingLeft(), containingBlockWidth), valueForLength(style.paddingRight(), containingBlockWidth) },

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (260509 => 260510)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-04-22 14:42:38 UTC (rev 260510)
@@ -61,55 +61,53 @@
 {
 }
 
-void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints&)
+void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
 {
     auto& grid = formattingState().tableGrid();
-    auto& columns = grid.columns();
-
+    auto& columnList = grid.columns().list();
+    auto& rowList = grid.rows().list();
+    // 1. Compute width and height for the grid.
     computeAndDistributeExtraHorizontalSpace(horizontalConstraints.logicalWidth);
-    // 1. Position each column.
-    // FIXME: This should also deal with collapsing borders etc.
+    computeAndDistributeExtraVerticalSpace(horizontalConstraints.logicalWidth, verticalConstraints.logicalHeight);
+    // 2. Position columns.
     auto horizontalSpacing = grid.horizontalSpacing();
     auto columnLogicalLeft = horizontalSpacing;
-    for (auto& column : columns.list()) {
+    for (auto& column : columnList) {
         column.setLogicalLeft(columnLogicalLeft);
-        columnLogicalLeft += (column.logicalWidth() + horizontalSpacing);
+        columnLogicalLeft += column.logicalWidth() + horizontalSpacing;
     }
-
-    // 2. Layout each table cell (and compute row height as well).
+    // 3. Position rows.
+    auto verticalSpacing = grid.verticalSpacing();
+    auto rowLogicalTop = verticalSpacing;
+    for (auto& row : rowList) {
+        row.setLogicalTop(rowLogicalTop);
+        rowLogicalTop += row.logicalHeight() + verticalSpacing;
+    }
+    // 4. Position cells.
+    for (auto& cell : grid.cells()) {
+        auto& cellDisplayBox = formattingState().displayBox(cell->box());
+        cellDisplayBox.setTop(rowList[cell->startRow()].logicalTop());
+        cellDisplayBox.setLeft(columnList[cell->startColumn()].logicalLeft());
+    }
+    // 5. Final table cell layout. At this point all percentage values can be resolved.
     auto& cellList = grid.cells();
     ASSERT(!cellList.isEmpty());
-    for (auto& cell : cellList) {
-        auto& cellBox = cell->box();
-        layoutCell(*cell, invalidationState, horizontalConstraints);
-        // FIXME: Add support for column and row spanning and this requires a 2 pass layout.
-        auto& row = grid.rows().list().at(cell->startRow());
-        row.setLogicalHeight(std::max(row.logicalHeight(), geometryForBox(cellBox).marginBoxHeight()));
-    }
-    // This is after the second pass when cell heights are fully computed.
-    auto rowLogicalTop = grid.verticalSpacing();
-    for (auto& row : grid.rows().list()) {
-        row.setLogicalTop(rowLogicalTop);
-        rowLogicalTop += (row.logicalHeight() + grid.verticalSpacing());
-    }
-
+    for (auto& cell : cellList)
+        layoutCell(*cell, invalidationState, horizontalConstraints.logicalWidth);
     // 3. Finalize size and position.
-    positionTableCells();
     setComputedGeometryForSections();
     setComputedGeometryForRows();
 }
 
-void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints)
+void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, LayoutUnit availableHorizontalSpace)
 {
     auto& cellBox = cell.box();
-    computeBorderAndPadding(cellBox, horizontalConstraints);
+    computeBorderAndPadding(cellBox, HorizontalConstraints { { }, availableHorizontalSpace });
     // Margins do not apply to internal table elements.
     auto& cellDisplayBox = formattingState().displayBox(cellBox);
     cellDisplayBox.setHorizontalMargin({ });
     cellDisplayBox.setHorizontalComputedMargin({ });
-    // Don't know the actual position yet.
-    cellDisplayBox.setTopLeft({ });
-    auto contentWidth = [&] {
+    auto availableSpaceForContent = [&] {
         auto& grid = formattingState().tableGrid();
         auto& columnList = grid.columns().list();
         auto logicalWidth = LayoutUnit { };
@@ -119,7 +117,7 @@
         logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
         return logicalWidth - cellDisplayBox.horizontalMarginBorderAndPadding();
     }();
-    cellDisplayBox.setContentBoxWidth(contentWidth);
+    cellDisplayBox.setContentBoxWidth(availableSpaceForContent);
 
     ASSERT(cellBox.establishesBlockFormattingContext());
     if (cellBox.hasInFlowOrFloatingChild()) {
@@ -133,46 +131,6 @@
     // FIXME: Check what to do with out-of-flow content.
 }
 
-void TableFormattingContext::positionTableCells()
-{
-    auto& grid = formattingState().tableGrid();
-    auto& rowList = grid.rows().list();
-    auto& columnList = grid.columns().list();
-    for (auto& cell : grid.cells()) {
-        auto& cellDisplayBox = formattingState().displayBox(cell->box());
-        cellDisplayBox.setTop(rowList.at(cell->startRow()).logicalTop());
-        cellDisplayBox.setLeft(columnList.at(cell->startColumn()).logicalLeft());
-    }
-}
-
-void TableFormattingContext::setComputedGeometryForRows()
-{
-    auto& grid = formattingState().tableGrid();
-    auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
-
-    for (auto& row : grid.rows().list()) {
-        auto& rowDisplayBox = formattingState().displayBox(row.box());
-        initializeDisplayBoxToBlank(rowDisplayBox);
-        rowDisplayBox.setContentBoxHeight(row.logicalHeight());
-        rowDisplayBox.setContentBoxWidth(rowWidth);
-        rowDisplayBox.setTop(row.logicalTop());
-    }
-}
-
-void TableFormattingContext::setComputedGeometryForSections()
-{
-    auto& grid = formattingState().tableGrid();
-    auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
-
-    for (auto& section : childrenOfType<Box>(root())) {
-        auto& sectionDisplayBox = formattingState().displayBox(section);
-        initializeDisplayBoxToBlank(sectionDisplayBox);
-        // FIXME: Size table sections properly.
-        sectionDisplayBox.setContentBoxWidth(sectionWidth);
-        sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
-    }
-}
-
 FormattingContext::IntrinsicWidthConstraints TableFormattingContext::computedIntrinsicWidthConstraints()
 {
     // Tables have a slighty different concept of shrink to fit. It's really only different with non-auto "width" values, where
@@ -479,7 +437,63 @@
     computeColumnWidths(ColumnWidthBalancingBase::MinimumWidth, horizontalSpaceToDistribute);
 }
 
+void TableFormattingContext::computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit>)
+{
+    auto& grid = formattingState().tableGrid();
+    auto& columns = grid.columns().list();
+    auto& rows = grid.rows();
+
+    Vector<float> rownHeights;
+    // 1. Collect initial row heights.
+    for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
+        float maximumColumnHeight = 0;
+        for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
+            auto& slot = *grid.slot({ columnIndex, rowIndex });
+            if (slot.isColumnSpanned())
+                continue;
+            auto invalidationState = InvalidationState { };
+            layoutCell(slot.cell(), invalidationState, availableHorizontalSpace);
+            maximumColumnHeight = std::max<float>(maximumColumnHeight, geometryForBox(slot.cell().box()).height());
+        }
+        // <tr style="height: 10px"> is considered as min height.
+        auto computedRowHeight = geometry().computedContentHeight(rows.list()[rowIndex].box(), { }).valueOr(LayoutUnit { });
+        // FIXME: add support for baseline syncing.
+        rownHeights.append(std::max(maximumColumnHeight, computedRowHeight.toFloat()));
+    }
+
+    for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex)
+        grid.rows().list()[rowIndex].setLogicalHeight(LayoutUnit { rownHeights[rowIndex] });
 }
+
+void TableFormattingContext::setComputedGeometryForRows()
+{
+    auto& grid = formattingState().tableGrid();
+    auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
+
+    for (auto& row : grid.rows().list()) {
+        auto& rowDisplayBox = formattingState().displayBox(row.box());
+        initializeDisplayBoxToBlank(rowDisplayBox);
+        rowDisplayBox.setContentBoxHeight(row.logicalHeight());
+        rowDisplayBox.setContentBoxWidth(rowWidth);
+        rowDisplayBox.setTop(row.logicalTop());
+    }
 }
 
+void TableFormattingContext::setComputedGeometryForSections()
+{
+    auto& grid = formattingState().tableGrid();
+    auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
+
+    for (auto& section : childrenOfType<Box>(root())) {
+        auto& sectionDisplayBox = formattingState().displayBox(section);
+        initializeDisplayBoxToBlank(sectionDisplayBox);
+        // FIXME: Size table sections properly.
+        sectionDisplayBox.setContentBoxWidth(sectionWidth);
+        sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
+    }
+}
+
+}
+}
+
 #endif

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h (260509 => 260510)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-04-22 14:42:38 UTC (rev 260510)
@@ -60,7 +60,7 @@
     TableFormattingContext::Geometry geometry() const { return Geometry(*this); }
 
     IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
-    void layoutCell(const TableGrid::Cell&, InvalidationState&, const HorizontalConstraints&);
+    void layoutCell(const TableGrid::Cell&, InvalidationState&, LayoutUnit availableHorizontalSpace);
     void positionTableCells();
     void setComputedGeometryForRows();
     void setComputedGeometryForSections();
@@ -68,6 +68,7 @@
     void ensureTableGrid();
     IntrinsicWidthConstraints computedPreferredWidthForColumns();
     void computeAndDistributeExtraHorizontalSpace(LayoutUnit availableHorizontalSpace);
+    void computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> availableVerticalSpace);
 
     void initializeDisplayBoxToBlank(Display::Box&) const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to