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 };
});
}