Title: [278537] trunk
Revision
278537
Author
[email protected]
Date
2021-06-06 08:15:40 -0700 (Sun, 06 Jun 2021)

Log Message

[LFC][TFC] Adopt a less quirky fixed column width space distribution
https://bugs.webkit.org/show_bug.cgi?id=226696

Reviewed by Antti Koivisto.

Source/WebCore:

This patch adopts a less quirky space distribution model where any fixed cell width
makes the column fixed (as opposed to just when <col> has fixed with).
This distribution model matches both Chrome and Firefox.
It also enables us to simplify some of the distribution logic by using the same set of values (min vs max)
as the base for the distribution ratio.

Test: fast/layoutformattingcontext/table-fixed-width-variations-simple.html

* layout/formattingContexts/table/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::computedPreferredWidthForColumns): Collect the fixed with values from the cells too now.
* layout/formattingContexts/table/TableFormattingGeometry.cpp:
(WebCore::Layout::TableFormattingGeometry::intrinsicWidthConstraintsForCellContent const):
(WebCore::Layout::TableFormattingGeometry::intrinsicWidthConstraintsForCell const): Deleted.
* layout/formattingContexts/table/TableFormattingGeometry.h:
* layout/formattingContexts/table/TableGrid.cpp:
(WebCore::Layout::TableGrid::appendCell):
(WebCore::Layout::TableGrid::Column::isFixedWidth const): Deleted.
(WebCore::Layout::TableGrid::Columns::hasFixedColumnsOnly const): Deleted.
(WebCore::Layout::TableGrid::Cell::isFixedWidth const): Deleted.
* layout/formattingContexts/table/TableGrid.h:
(WebCore::Layout::TableGrid::Column::setFixedWidth):
(WebCore::Layout::TableGrid::Column::fixedWidth const):
(WebCore::Layout::TableGrid::Columns::logicalWidth const):
(WebCore::Layout::TableGrid::Column::setHasFixedWidthCell): Deleted.
(WebCore::Layout::TableGrid::Column::hasFixedWidthCell const): Deleted.
* layout/formattingContexts/table/TableLayout.cpp:
(WebCore::Layout::TableFormattingContext::TableLayout::distributedHorizontalSpace): Adjust the distribution values based on whether
the column has fixed width and use max/max in both fixed and non-fixed cases.

LayoutTests:

* TestExpectations: We don't match current WebKit space distribution anymore.
* fast/layoutformattingcontext/table-fixed-width-variations-simple-expected.html: Added.
* fast/layoutformattingcontext/table-fixed-width-variations-simple.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (278536 => 278537)


--- trunk/LayoutTests/ChangeLog	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/LayoutTests/ChangeLog	2021-06-06 15:15:40 UTC (rev 278537)
@@ -1,3 +1,14 @@
+2021-06-06  Alan Bujtas  <[email protected]>
+
+        [LFC][TFC] Adopt a less quirky fixed column width space distribution
+        https://bugs.webkit.org/show_bug.cgi?id=226696
+
+        Reviewed by Antti Koivisto.
+
+        * TestExpectations: We don't match current WebKit space distribution anymore.
+        * fast/layoutformattingcontext/table-fixed-width-variations-simple-expected.html: Added.
+        * fast/layoutformattingcontext/table-fixed-width-variations-simple.html: Added.
+
 2021-06-05  Cameron McCormack  <[email protected]>
 
         Diff aspect-ratio property values correctly

Modified: trunk/LayoutTests/TestExpectations (278536 => 278537)


--- trunk/LayoutTests/TestExpectations	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/LayoutTests/TestExpectations	2021-06-06 15:15:40 UTC (rev 278537)
@@ -4876,6 +4876,7 @@
 
 webkit.org/b/226002 fast/layoutformattingcontext/table-simple-row-height.html [ Skip ]
 webkit.org/b/226364 fast/layoutformattingcontext/table-with-percent-columns-and-spacing.html [ Skip ]
+[ Debug ] fast/layoutformattingcontext/table-fixed-width-with-max-distribution.html [ Skip ]
 
 # This webstorage test has crashed since it was imported.
 imported/w3c/web-platform-tests/webstorage/storage_session_setitem_quotaexceedederr.window.html [ Skip ]

Added: trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple-expected.html (0 => 278537)


--- trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple-expected.html	2021-06-06 15:15:40 UTC (rev 278537)
@@ -0,0 +1,9 @@
+<!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+ background-color: green;
+ width: 100px;
+ height: 350px;
+}
+</style>
+<div></div>

Added: trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple.html (0 => 278537)


--- trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-fixed-width-variations-simple.html	2021-06-06 15:15:40 UTC (rev 278537)
@@ -0,0 +1,20 @@
+<!DOCTYPE html><!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+td {
+  height: 50px;
+  padding: 0px;
+}
+
+table {
+  border-spacing: 0px;
+  background-color: green;
+}
+</style>
+<table><tr><td style="width: 50px"></td><td style="width: 50px"></td></tr></table>
+<table><tr><td style="width: 90px"></td><td style="width: 10px"></td></tr></table>
+<table><tr><td style="width: 80px"></td><td style="width: 10px"></td><td style="width: 10px"></td></tr></table>
+
+<table style="width: 100px;"><tr><td style="width: 90px"></td><td style="width: 10px"></td></tr></table>
+<table style="width: 100px;"><tr><td style="width: 50px"></td><td style="width: 10px"></td></tr></table>
+<table style="width: 100px;"><tr><td style="width: 900px"></td><td style="width: 100px"></td></tr></table>
+<table style="width: 100px;"><tr><td style="width: 900px"></td><td style="width: 900px"></td></tr></table>

Modified: trunk/Source/WebCore/ChangeLog (278536 => 278537)


--- trunk/Source/WebCore/ChangeLog	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/ChangeLog	2021-06-06 15:15:40 UTC (rev 278537)
@@ -1,3 +1,39 @@
+2021-06-06  Alan Bujtas  <[email protected]>
+
+        [LFC][TFC] Adopt a less quirky fixed column width space distribution
+        https://bugs.webkit.org/show_bug.cgi?id=226696
+
+        Reviewed by Antti Koivisto.
+
+        This patch adopts a less quirky space distribution model where any fixed cell width
+        makes the column fixed (as opposed to just when <col> has fixed with).
+        This distribution model matches both Chrome and Firefox.
+        It also enables us to simplify some of the distribution logic by using the same set of values (min vs max)
+        as the base for the distribution ratio.
+
+        Test: fast/layoutformattingcontext/table-fixed-width-variations-simple.html
+
+        * layout/formattingContexts/table/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::computedPreferredWidthForColumns): Collect the fixed with values from the cells too now.
+        * layout/formattingContexts/table/TableFormattingGeometry.cpp:
+        (WebCore::Layout::TableFormattingGeometry::intrinsicWidthConstraintsForCellContent const):
+        (WebCore::Layout::TableFormattingGeometry::intrinsicWidthConstraintsForCell const): Deleted.
+        * layout/formattingContexts/table/TableFormattingGeometry.h:
+        * layout/formattingContexts/table/TableGrid.cpp:
+        (WebCore::Layout::TableGrid::appendCell):
+        (WebCore::Layout::TableGrid::Column::isFixedWidth const): Deleted.
+        (WebCore::Layout::TableGrid::Columns::hasFixedColumnsOnly const): Deleted.
+        (WebCore::Layout::TableGrid::Cell::isFixedWidth const): Deleted.
+        * layout/formattingContexts/table/TableGrid.h:
+        (WebCore::Layout::TableGrid::Column::setFixedWidth):
+        (WebCore::Layout::TableGrid::Column::fixedWidth const):
+        (WebCore::Layout::TableGrid::Columns::logicalWidth const):
+        (WebCore::Layout::TableGrid::Column::setHasFixedWidthCell): Deleted.
+        (WebCore::Layout::TableGrid::Column::hasFixedWidthCell const): Deleted.
+        * layout/formattingContexts/table/TableLayout.cpp:
+        (WebCore::Layout::TableFormattingContext::TableLayout::distributedHorizontalSpace): Adjust the distribution values based on whether
+        the column has fixed width and use max/max in both fixed and non-fixed cases.
+
 2021-06-06  Antti Koivisto  <[email protected]>
 
         Rename InlineElementBox to LegacyInlineElementBox

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


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp	2021-06-06 15:15:40 UTC (rev 278537)
@@ -316,27 +316,14 @@
     ASSERT(!grid.widthConstraints());
 
     // Column preferred width computation as follows:
-    // 1. Collect each cells' width constraints
-    // 2. Collect fixed column widths set by <colgroup>'s and <col>s
+    // 1. Collect fixed column widths set by <colgroup>'s and <col>s
+    // 2. Collect each cells' width constraints and adjust fixed width column values.
     // 3. Find the min/max width for each columns using the cell constraints and the <col> fixed widths but ignore column spans.
     // 4. Distribute column spanning cells min/max widths.
     // 5. Add them all up and return the computed min/max widths.
-    for (auto& cell : grid.cells()) {
-        auto& cellBox = cell->box();
-        ASSERT(cellBox.establishesBlockFormattingContext());
-
-        auto intrinsicWidth = formattingState.intrinsicWidthConstraintsForBox(cellBox);
-        if (!intrinsicWidth) {
-            intrinsicWidth = formattingGeometry().intrinsicWidthConstraintsForCell(*cell);
-            formattingState.setIntrinsicWidthConstraintsForBox(cellBox, *intrinsicWidth);
-        }
-        // Spanner cells put their intrinsic widths on the initial slots.
-        grid.slot(cell->position())->setWidthConstraints(*intrinsicWidth);
-    }
-
     // 2. Collect the fixed width <col>s.
     auto& columnList = grid.columns().list();
-    Vector<std::optional<LayoutUnit>> fixedWidthColumns;
+    auto& formattingGeometry = this->formattingGeometry();
     for (auto& column : columnList) {
         auto fixedWidth = [&] () -> std::optional<LayoutUnit> {
             auto* columnBox = column.box();
@@ -346,11 +333,35 @@
             }
             if (auto width = columnBox->columnWidth())
                 return width;
-            return formattingGeometry().computedColumnWidth(*columnBox);
-        };
-        fixedWidthColumns.append(fixedWidth());
+            return formattingGeometry.computedColumnWidth(*columnBox);
+        }();
+        if (fixedWidth)
+            column.setFixedWidth(*fixedWidth);
     }
 
+    for (auto& cell : grid.cells()) {
+        auto& cellBox = cell->box();
+        ASSERT(cellBox.establishesBlockFormattingContext());
+
+        auto intrinsicWidth = formattingState.intrinsicWidthConstraintsForBox(cellBox);
+        if (!intrinsicWidth) {
+            intrinsicWidth = formattingGeometry.intrinsicWidthConstraintsForCellContent(*cell);
+            formattingState.setIntrinsicWidthConstraintsForBox(cellBox, *intrinsicWidth);
+        }
+        auto cellPosition = cell->position();
+        // Expand it with border and padding.
+        auto horizontalBorderAndPaddingWidth = formattingGeometry.computedCellBorder(*cell).width()
+            + formattingGeometry.fixedValue(cellBox.style().paddingLeft()).value_or(0)
+            + formattingGeometry.fixedValue(cellBox.style().paddingRight()).value_or(0);
+        intrinsicWidth->expand(horizontalBorderAndPaddingWidth);
+        // Spanner cells put their intrinsic widths on the initial slots.
+        grid.slot(cellPosition)->setWidthConstraints(*intrinsicWidth);
+        if (auto fixedWidth = formattingGeometry.fixedValue(cellBox.style().logicalWidth())) {
+            *fixedWidth += horizontalBorderAndPaddingWidth;
+            columnList[cellPosition.column].setFixedWidth(std::max(*fixedWidth, columnList[cellPosition.column].fixedWidth().value_or(0)));
+        }
+    }
+
     Vector<IntrinsicWidthConstraints> columnIntrinsicWidths(columnList.size());
     // 3. Collect he min/max width for each column but ignore column spans for now.
     Vector<SlotPosition> spanningCellPositionList;
@@ -366,8 +377,10 @@
                 spanningCellPositionList.append({ columnIndex, rowIndex });
                 continue;
             }
-            auto columnFixedWidth = fixedWidthColumns[columnIndex];
-            auto widthConstraints = !columnFixedWidth ? slot.widthConstraints() : IntrinsicWidthConstraints { *columnFixedWidth, *columnFixedWidth };
+            auto widthConstraints = slot.widthConstraints();
+            if (auto columnFixedWidth = columnList[columnIndex].fixedWidth())
+                widthConstraints.maximum = std::max(*columnFixedWidth, widthConstraints.minimum);
+
             columnIntrinsicWidths[columnIndex].minimum = std::max(widthConstraints.minimum, columnIntrinsicWidths[columnIndex].minimum);
             columnIntrinsicWidths[columnIndex].maximum = std::max(widthConstraints.maximum, columnIntrinsicWidths[columnIndex].maximum);
         }

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


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp	2021-06-06 15:15:40 UTC (rev 278537)
@@ -118,35 +118,15 @@
     return columnBox.columnWidth();
 }
 
-IntrinsicWidthConstraints TableFormattingGeometry::intrinsicWidthConstraintsForCell(const TableGrid::Cell& cell) const
+IntrinsicWidthConstraints TableFormattingGeometry::intrinsicWidthConstraintsForCellContent(const TableGrid::Cell& cell) const
 {
     auto& cellBox = cell.box();
-    auto& style = cellBox.style();
-
-    auto computedIntrinsicWidthConstraints = [&]() -> IntrinsicWidthConstraints {
-        // Even fixed width cells expand to their minimum content width
-        // <td style="width: 10px">test_content</td> will size to max(minimum content width, computed width).
-        auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
-        if (cellBox.hasChild()) {
-            auto& layoutState = this->layoutState();
-            intrinsicWidthConstraints = LayoutContext::createFormattingContext(cellBox, const_cast<LayoutState&>(layoutState))->computedIntrinsicWidthConstraints();
-        }
-        if (auto fixedWidth = fixedValue(style.logicalWidth()))
-            return { std::max(intrinsicWidthConstraints.minimum, *fixedWidth), std::max(intrinsicWidthConstraints.minimum, *fixedWidth) };
-        return intrinsicWidthConstraints;
-    };
-    // FIXME Check for box-sizing: border-box;
-    auto intrinsicWidthConstraints = constrainByMinMaxWidth(cellBox, computedIntrinsicWidthConstraints());
-    // Expand with border
-    intrinsicWidthConstraints.expand(computedCellBorder(cell).width());
-    // padding
-    intrinsicWidthConstraints.expand(fixedValue(style.paddingLeft()).value_or(0) + fixedValue(style.paddingRight()).value_or(0));
-    // and margin
-    intrinsicWidthConstraints.expand(fixedValue(style.marginStart()).value_or(0) + fixedValue(style.marginEnd()).value_or(0));
-    return intrinsicWidthConstraints;
+    if (!cellBox.hasInFlowOrFloatingChild())
+        return { };
+    auto& layoutState = this->layoutState();
+    return LayoutContext::createFormattingContext(cellBox, const_cast<LayoutState&>(layoutState))->computedIntrinsicWidthConstraints();
 }
 
-
 InlineLayoutUnit TableFormattingGeometry::usedBaselineForCell(const ContainerBox& cellBox) const
 {
     // The baseline of a cell is defined as the baseline of the first in-flow line box in the cell,

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


--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h	2021-06-06 15:15:40 UTC (rev 278537)
@@ -42,7 +42,7 @@
     LayoutUnit cellBoxContentHeight(const ContainerBox&) const;
     Edges computedCellBorder(const TableGrid::Cell&) const;
     std::optional<LayoutUnit> computedColumnWidth(const ContainerBox& columnBox) const;
-    IntrinsicWidthConstraints intrinsicWidthConstraintsForCell(const TableGrid::Cell&) const;
+    IntrinsicWidthConstraints intrinsicWidthConstraintsForCellContent(const TableGrid::Cell&) const;
     InlineLayoutUnit usedBaselineForCell(const ContainerBox& cellBox) const;
     LayoutUnit horizontalSpaceForCellContent(const TableGrid::Cell&) const;
     LayoutUnit verticalSpaceForCellContent(const TableGrid::Cell&, std::optional<LayoutUnit> availableVerticalSpace) const;

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.cpp (278536 => 278537)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.cpp	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.cpp	2021-06-06 15:15:40 UTC (rev 278537)
@@ -68,11 +68,6 @@
     return m_computedLogicalLeft;
 }
 
-bool TableGrid::Column::isFixedWidth() const
-{
-    return hasFixedWidthCell() || (box() && box()->columnWidth());
-}
-
 void TableGrid::Columns::addColumn(const ContainerBox& columnBox)
 {
     m_columnList.append({ &columnBox });
@@ -83,15 +78,6 @@
     m_columnList.append({ nullptr });
 }
 
-bool TableGrid::Columns::hasFixedColumnsOnly() const
-{
-    for (auto& column : m_columnList) {
-        if (!column.isFixedWidth())
-            return false;
-    }
-    return true;
-}
-
 void TableGrid::Rows::addRow(const ContainerBox& rowBox)
 {
     m_rowList.append({ rowBox });
@@ -109,11 +95,6 @@
 {
 }
 
-bool TableGrid::Cell::isFixedWidth() const
-{
-    return box().style().logicalWidth().isFixed();
-}
-
 TableGrid::Slot::Slot(Cell& cell, bool isColumnSpanned, bool isRowSpanned)
     : m_cell(makeWeakPtr(cell))
     , m_isColumnSpanned(isColumnSpanned)
@@ -170,11 +151,6 @@
     for (auto column = 0; column < missingNumberOfColumns; ++column)
         m_columns.addAnonymousColumn();
 
-    if (cell->isFixedWidth()) {
-        for (auto column = cell->startColumn(); column < cell->endColumn(); ++column)
-            m_columns.list()[column].setHasFixedWidthCell();
-    }
-
     if (isInNewRow)
         m_rows.addRow(cellBox.parent());
 

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.h (278536 => 278537)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.h	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableGrid.h	2021-06-06 15:15:40 UTC (rev 278537)
@@ -73,18 +73,16 @@
         void setLogicalWidth(LayoutUnit);
         LayoutUnit logicalWidth() const;
 
-        bool isFixedWidth() const;
+        void setFixedWidth(LayoutUnit fixedValue) { m_fixedWidth = fixedValue; }
+        std::optional<LayoutUnit> fixedWidth() const { return m_fixedWidth; }
 
-        void setHasFixedWidthCell() { m_hasFixedWidthCell = true; }
         const ContainerBox* box() const { return m_layoutBox.get(); }
 
     private:
-        bool hasFixedWidthCell() const { return m_hasFixedWidthCell; }
-
         LayoutUnit m_computedLogicalWidth;
         LayoutUnit m_computedLogicalLeft;
+        std::optional<LayoutUnit> m_fixedWidth;
         WeakPtr<const ContainerBox> m_layoutBox;
-        bool m_hasFixedWidthCell { false };
 
 #if ASSERT_ENABLED
         bool m_hasComputedWidth { false };
@@ -103,7 +101,6 @@
         void addAnonymousColumn();
 
         LayoutUnit logicalWidth() const { return m_columnList.last().logicalRight() - m_columnList.first().logicalLeft(); }
-        bool hasFixedColumnsOnly() const;
 
     private:
         ColumnList m_columnList;
@@ -167,8 +164,6 @@
         void setBaseline(InlineLayoutUnit baseline) { m_baseline = baseline; }
         InlineLayoutUnit baseline() const { return m_baseline; }
 
-        bool isFixedWidth() const;
-
         const ContainerBox& box() const { return *m_layoutBox.get(); }
 
     private:

Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp (278536 => 278537)


--- trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp	2021-06-06 14:47:34 UTC (rev 278536)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp	2021-06-06 15:15:40 UTC (rev 278537)
@@ -244,18 +244,16 @@
     enum class ColumnWidthBalancingBase { MinimumWidth, MaximumWidth };
     auto columnWidthBalancingBase = availableHorizontalSpace >= m_grid.widthConstraints()->maximum ? ColumnWidthBalancingBase::MaximumWidth : ColumnWidthBalancingBase::MinimumWidth;
     return distributeAvailableSpace<ColumnSpan>(m_grid, availableHorizontalSpace, [&] (const TableGrid::Slot& slot, size_t columnIndex) {
-        auto& column = m_grid.columns().list()[columnIndex];
-        auto columnBoxFixedWidth = column.box() ? column.box()->columnWidth().value_or(0_lu) : 0_lu;
-        auto minimumWidth = std::max<float>(slot.widthConstraints().minimum, columnBoxFixedWidth);
-        auto maximumWidth = std::max<float>(slot.widthConstraints().maximum, columnBoxFixedWidth);
+        float minimumWidth = slot.widthConstraints().minimum;
+        float maximumWidth = slot.widthConstraints().maximum;
 
+        if (auto fixedWidth = m_grid.columns().list()[columnIndex].fixedWidth())
+            maximumWidth = std::max<float>(minimumWidth, *fixedWidth);
+
         if (columnWidthBalancingBase == ColumnWidthBalancingBase::MinimumWidth) {
             ASSERT(maximumWidth >= minimumWidth);
             return GridSpace { minimumWidth, maximumWidth - minimumWidth };
         }
-        // When the column has a fixed width cell, the maximum width balancing is based on the minimum width.
-        if (column.isFixedWidth())
-            return GridSpace { minimumWidth, maximumWidth };
         return GridSpace { maximumWidth, maximumWidth };
     });
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to