<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[259984] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/259984">259984</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2020-04-12 11:32:07 -0700 (Sun, 12 Apr 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>[LFC][TFC] Add support for column spanners
https://bugs.webkit.org/show_bug.cgi?id=210403

Reviewed by Antti Koivisto.

Table width constraint computation with spanner support is as follows:

1. Collect each cells' width constraints.
2. Collect fixed column widths set by <colgroup>'s and <col>s.
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.

* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::IntrinsicWidthConstraints::operator-=):
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::computedPreferredWidthForColumns):
(WebCore::Layout::TableFormattingContext::computeAndDistributeExtraHorizontalSpace):
* layout/tableformatting/TableFormattingContextGeometry.cpp:
(WebCore::Layout::TableFormattingContext::Geometry::intrinsicWidthConstraintsForCell):
* layout/tableformatting/TableGrid.cpp:
(WebCore::Layout::TableGrid::Columns::hasFixedColumnsOnly const):
* layout/tableformatting/TableGrid.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorelayoutFormattingContexth">trunk/Source/WebCore/layout/FormattingContext.h</a></li>
<li><a href="#trunkSourceWebCorelayouttableformattingTableFormattingContextcpp">trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorelayouttableformattingTableGridcpp">trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp</a></li>
<li><a href="#trunkSourceWebCorelayouttableformattingTableGridh">trunk/Source/WebCore/layout/tableformatting/TableGrid.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (259983 => 259984)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2020-04-12 17:53:37 UTC (rev 259983)
+++ trunk/Source/WebCore/ChangeLog      2020-04-12 18:32:07 UTC (rev 259984)
</span><span class="lines">@@ -1,5 +1,31 @@
</span><span class="cx"> 2020-04-12  Zalan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><ins>+        [LFC][TFC] Add support for column spanners
+        https://bugs.webkit.org/show_bug.cgi?id=210403
+
+        Reviewed by Antti Koivisto.
+
+        Table width constraint computation with spanner support is as follows:
+
+        1. Collect each cells' width constraints.
+        2. Collect fixed column widths set by <colgroup>'s and <col>s.
+        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.
+
+        * layout/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::IntrinsicWidthConstraints::operator-=):
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::computedPreferredWidthForColumns):
+        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraHorizontalSpace):
+        * layout/tableformatting/TableFormattingContextGeometry.cpp:
+        (WebCore::Layout::TableFormattingContext::Geometry::intrinsicWidthConstraintsForCell):
+        * layout/tableformatting/TableGrid.cpp:
+        (WebCore::Layout::TableGrid::Columns::hasFixedColumnsOnly const):
+        * layout/tableformatting/TableGrid.h:
+
+2020-04-12  Zalan Bujtas  <zalan@apple.com>
+
</ins><span class="cx">         [LFC][TFC] Column, Row and Cell boxes are always ContainerBoxes
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=210402
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutFormattingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/FormattingContext.h (259983 => 259984)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/FormattingContext.h  2020-04-12 17:53:37 UTC (rev 259983)
+++ trunk/Source/WebCore/layout/FormattingContext.h     2020-04-12 18:32:07 UTC (rev 259984)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx">     struct IntrinsicWidthConstraints {
</span><span class="cx">         void expand(LayoutUnit horizontalValue);
</span><span class="cx">         IntrinsicWidthConstraints& operator+=(const IntrinsicWidthConstraints&);
</span><ins>+        IntrinsicWidthConstraints& operator-=(const IntrinsicWidthConstraints&);
</ins><span class="cx">         IntrinsicWidthConstraints& operator-=(LayoutUnit);
</span><span class="cx"> 
</span><span class="cx">         LayoutUnit minimum;
</span><span class="lines">@@ -229,6 +230,13 @@
</span><span class="cx">     return *this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline FormattingContext::IntrinsicWidthConstraints& FormattingContext::IntrinsicWidthConstraints::operator-=(const IntrinsicWidthConstraints& other)
+{
+    minimum -= other.minimum;
+    maximum -= other.maximum;
+    return *this;
+}
+
</ins><span class="cx"> inline FormattingContext::IntrinsicWidthConstraints& FormattingContext::IntrinsicWidthConstraints::operator-=(LayoutUnit value)
</span><span class="cx"> {
</span><span class="cx">     minimum -= value;
</span></span></pre></div>
<a id="trunkSourceWebCorelayouttableformattingTableFormattingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (259983 => 259984)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp   2020-04-12 17:53:37 UTC (rev 259983)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp      2020-04-12 18:32:07 UTC (rev 259984)
</span><span class="lines">@@ -241,9 +241,12 @@
</span><span class="cx">     auto& grid = formattingState.tableGrid();
</span><span class="cx">     ASSERT(!grid.widthConstraints());
</span><span class="cx"> 
</span><del>-    // 1. Calculate the minimum content width (MCW) of each cell: the formatted content may span any number of lines but may not overflow the cell box.
-    //    If the specified 'width' (W) of the cell is greater than MCW, W is the minimum cell width. A value of 'auto' means that MCW is the minimum cell width.
-    //    Also, calculate the "maximum" cell width of each cell: formatting the content without breaking lines other than where explicit line breaks occur.
</del><ins>+    // Column preferred width computation as follows:
+    // 1. Collect each cells' width constraints
+    // 2. Collect fixed column widths set by <colgroup>'s and <col>s
+    // 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.
</ins><span class="cx">     for (auto& cell : grid.cells()) {
</span><span class="cx">         auto& cellBox = cell->box();
</span><span class="cx">         ASSERT(cellBox.establishesBlockFormattingContext());
</span><span class="lines">@@ -257,13 +260,14 @@
</span><span class="cx">         grid.slot(cell->position())->setWidthConstraints(*intrinsicWidth);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // 2. Collect the fixed width <col>s.
</ins><span class="cx">     auto& columnList = grid.columns().list();
</span><span class="cx">     Vector<Optional<LayoutUnit>> fixedWidthColumns;
</span><del>-    for (size_t columnIndex = 0; columnIndex < columnList.size(); ++columnIndex) {
</del><ins>+    for (auto& column : columnList) {
</ins><span class="cx">         auto fixedWidth = [&] () -> Optional<LayoutUnit> {
</span><del>-            auto* columnBox = columnList[columnIndex].box();
</del><ins>+            auto* columnBox = column.box();
</ins><span class="cx">             if (!columnBox) {
</span><del>-                // Anoynmous columns don't have associated layout boxes.
</del><ins>+                // Anoynmous columns don't have associated layout boxes and can't have fixed col size.
</ins><span class="cx">                 return { };
</span><span class="cx">             }
</span><span class="cx">             if (auto width = columnBox->columnWidth())
</span><span class="lines">@@ -274,33 +278,43 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Vector<FormattingContext::IntrinsicWidthConstraints> columnIntrinsicWidths;
</span><del>-    // Collect he min/max width for each column and finalize the preferred width for the table.
</del><ins>+    // 3. Collect he min/max width for each column but ignore column spans for now.
+    Vector<SlotPosition> spanningCellPositionList;
</ins><span class="cx">     for (size_t columnIndex = 0; columnIndex < columnList.size(); ++columnIndex) {
</span><span class="cx">         columnIntrinsicWidths.append(FormattingContext::IntrinsicWidthConstraints { });
</span><span class="cx">         for (size_t rowIndex = 0; rowIndex < grid.rows().size(); ++rowIndex) {
</span><span class="cx">             auto& slot = *grid.slot({ columnIndex, rowIndex });
</span><span class="cx">             if (slot.hasColumnSpan()) {
</span><del>-                auto& cell = slot.cell();
-                auto widthConstraintsToDistribute = slot.widthConstraints();
-                auto numberOfNonFixedSpannedColumns = cell.columnSpan();
-                for (size_t columnSpanIndex = cell.startColumn(); columnSpanIndex < cell.endColumn(); ++columnSpanIndex) {
-                    if (auto fixedWidth = fixedWidthColumns[columnSpanIndex]) {
-                        widthConstraintsToDistribute -= *fixedWidth;
-                        --numberOfNonFixedSpannedColumns;
-                    }
-                }
-                for (size_t columnSpanIndex = cell.startColumn(); columnSpanIndex < cell.endColumn(); ++columnSpanIndex) {
-                    columnIntrinsicWidths[columnIndex].minimum = std::max(widthConstraintsToDistribute.minimum / numberOfNonFixedSpannedColumns, columnIntrinsicWidths[columnIndex].minimum);
-                    columnIntrinsicWidths[columnIndex].maximum = std::max(widthConstraintsToDistribute.maximum / numberOfNonFixedSpannedColumns, columnIntrinsicWidths[columnIndex].maximum);
-                }
-            } else {
-                auto columnFixedWidth = fixedWidthColumns[columnIndex];
-                auto widthConstraints = !columnFixedWidth ? slot.widthConstraints() : FormattingContext::IntrinsicWidthConstraints { *columnFixedWidth, *columnFixedWidth };
-                columnIntrinsicWidths[columnIndex].minimum = std::max(widthConstraints.minimum, columnIntrinsicWidths[columnIndex].minimum);
-                columnIntrinsicWidths[columnIndex].maximum = std::max(widthConstraints.maximum, columnIntrinsicWidths[columnIndex].maximum);
</del><ins>+                spanningCellPositionList.append({ columnIndex, rowIndex });
+                continue;
</ins><span class="cx">             }
</span><ins>+            if (slot.isColumnSpanned())
+                continue;
+            auto columnFixedWidth = fixedWidthColumns[columnIndex];
+            auto widthConstraints = !columnFixedWidth ? slot.widthConstraints() : FormattingContext::IntrinsicWidthConstraints { *columnFixedWidth, *columnFixedWidth };
+            columnIntrinsicWidths[columnIndex].minimum = std::max(widthConstraints.minimum, columnIntrinsicWidths[columnIndex].minimum);
+            columnIntrinsicWidths[columnIndex].maximum = std::max(widthConstraints.maximum, columnIntrinsicWidths[columnIndex].maximum);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    // 4. Distribute the spanning min/max widths.
+    for (auto spanningCellPosition : spanningCellPositionList) {
+        auto& slot = *grid.slot(spanningCellPosition);
+        auto& cell = slot.cell();
+        ASSERT(slot.hasColumnSpan());
+        auto widthConstraintsToDistribute = slot.widthConstraints();
+        for (size_t columnSpanIndex = cell.startColumn(); columnSpanIndex < cell.endColumn(); ++columnSpanIndex)
+            widthConstraintsToDistribute -= columnIntrinsicWidths[columnSpanIndex];
+        // FIXME: Check if fixed width columns should be skipped here.
+        widthConstraintsToDistribute.minimum = std::max(LayoutUnit { }, widthConstraintsToDistribute.minimum / cell.columnSpan());
+        widthConstraintsToDistribute.maximum = std::max(LayoutUnit { }, widthConstraintsToDistribute.maximum / cell.columnSpan());
+        if (widthConstraintsToDistribute.minimum || widthConstraintsToDistribute.maximum) {
+            for (size_t columnSpanIndex = cell.startColumn(); columnSpanIndex < cell.endColumn(); ++columnSpanIndex)
+                columnIntrinsicWidths[columnSpanIndex] += widthConstraintsToDistribute;
+        }
+    }
+
+    // 5. The final table min/max widths is just the accumulated column constraints.
</ins><span class="cx">     auto tableWidthConstraints = IntrinsicWidthConstraints { };
</span><span class="cx">     for (auto& columnIntrinsicWidth : columnIntrinsicWidths)
</span><span class="cx">         tableWidthConstraints += columnIntrinsicWidth;
</span><span class="lines">@@ -314,19 +328,16 @@
</span><span class="cx">     auto& rows = grid.rows();
</span><span class="cx">     auto tableWidthConstraints = *grid.widthConstraints();
</span><span class="cx"> 
</span><del>-    // Column and caption widths influence the final table width as follows:
-    // If the 'table' or 'inline-table' element's 'width' property has a computed value (W) other than 'auto', the used width is the greater of
-    // W, CAPMIN, and the minimum width required by all the columns plus cell spacing or borders (MIN).
-    // If the used width is greater than MIN, the extra width should be distributed over the columns.
-    // If the 'table' or 'inline-table' element has 'width: auto', the used width is the greater of the table's containing block width,
-    // CAPMIN, and MIN. However, if either CAPMIN or the maximum width required by the columns plus cell spacing or borders (MAX) is
-    // less than that of the containing block, use max(MAX, CAPMIN).
</del><span class="cx">     auto distributeExtraHorizontalSpace = [&] (auto horizontalSpaceToDistribute) {
</span><span class="cx">         auto& columnList = grid.columns().list();
</span><span class="cx">         ASSERT(!columnList.isEmpty());
</span><span class="cx"> 
</span><del>-        // 1. Collect minimum widths across columns but ignore spanning cells first.
-        Vector<float> columnMinimumWidths;
</del><ins>+        // 1. Collect minimum widths driven by <td> across columns but ignore spanning cells first.
+        struct ColumnMinimumWidth {
+            float value { 0 };
+            bool shouldFlex { true };
+        };
+        Vector<ColumnMinimumWidth> columnMinimumWidths;
</ins><span class="cx">         Vector<SlotPosition> spanningCellPositionList;
</span><span class="cx">         for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
</span><span class="cx">             for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
</span><span class="lines">@@ -338,12 +349,25 @@
</span><span class="cx">                 if (slot.isColumnSpanned())
</span><span class="cx">                     continue;
</span><span class="cx">                 if (!rowIndex)
</span><del>-                    columnMinimumWidths.append(slot.widthConstraints().minimum);
</del><ins>+                    columnMinimumWidths.append({ slot.widthConstraints().minimum, !columns.list()[columnIndex].isFixedWidth() });
</ins><span class="cx">                 else
</span><del>-                    columnMinimumWidths[columnIndex] = std::max<float>(columnMinimumWidths[columnIndex], slot.widthConstraints().minimum);
</del><ins>+                    columnMinimumWidths[columnIndex].value = std::max<float>(columnMinimumWidths[columnIndex].value, slot.widthConstraints().minimum);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><del>-        // 2. Distribute the spanning cells' mimimum widths across the columns using the non-spanning minium widths.
</del><ins>+        // 2. Adjust the minimum width with fixed column widths (<col> vs. <td>) and also manage all-fixed-width-column content.
+        auto hasFixedColumnsOnly = columns.hasFixedColumnsOnly();
+        for (size_t columnIndex = 0; columnIndex < columnList.size(); ++columnIndex) {
+            auto& column = columnList[columnIndex];
+            if (!column.isFixedWidth())
+                continue;
+            // This is the column width based on <col width=""> and not <td style="width: ">.
+            auto columnFixedWidth = column.box() ? column.box()->columnWidth() : WTF::nullopt; 
+            columnMinimumWidths[columnIndex].value = std::max(columnMinimumWidths[columnIndex].value, columnFixedWidth.valueOr(0).toFloat());
+            // Fixed columns flex when there are no other flexable columns.
+            columnMinimumWidths[columnIndex].shouldFlex = hasFixedColumnsOnly | columnMinimumWidths[columnIndex].shouldFlex;
+        }
+
+        // 3. Distribute the spanning cells' mimimum widths across the columns using the non-spanning minimum widths.
</ins><span class="cx">         // e.g. [ 1 ][ 5 ][ 1 ]
</span><span class="cx">         //      [    9   ][ 1 ]
</span><span class="cx">         // The minimum widths are: [ 2 ][ 7 ][ 1 ]
</span><span class="lines">@@ -354,7 +378,7 @@
</span><span class="cx">             float currentSpanningMinimumWidth = 0;
</span><span class="cx">             // 1. Collect the non-spaning minimum widths.
</span><span class="cx">             for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
</span><del>-                currentSpanningMinimumWidth += columnMinimumWidths[columnIndex];
</del><ins>+                currentSpanningMinimumWidth += columnMinimumWidths[columnIndex].value;
</ins><span class="cx">             float spanningMinimumWidth = slot.widthConstraints().minimum;
</span><span class="cx">             if (currentSpanningMinimumWidth >= spanningMinimumWidth) {
</span><span class="cx">                 // The spanning cell fits the spanned columns just fine. Nothing to distribute.
</span><span class="lines">@@ -365,30 +389,29 @@
</span><span class="cx">             // New minimum widths: [ 3 ] [ 6 ].
</span><span class="cx">             auto spaceToDistribute = spanningMinimumWidth - currentSpanningMinimumWidth;
</span><span class="cx">             for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
</span><del>-                columnMinimumWidths[columnIndex] += spaceToDistribute / currentSpanningMinimumWidth * columnMinimumWidths[columnIndex];
</del><ins>+                columnMinimumWidths[columnIndex].value += spaceToDistribute / currentSpanningMinimumWidth * columnMinimumWidths[columnIndex].value;
</ins><span class="cx">         }
</span><span class="cx">         // 3. Distribute the extra space using the final minimum widths.
</span><del>-        float adjustabledHorizontalSpace = tableWidthConstraints.minimum - grid.totalHorizontalSpacing();
-        auto numberOfColumns = columnList.size();
</del><span class="cx">         // Fixed width columns don't participate in available space distribution.
</span><del>-        for (auto& column : columnList) {
-            if (!column.isFixedWidth())
</del><ins>+        // Unless there are no flexing column at all, then they start flexing as if they were not fixed at all.
+        float adjustabledHorizontalSpace = 0;
+        for (auto& columnMinimumWidth : columnMinimumWidths) {
+            if (!columnMinimumWidth.shouldFlex)
</ins><span class="cx">                 continue;
</span><del>-            auto columnFixedWidth = *column.box()->columnWidth();
-            column.setLogicalWidth(columnFixedWidth);
-
-            --numberOfColumns;
-            adjustabledHorizontalSpace -= columnFixedWidth;
</del><ins>+            adjustabledHorizontalSpace += columnMinimumWidth.value;
</ins><span class="cx">         }
</span><del>-        if (!numberOfColumns || !adjustabledHorizontalSpace)
</del><ins>+        if (!adjustabledHorizontalSpace)
</ins><span class="cx">             return;
</span><del>-        ASSERT(adjustabledHorizontalSpace > 0);
</del><ins>+        // FIXME: Implement overconstrained columns when fixed width content is wider than the table.
</ins><span class="cx">         for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
</span><span class="cx">             auto& column = columns.list()[columnIndex];
</span><del>-            if (column.isFixedWidth())
</del><ins>+            auto minimumWidth = columnMinimumWidths[columnIndex].value;
+            if (!columnMinimumWidths[columnIndex].shouldFlex) {
+                column.setLogicalWidth(LayoutUnit { minimumWidth });
</ins><span class="cx">                 continue;
</span><del>-            auto columnExtraSpace = horizontalSpaceToDistribute / adjustabledHorizontalSpace * columnMinimumWidths[columnIndex];
-            column.setLogicalWidth(LayoutUnit { columnMinimumWidths[columnIndex] + columnExtraSpace });
</del><ins>+            }
+            auto columnExtraSpace = horizontalSpaceToDistribute / adjustabledHorizontalSpace * minimumWidth;
+            column.setLogicalWidth(LayoutUnit { minimumWidth + columnExtraSpace });
</ins><span class="cx">         }
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorelayouttableformattingTableGridcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp (259983 => 259984)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp        2020-04-12 17:53:37 UTC (rev 259983)
+++ trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp   2020-04-12 18:32:07 UTC (rev 259984)
</span><span class="lines">@@ -83,6 +83,15 @@
</span><span class="cx">     m_columnList.append({ nullptr });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool TableGrid::Columns::hasFixedColumnsOnly() const
+{
+    for (auto& column : m_columnList) {
+        if (!column.isFixedWidth())
+            return false;
+    }
+    return true;
+}
+
</ins><span class="cx"> void TableGrid::Rows::addRow(const ContainerBox& rowBox)
</span><span class="cx"> {
</span><span class="cx">     m_rowList.append({ rowBox });
</span></span></pre></div>
<a id="trunkSourceWebCorelayouttableformattingTableGridh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/tableformatting/TableGrid.h (259983 => 259984)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/tableformatting/TableGrid.h  2020-04-12 17:53:37 UTC (rev 259983)
+++ trunk/Source/WebCore/layout/tableformatting/TableGrid.h     2020-04-12 18:32:07 UTC (rev 259984)
</span><span class="lines">@@ -100,6 +100,7 @@
</span><span class="cx">         void addAnonymousColumn();
</span><span class="cx"> 
</span><span class="cx">         LayoutUnit logicalWidth() const { return m_columnList.last().logicalRight() - m_columnList.first().logicalLeft(); }
</span><ins>+        bool hasFixedColumnsOnly() const;
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         ColumnList m_columnList;
</span></span></pre>
</div>
</div>

</body>
</html>