[LFC][TFC] TableFormattingContext::distributeExtraHorizontalSpace should not ignore fixed width columns
https://bugs.webkit.org/show_bug.cgi?id=203010

Reviewed by Antti Koivisto.

Fixed width columns (e.g. <col width=100px>) don't participate in the extra horizontal space distribution.

* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::computedTableWidth):
(WebCore::Layout::TableFormattingContext::distributeExtraHorizontalSpace):
(WebCore::Layout::TableFormattingContext::distributeAvailableWidth): Deleted.
* layout/tableformatting/TableFormattingContext.h:
* layout/tableformatting/TableGrid.cpp:
(WebCore::Layout::TableGrid::Column::hasFixedWidth const):
(WebCore::Layout::TableGrid::widthConstraints const):
* layout/tableformatting/TableGrid.h:
(WebCore::Layout::TableGrid::totalHorizontalSpacing const):
(WebCore::Layout::TableGrid::columnsContext const):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 1566464..eac9820 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2019-10-16  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][TFC] TableFormattingContext::distributeExtraHorizontalSpace should not ignore fixed width columns
+        https://bugs.webkit.org/show_bug.cgi?id=203010
+
+        Reviewed by Antti Koivisto.
+
+        Fixed width columns (e.g. <col width=100px>) don't participate in the extra horizontal space distribution.
+
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::computedTableWidth):
+        (WebCore::Layout::TableFormattingContext::distributeExtraHorizontalSpace):
+        (WebCore::Layout::TableFormattingContext::distributeAvailableWidth): Deleted.
+        * layout/tableformatting/TableFormattingContext.h:
+        * layout/tableformatting/TableGrid.cpp:
+        (WebCore::Layout::TableGrid::Column::hasFixedWidth const):
+        (WebCore::Layout::TableGrid::widthConstraints const):
+        * layout/tableformatting/TableGrid.h:
+        (WebCore::Layout::TableGrid::totalHorizontalSpacing const):
+        (WebCore::Layout::TableGrid::columnsContext const):
+
 2019-10-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK][WPE] ASSERTION FAILED: blob in SQLiteStatement.cpp(163) : int WebCore::SQLiteStatement::bindBlob()
diff --git a/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp b/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
index bf1466f0..5a66389 100644
--- a/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
+++ b/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
@@ -279,12 +279,13 @@
     auto& grid = formattingState().tableGrid();
     auto& columnsContext = grid.columnsContext();
     auto tableWidthConstraints = grid.widthConstraints();
+    auto totalHorizontalSpacing = grid.totalHorizontalSpacing();
 
     auto width = geometry().computedValueIfNotAuto(style.width(), containingBlockWidth);
     LayoutUnit usedWidth;
     if (width) {
         if (*width > tableWidthConstraints.minimum) {
-            distributeAvailableWidth(*width - tableWidthConstraints.minimum);
+            distributeExtraHorizontalSpace(*width - totalHorizontalSpacing, tableWidthConstraints.minimum - totalHorizontalSpacing);
             usedWidth = *width;
         } else {
             usedWidth = tableWidthConstraints.minimum;
@@ -299,7 +300,7 @@
             useAsContentLogicalWidth(WidthConstraintsType::Maximum);
         } else {
             usedWidth = containingBlockWidth;
-            distributeAvailableWidth(*width - tableWidthConstraints.minimum);
+            distributeExtraHorizontalSpace(usedWidth - totalHorizontalSpacing, tableWidthConstraints.minimum - totalHorizontalSpacing);
         }
     }
     // FIXME: This should also deal with collapsing borders etc.
@@ -312,15 +313,36 @@
     return usedWidth;
 }
 
-void TableFormattingContext::distributeAvailableWidth(LayoutUnit extraHorizontalSpace)
+void TableFormattingContext::distributeExtraHorizontalSpace(LayoutUnit availableContentWidth, LayoutUnit tableMinimumContentWidth)
 {
-    // FIXME: Right now just distribute the extra space equaly among the columns.
-    auto& columns = formattingState().tableGrid().columnsContext().columns();
+    ASSERT(availableContentWidth >= tableMinimumContentWidth);
+    auto& grid = formattingState().tableGrid();
+    auto& columns = grid.columnsContext().columns();
     ASSERT(!columns.isEmpty());
 
-    auto columnExtraSpace = extraHorizontalSpace / columns.size();
-    for (auto& column : columns)
+    auto extraHorizontalSpace = availableContentWidth - tableMinimumContentWidth;
+    auto adjustabledHorizontalSpace = tableMinimumContentWidth;
+    auto numberOfColumns = columns.size();
+    // Fixed width columns don't participate in available space distribution.
+    for (auto& column : columns) {
+        if (!column.hasFixedWidth())
+            continue;
+        auto columnFixedWidth = *column.columnBox()->columnWidth();
+        column.setLogicalWidth(columnFixedWidth);
+
+        --numberOfColumns;
+        adjustabledHorizontalSpace -= columnFixedWidth;
+    }
+    if (!numberOfColumns || !adjustabledHorizontalSpace)
+        return;
+    // FIXME: Right now just distribute the extra space equaly among the columns using the minimum width.
+    ASSERT(adjustabledHorizontalSpace > 0);
+    for (auto& column : columns) {
+        if (column.hasFixedWidth())
+            continue;
+        auto columnExtraSpace = extraHorizontalSpace / adjustabledHorizontalSpace * column.widthConstraints().minimum;
         column.setLogicalWidth(column.widthConstraints().minimum + columnExtraSpace);
+    }
 }
 
 void TableFormattingContext::useAsContentLogicalWidth(WidthConstraintsType type)
diff --git a/Source/WebCore/layout/tableformatting/TableFormattingContext.h b/Source/WebCore/layout/tableformatting/TableFormattingContext.h
index 747d207..fa386a1 100644
--- a/Source/WebCore/layout/tableformatting/TableFormattingContext.h
+++ b/Source/WebCore/layout/tableformatting/TableFormattingContext.h
@@ -66,7 +66,7 @@
 
     void ensureTableGrid();
     void computePreferredWidthForColumns();
-    void distributeAvailableWidth(LayoutUnit extraHorizontalSpace);
+    void distributeExtraHorizontalSpace(LayoutUnit availableContentWidth, LayoutUnit tableMinimumContentWidth);
     enum class WidthConstraintsType { Minimum, Maximum };
     void useAsContentLogicalWidth(WidthConstraintsType);
 
diff --git a/Source/WebCore/layout/tableformatting/TableGrid.cpp b/Source/WebCore/layout/tableformatting/TableGrid.cpp
index dca1916..9995c42 100644
--- a/Source/WebCore/layout/tableformatting/TableGrid.cpp
+++ b/Source/WebCore/layout/tableformatting/TableGrid.cpp
@@ -82,6 +82,12 @@
     return m_computedLogicalLeft;
 }
 
+bool TableGrid::Column::hasFixedWidth() const
+{
+    // FIXME: This only covers the <col> attribute case.
+    return columnBox() && columnBox()->columnWidth();
+}
+
 void TableGrid::ColumnsContext::addColumn(const Box* columnBox)
 {
     m_columns.append({ columnBox });
@@ -173,7 +179,7 @@
     auto widthConstraints = FormattingContext::IntrinsicWidthConstraints { };
     for (auto& column : m_columnsContext.columns())
         widthConstraints += column.widthConstraints();
-    widthConstraints.expand((m_columnsContext.columns().size() + 1) * m_horizontalSpacing); 
+    widthConstraints.expand(totalHorizontalSpacing()); 
     return widthConstraints;
 }
 
diff --git a/Source/WebCore/layout/tableformatting/TableGrid.h b/Source/WebCore/layout/tableformatting/TableGrid.h
index 66ebad2..b0ca0de 100644
--- a/Source/WebCore/layout/tableformatting/TableGrid.h
+++ b/Source/WebCore/layout/tableformatting/TableGrid.h
@@ -48,6 +48,7 @@
 
     void setHorizontalSpacing(LayoutUnit horizontalSpacing) { m_horizontalSpacing = horizontalSpacing; }
     LayoutUnit horizontalSpacing() const { return m_horizontalSpacing; }
+    LayoutUnit totalHorizontalSpacing() const { return columnsContext().columns().size() * horizontalSpacing(); }
 
     void setVerticalSpacing(LayoutUnit verticalSpacing) { m_verticalSpacing = verticalSpacing; }
     LayoutUnit verticalSpacing() const { return m_verticalSpacing; }
@@ -80,6 +81,8 @@
         void setLogicalWidth(LayoutUnit);
         LayoutUnit logicalWidth() const;
 
+        bool hasFixedWidth() const;
+
         const Box* columnBox() const { return m_columnBox.get(); }
 
     private:
@@ -112,6 +115,7 @@
 
         ColumnList m_columns;
     };
+    const ColumnsContext& columnsContext() const { return m_columnsContext; }
     ColumnsContext& columnsContext() { return m_columnsContext; }
 
     struct Row {