Modified: trunk/LayoutTests/ChangeLog (279317 => 279318)
--- trunk/LayoutTests/ChangeLog 2021-06-27 17:39:38 UTC (rev 279317)
+++ trunk/LayoutTests/ChangeLog 2021-06-27 19:16:51 UTC (rev 279318)
@@ -1,3 +1,15 @@
+2021-06-27 Alan Bujtas <[email protected]>
+
+ [LFC][TFC] Add support for shrinking over-constrained columns based on the width type priority list
+ https://bugs.webkit.org/show_bug.cgi?id=227426
+
+ Reviewed by Antti Koivisto.
+
+ * fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple-expected.html: Added.
+ * fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple.html: Added.
+ * fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2-expected.html: Added.
+ * fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2.html: Added.
+
2021-06-27 Philippe Normand <[email protected]>
[GStreamer] SleepDisabler not destroyed when video playback stops
Added: trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple-expected.html (0 => 279318)
--- trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple-expected.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple-expected.html 2021-06-27 19:16:51 UTC (rev 279318)
@@ -0,0 +1,25 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+body {
+ font-size: 16px;
+ overflow: hidden;
+}
+
+div {
+ height: 20px;
+ background-color: blue;
+ width: 200px;
+}
+
+.inner {
+ background-color: green;
+}
+</style>
+
+<div><div class=inner style="width: 140px"></div></div>
+<div><div class=inner style="width: 120px"></div></div>
+<div><div class=inner style="width: 100px"></div></div>
+<div><div class=inner style="width: 80px"></div></div>
+<div><div class=inner style="width: 60px"></div></div>
+<div><div class=inner style="width: 40px"></div></div>
+<div><div class=inner style="width: 20px"></div></div>
Added: trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple.html (0 => 279318)
--- trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple.html 2021-06-27 19:16:51 UTC (rev 279318)
@@ -0,0 +1,35 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+body {
+ font-size: 16px;
+ overflow: hidden;
+}
+
+table {
+ border-spacing: 0px;
+}
+
+td {
+ height: 20px;
+ padding: 0px;
+ background-color: blue;
+ white-space: pre-wrap;
+}
+
+td:nth-child(odd) {
+ background-color: green;
+}
+
+div {
+ height: 20px;
+}
+</style>
+<div style="width: 200px; height: auto;">
+<table><tr><td style="width: 300px;"></td><td style="width: 30%;"></td></tr></table>
+<table><tr><td style="width: 400px;"></td><td style="width: 40%;"></td></tr></table>
+<table><tr><td style="width: 500px;"></td><td style="width: 50%;"></td></tr></table>
+<table><tr><td style="width: 600px;"></td><td style="width: 60%;"></td></tr></table>
+<table><tr><td style="width: 700px;"></td><td style="width: 70%;"></td></tr></table>
+<table><tr><td style="width: 800px;"></td><td style="width: 80%;"></td></tr></table>
+<table><tr><td style="width: 900px;"></td><td style="width: 90%;"></td></tr></table>
+</div>
Added: trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2-expected.html (0 => 279318)
--- trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2-expected.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2-expected.html 2021-06-27 19:16:51 UTC (rev 279318)
@@ -0,0 +1,26 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+body {
+ font-size: 16px;
+ overflow: hidden;
+}
+
+div {
+ height: 20px;
+ background-color: green;
+ width: 200px;
+}
+
+.inner {
+ background-color: blue;
+ position: relative;
+}
+</style>
+
+<div><div class=inner style="left: 60px; width: 80px"></div></div>
+<div><div class=inner style="left: 53px; width: 67px"></div></div>
+<div><div class=inner style="left: 45px; width: 55px"></div></div>
+<div><div class=inner style="left: 43.5px; width: 36.5px"></div></div>
+<div><div class=inner style="left: 38px; width: 22px"></div></div>
+<div><div class=inner style="left: 29px; width: 11px"></div></div>
+<div><div class=inner style="left: 16px; width: 4px"></div></div>
Added: trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2.html (0 => 279318)
--- trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2.html 2021-06-27 19:16:51 UTC (rev 279318)
@@ -0,0 +1,35 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextEnabled=true LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+body {
+ font-size: 16px;
+ overflow: hidden;
+}
+
+table {
+ border-spacing: 0px;
+}
+
+td {
+ height: 20px;
+ padding: 0px;
+ background-color: blue;
+ white-space: pre-wrap;
+}
+
+td:nth-child(odd) {
+ background-color: green;
+}
+
+div {
+ height: 20px;
+}
+</style>
+<div style="width: 200px; height: auto;">
+<table><tr><td style="width: 300px;"></td><td style="width: 400px;"></td><td style="width: 30%;"></td></tr></table>
+<table><tr><td style="width: 400px;"></td><td style="width: 500px;"></td><td style="width: 40%;"></td></tr></table>
+<table><tr><td style="width: 500px;"></td><td style="width: 600px;"></td><td style="width: 50%;"></td></tr></table>
+<table><tr><td style="width: 600px;"></td><td style="width: 500px;"></td><td style="width: 60%;"></td></tr></table>
+<table><tr><td style="width: 700px;"></td><td style="width: 400px;"></td><td style="width: 70%;"></td></tr></table>
+<table><tr><td style="width: 800px;"></td><td style="width: 300px;"></td><td style="width: 80%;"></td></tr></table>
+<table><tr><td style="width: 900px;"></td><td style="width: 200px;"></td><td style="width: 90%;"></td></tr></table>
+</div>
Modified: trunk/Source/WebCore/ChangeLog (279317 => 279318)
--- trunk/Source/WebCore/ChangeLog 2021-06-27 17:39:38 UTC (rev 279317)
+++ trunk/Source/WebCore/ChangeLog 2021-06-27 19:16:51 UTC (rev 279318)
@@ -1,5 +1,36 @@
2021-06-27 Alan Bujtas <[email protected]>
+ [LFC][TFC] Add support for shrinking over-constrained columns based on the width type priority list
+ https://bugs.webkit.org/show_bug.cgi?id=227426
+
+ Reviewed by Antti Koivisto.
+
+ Let's take the priority list into use when shrinking the columns in an over-constrained context.
+ e.g.
+ <div style="width: 100px">
+ <table><tr><td style="width: 90%""></td><td style="width: 400px;"></td><td style="width: 100px;"></td></tr></table>
+ </div>
+
+ While the second and the third columns have the preferred width of 400px and 100px respectively, we can't accommodate
+ them as the containing block (<div>) sets a 100px horizontal constraint on the table content and the first column already takes up 90px space.
+
+ Now we start shrinking the columns using the following priority list: auto < relative < fixed < percent (ignoring the actual column order).
+
+ The preferred width of the table (assume 0px border spacing and padding) is 90px + 400px + 100px. It produces a -490px
+ available space. This negative space needs to be distributed among the columns staring with the fixed sized ones.
+ The fixed sized columns have a flex space of 500px which covers the -490px gap. Based on their 4:1 distribution ratio, they'll end
+ up with 8px and 2px and the percent column stays at 90px.
+
+ Tests: fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple.html
+ fast/layoutformattingcontext/table-space-shinking-mixed-width-type-simple2.html
+
+ * layout/formattingContexts/table/TableLayout.cpp:
+ (WebCore::Layout::distributeAvailableSpace):
+ (WebCore::Layout::TableFormattingContext::TableLayout::distributedHorizontalSpace):
+ (WebCore::Layout::TableFormattingContext::TableLayout::distributedVerticalSpace):
+
+2021-06-27 Alan Bujtas <[email protected]>
+
[LFC][TFC] Rename GridSpace::preferredSpace to preferredSize
https://bugs.webkit.org/show_bug.cgi?id=227425
Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp (279317 => 279318)
--- trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp 2021-06-27 17:39:38 UTC (rev 279317)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableLayout.cpp 2021-06-27 19:16:51 UTC (rev 279318)
@@ -85,6 +85,7 @@
// The base space value for the distribution computation e.g [ 9 ] [ 1 ] values for 2 columns in the table means that if
// we've go 100px flexible space to distribute, 90px and 10px go to the columns respectively.
float flexBase { 0 };
+ float minimumSize { 0 };
};
inline static GridSpace& operator-(GridSpace& a, const GridSpace& b)
@@ -210,60 +211,79 @@
}
}
}
- // 4. Distribute the extra space using the final resolved widths.
-#if ASSERT_ENABLED
- // We have to have all the spaces resolved at this point.
- for (auto& resolvedItem : resolvedItems)
+ // 4. Distribute the extra space using the final resolved sizes.
+ Vector<LayoutUnit> distributedSpaces(resolvedItems.size());
+ float spaceToDistribute = availableSpace - (resolvedItems.size() + 1) * SpanType::spacing(grid);
+ auto adjustabledSpace = GridSpace { };
+ for (auto& resolvedItem : resolvedItems) {
ASSERT(resolvedItem);
-#endif
- Vector<size_t> percentColumnIndexes;
- Vector<size_t> fixedColumnIndexes;
- Vector<size_t> relativeColumnIndexes;
- Vector<size_t> autoColumnIndexes;
-
- // Fixed size cells don't participate in available space distribution.
- auto adjustabledSpace = GridSpace { };
- for (size_t columnIndex = 0; columnIndex < resolvedItems.size(); ++columnIndex) {
- auto& resolvedItem = resolvedItems[columnIndex];
adjustabledSpace += *resolvedItem;
- switch (resolvedItem->type) {
- case GridSpace::Type::Percent:
- percentColumnIndexes.append(columnIndex);
- break;
- case GridSpace::Type::Fixed:
- fixedColumnIndexes.append(columnIndex);
- break;
- case GridSpace::Type::Relative:
- relativeColumnIndexes.append(columnIndex);
- break;
- case GridSpace::Type::Auto:
- autoColumnIndexes.append(columnIndex);
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
}
+ spaceToDistribute -= adjustabledSpace.preferredSize;
+ // Let's start with the preferred size for each column.
+ for (size_t columnIndex = 0; columnIndex < resolvedItems.size(); ++columnIndex)
+ distributedSpaces[columnIndex] = LayoutUnit { resolvedItems[columnIndex]->preferredSize };
- Vector<LayoutUnit> distributedSpaces(resolvedItems.size());
- float spaceToDistribute = availableSpace;
- // Top and bottom spacing are fixed.
- spaceToDistribute -= 2 * SpanType::spacing(grid);
- spaceToDistribute -= adjustabledSpace.preferredSize + ((resolvedItems.size() - 1) * SpanType::spacing(grid));
- // Distribute the extra space based on the resolved spaces. Note that the extra space could be a negative value in which case
- // we may assign less space to columns.
- auto columnsFlexBase = adjustabledSpace.flexBase ? spaceToDistribute / adjustabledSpace.flexBase : 0.f;
- auto distributeSpaceForType = [&](const auto& columnIndexes) {
- for (auto& columnIndex : columnIndexes) {
+ if (spaceToDistribute > 0) {
+ // Each column can get some extra space.
+ auto columnsFlexBase = adjustabledSpace.flexBase ? spaceToDistribute / adjustabledSpace.flexBase : 0.f;
+ for (size_t columnIndex = 0; columnIndex < resolvedItems.size(); ++columnIndex) {
auto columnExtraSpace = columnsFlexBase * resolvedItems[columnIndex]->flexBase;
- distributedSpaces[columnIndex] = LayoutUnit { resolvedItems[columnIndex]->preferredSize + columnExtraSpace };
+ distributedSpaces[columnIndex] += LayoutUnit { columnExtraSpace };
}
- };
- // Distribute the available space starting with percent columns and ending with autos.
- distributeSpaceForType(percentColumnIndexes);
- distributeSpaceForType(fixedColumnIndexes);
- distributeSpaceForType(relativeColumnIndexes);
- distributeSpaceForType(autoColumnIndexes);
+ } else if (spaceToDistribute < 0) {
+ // Can't accomodate the preferred width. Let's use the priority list to shrink columns.
+ Vector<size_t> autoColumnIndexes;
+ Vector<size_t> relativeColumnIndexes;
+ Vector<size_t> fixedColumnIndexes;
+ Vector<size_t> percentColumnIndexes;
+
+ for (size_t columnIndex = 0; columnIndex < resolvedItems.size(); ++columnIndex) {
+ switch (resolvedItems[columnIndex]->type) {
+ case GridSpace::Type::Percent:
+ percentColumnIndexes.append(columnIndex);
+ break;
+ case GridSpace::Type::Fixed:
+ fixedColumnIndexes.append(columnIndex);
+ break;
+ case GridSpace::Type::Relative:
+ relativeColumnIndexes.append(columnIndex);
+ break;
+ case GridSpace::Type::Auto:
+ autoColumnIndexes.append(columnIndex);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ auto spaceNeeded = -spaceToDistribute;
+ auto shrinkSpaceForType = [&](const auto& columnIndexes) {
+ auto adjustabledSpace = GridSpace { };
+ for (auto& columnIndex : columnIndexes)
+ adjustabledSpace += *resolvedItems[columnIndex];
+
+ auto columnsFlexBase = adjustabledSpace.flexBase ? spaceNeeded / adjustabledSpace.flexBase : 0.f;
+ for (auto& columnIndex : columnIndexes) {
+ auto& resolvedItem = *resolvedItems[columnIndex];
+ auto spaceToRemove = std::min(resolvedItem.preferredSize - resolvedItem.minimumSize, columnsFlexBase * resolvedItem.flexBase);
+ spaceToRemove = std::min(spaceToRemove, spaceNeeded);
+ distributedSpaces[columnIndex] -= spaceToRemove;
+ spaceNeeded -= spaceToRemove;
+ if (!spaceNeeded)
+ return;
+ }
+ ASSERT(spaceNeeded > 0);
+ };
+ shrinkSpaceForType(autoColumnIndexes);
+ if (spaceNeeded)
+ shrinkSpaceForType(relativeColumnIndexes);
+ if (spaceNeeded)
+ shrinkSpaceForType(fixedColumnIndexes);
+ if (spaceNeeded)
+ shrinkSpaceForType(percentColumnIndexes);
+ }
return distributedSpaces;
}
@@ -304,7 +324,7 @@
// total adjustable space: 120px - 80px - 50px = -10px <- Note the negative available space with over-constrained values.
// columns extra widths: -10px / (30px + 0px) * 30px = -10px and -10px / (30px + 0px) * 0px = 0px
// columns final widths: 70px and 50px (first column is narrower than its preferred width and the second is as wide as the minimum content width)
- return GridSpace { type, preferredWidth, preferredWidth - minimumContentWidth };
+ return GridSpace { type, preferredWidth, preferredWidth - minimumContentWidth, minimumContentWidth };
}
// maximum width <= available horizontal space
@@ -324,7 +344,7 @@
// total adjustable space: 2600px - 500px = 2100px
// columns extra widths: 2100px / 500px * 200px = 840px and 2100px / 500px * 300px = 1260px
// columns final widths: 1040px and 1560px
- return GridSpace { type, preferredWidth, preferredWidth };
+ return GridSpace { type, preferredWidth, preferredWidth, minimumContentWidth };
});
}
@@ -367,12 +387,14 @@
auto availableSpace = std::max(availableVerticalSpace.value_or(0_lu), tableUsedHeight);
// Distribute extra space if the table is supposed to be taller than the sum of the row heights.
return distributeAvailableSpace<RowSpan>(m_grid, availableSpace, [&] (const TableGrid::Slot& slot, size_t rowIndex) {
- if (slot.hasRowSpan())
- return GridSpace { { }, formattingContext().geometryForBox(slot.cell().box()).borderBoxHeight(), formattingContext().geometryForBox(slot.cell().box()).borderBoxHeight() };
+ if (slot.hasRowSpan()) {
+ auto borderBoxHeight = formattingContext().geometryForBox(slot.cell().box()).borderBoxHeight();
+ return GridSpace { { }, borderBoxHeight, borderBoxHeight, borderBoxHeight };
+ }
auto& rows = m_grid.rows();
auto computedRowHeight = formattingContext().formattingGeometry().computedHeight(rows.list()[rowIndex].box(), { });
auto height = std::max<float>(rowHeight[rowIndex], computedRowHeight.value_or(0_lu));
- return GridSpace { { }, height, height };
+ return GridSpace { { }, height, height, height };
});
}