Title: [260582] trunk
Revision
260582
Author
za...@apple.com
Date
2020-04-23 10:49:44 -0700 (Thu, 23 Apr 2020)

Log Message

[LFC][TFC] Add support for basic baseline align inside a table row
https://bugs.webkit.org/show_bug.cgi?id=210918

Reviewed by Antti Koivisto.

Source/WebCore:

Test: fast/layoutformattingcontext/table-basic-row-baseline-align.html

The minimum height of a row is defined as the height of an hypothetical linebox containing
the cells originating in the row. In this hypothetical linebox, we use baseline alignment to
align the cells vertically.
Use these vertically aligned cells to compute the final row height.

* layout/displaytree/DisplayBox.h:
(WebCore::Display::Box::verticalMarginBorderAndPadding const):
(WebCore::Display::Box::setVerticalPadding):
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::layoutInFlowContent):
(WebCore::Layout::TableFormattingContext::layoutCell):
(WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
* layout/tableformatting/TableFormattingContext.h:

LayoutTests:

* fast/layoutformattingcontext/table-basic-row-baseline-align-expected.txt: Added.
* fast/layoutformattingcontext/table-basic-row-baseline-align.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (260581 => 260582)


--- trunk/LayoutTests/ChangeLog	2020-04-23 17:48:58 UTC (rev 260581)
+++ trunk/LayoutTests/ChangeLog	2020-04-23 17:49:44 UTC (rev 260582)
@@ -1,3 +1,13 @@
+2020-04-23  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][TFC] Add support for basic baseline align inside a table row
+        https://bugs.webkit.org/show_bug.cgi?id=210918
+
+        Reviewed by Antti Koivisto.
+
+        * fast/layoutformattingcontext/table-basic-row-baseline-align-expected.txt: Added.
+        * fast/layoutformattingcontext/table-basic-row-baseline-align.html: Added.
+
 2020-04-23  Chris Dumez  <cdu...@apple.com>
 
         http/tests/paymentrequest/page-cache-completed-payment-response.https.html is flaky failing.

Added: trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align-expected.txt (0 => 260582)


--- trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align-expected.txt	2020-04-23 17:49:44 UTC (rev 260582)
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x100
+  RenderBlock {HTML} at (0,0) size 800x100
+    RenderBody {BODY} at (8,8) size 784x84
+      RenderTable {TABLE} at (0,0) size 60x84
+        RenderTableSection {TBODY} at (0,0) size 60x84
+          RenderTableRow {TR} at (0,2) size 60x55
+            RenderTableCell {TD} at (2,2) size 47x55 [r=0 c=0 rs=1 cs=1]
+              RenderText {#text} at (1,41) size 5x13
+                text run at (1,41) width 5: "#"
+              RenderImage {IMG} at (6,1) size 40x50
+            RenderTableCell {TD} at (51,22) size 7x15 [r=0 c=1 rs=1 cs=1]
+              RenderText {#text} at (1,1) size 5x13
+                text run at (1,1) width 5: "#"
+          RenderTableRow {TR} at (0,59) size 60x23
+            RenderTableCell {TD} at (2,59) size 56x23 [r=1 c=0 rs=1 cs=2]
+              RenderText {#text} at (5,5) size 15x13
+                text run at (5,5) width 15: "###"

Added: trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align.html (0 => 260582)


--- trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/table-basic-row-baseline-align.html	2020-04-23 17:49:44 UTC (rev 260582)
@@ -0,0 +1,10 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+table {
+    font-size: 10px;
+}
+</style>
+<table>
+<tr><td>#<img height=50px width=40px src=""
+<tr><td colspan=2 style="padding: 5px">###</td></tr>
+</table>

Modified: trunk/Source/WebCore/ChangeLog (260581 => 260582)


--- trunk/Source/WebCore/ChangeLog	2020-04-23 17:48:58 UTC (rev 260581)
+++ trunk/Source/WebCore/ChangeLog	2020-04-23 17:49:44 UTC (rev 260582)
@@ -1,3 +1,26 @@
+2020-04-23  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][TFC] Add support for basic baseline align inside a table row
+        https://bugs.webkit.org/show_bug.cgi?id=210918
+
+        Reviewed by Antti Koivisto.
+
+        Test: fast/layoutformattingcontext/table-basic-row-baseline-align.html
+
+        The minimum height of a row is defined as the height of an hypothetical linebox containing
+        the cells originating in the row. In this hypothetical linebox, we use baseline alignment to
+        align the cells vertically.
+        Use these vertically aligned cells to compute the final row height.  
+
+        * layout/displaytree/DisplayBox.h:
+        (WebCore::Display::Box::verticalMarginBorderAndPadding const):
+        (WebCore::Display::Box::setVerticalPadding):
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::TableFormattingContext::layoutCell):
+        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
+        * layout/tableformatting/TableFormattingContext.h:
+
 2020-04-23  Sihui Liu  <sihui_...@apple.com>
 
         TextManipulationController should set range of paragraph using token's positions

Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.h (260581 => 260582)


--- trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2020-04-23 17:48:58 UTC (rev 260581)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2020-04-23 17:49:44 UTC (rev 260582)
@@ -103,6 +103,7 @@
     LayoutUnit marginBoxHeight() const { return marginBefore() + borderBoxHeight() + marginAfter(); }
     LayoutUnit marginBoxWidth() const { return marginStart() + borderBoxWidth() + marginEnd(); }
 
+    LayoutUnit verticalMarginBorderAndPadding() const { return marginBefore() + verticalBorder() + verticalPadding().valueOr(0) + marginAfter(); }
     LayoutUnit horizontalMarginBorderAndPadding() const { return marginStart() + horizontalBorder() + horizontalPadding().valueOr(0) + marginEnd(); }
 
     Rect marginBox() const;
@@ -133,6 +134,8 @@
     void setHasClearance() { m_hasClearance = true; }
 
     void setBorder(Layout::Edges);
+
+    void setVerticalPadding(Layout::VerticalEdges);
     void setPadding(Optional<Layout::Edges>);
 
 private:
@@ -305,6 +308,14 @@
     m_padding = padding;
 }
 
+inline void Box::setVerticalPadding(Layout::VerticalEdges verticalPadding)
+{
+#if ASSERT_ENABLED
+    setHasValidPadding();
+#endif
+    m_padding = Layout::Edges { m_padding ? m_padding->horizontal : Layout::HorizontalEdges(), verticalPadding };
+}
+
 inline Rect Box::rectWithMargin() const
 {
     auto marginAfter = this->marginAfter();

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (260581 => 260582)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-04-23 17:48:58 UTC (rev 260581)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-04-23 17:49:44 UTC (rev 260582)
@@ -83,7 +83,7 @@
         row.setLogicalTop(rowLogicalTop);
         rowLogicalTop += row.logicalHeight() + verticalSpacing;
     }
-    // 4. Position cells.
+    // 4. Position and size cells.
     for (auto& cell : grid.cells()) {
         auto& cellDisplayBox = formattingState().displayBox(cell->box());
         cellDisplayBox.setTop(rowList[cell->startRow()].logicalTop());
@@ -93,13 +93,13 @@
     auto& cellList = grid.cells();
     ASSERT(!cellList.isEmpty());
     for (auto& cell : cellList)
-        layoutCell(*cell, invalidationState, horizontalConstraints.logicalWidth);
+        layoutCell(*cell, invalidationState, horizontalConstraints.logicalWidth, grid.rows().list()[cell->startRow()].logicalHeight());
     // 3. Finalize size and position.
     setComputedGeometryForSections();
     setComputedGeometryForRows();
 }
 
-void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, LayoutUnit availableHorizontalSpace)
+void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> usedCellHeight)
 {
     auto& cellBox = cell.box();
     computeBorderAndPadding(cellBox, HorizontalConstraints { { }, availableHorizontalSpace });
@@ -123,11 +123,19 @@
     if (cellBox.hasInFlowOrFloatingChild()) {
         auto formattingContextForCellContent = LayoutContext::createFormattingContext(cellBox, layoutState());
         auto horizontalConstraintsForCellContent = Geometry::horizontalConstraintsForInFlow(cellDisplayBox);
-        auto verticalConstraintsForCellContent = Geometry::verticalConstraintsForInFlow(cellDisplayBox);
+        auto verticalConstraintsForCellContent = VerticalConstraints { cellDisplayBox.contentBoxTop(), usedCellHeight };
         formattingContextForCellContent->layoutInFlowContent(invalidationState, horizontalConstraintsForCellContent, verticalConstraintsForCellContent);
     }
     cellDisplayBox.setVerticalMargin({ { }, { } });
-    cellDisplayBox.setContentBoxHeight(geometry().tableCellHeightAndMargin(cellBox).contentHeight);
+    auto contentHeight = geometry().tableCellHeightAndMargin(cellBox).contentHeight;
+    if (usedCellHeight) {
+        // FIXME: Find out if it is ok to use the regular padding here to align the content box inside a tall cell or we need to 
+        // use some kind of intrinsic padding similar to RenderTableCell.
+        auto verticalBorder = cellDisplayBox.verticalBorder();
+        auto intrinsicVerticalPadding = std::max(0_lu, *usedCellHeight - verticalBorder - contentHeight);
+        cellDisplayBox.setVerticalPadding({ intrinsicVerticalPadding / 2, intrinsicVerticalPadding / 2 });
+    }
+    cellDisplayBox.setContentBoxHeight(contentHeight);
     // FIXME: Check what to do with out-of-flow content.
 }
 
@@ -446,7 +454,8 @@
     Vector<float> rownHeights;
     // 1. Collect initial row heights.
     for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
-        float maximumColumnHeight = 0;
+        float maximumColumnAscent = 0;
+        float maximumColumnDescent = 0;
         for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
             auto& slot = *grid.slot({ columnIndex, rowIndex });
             if (slot.isColumnSpanned())
@@ -453,12 +462,26 @@
                 continue;
             auto invalidationState = InvalidationState { };
             layoutCell(slot.cell(), invalidationState, availableHorizontalSpace);
-            maximumColumnHeight = std::max<float>(maximumColumnHeight, geometryForBox(slot.cell().box()).height());
+            // The minimum height of a row (without spanning-related height distribution) is defined as the height of an hypothetical
+            // linebox containing the cells originating in the row.
+            auto& cellBox = slot.cell().box();
+            auto& cellDisplayBox = geometryForBox(cellBox);
+            auto cellBaselineOffset = InlineLayoutUnit { };
+            if (cellBox.establishesInlineFormattingContext()) {
+                // The baseline of a cell is defined as the baseline of the first in-flow line box in the cell,
+                // or the first in-flow table-row in the cell, whichever comes first
+                auto& firstLineBox = layoutState().establishedInlineFormattingState(cellBox).displayInlineContent()->lineBoxes[0];
+                cellBaselineOffset = firstLineBox.baselineOffset();
+            } else {
+                // If there is no such line box, the baseline is the bottom of content edge of the cell box.
+                cellBaselineOffset = cellDisplayBox.contentBoxBottom();
+            }
+            maximumColumnAscent = std::max<float>(maximumColumnAscent, cellBaselineOffset);
+            maximumColumnDescent = std::max<float>(maximumColumnDescent, cellDisplayBox.height() - cellBaselineOffset);
         }
         // <tr style="height: 10px"> is considered as min height.
         auto computedRowHeight = geometry().computedContentHeight(rows.list()[rowIndex].box(), { }).valueOr(LayoutUnit { });
-        // FIXME: add support for baseline syncing.
-        rownHeights.append(std::max(maximumColumnHeight, computedRowHeight.toFloat()));
+        rownHeights.append(std::max(computedRowHeight.toFloat(), maximumColumnAscent + maximumColumnDescent));
     }
 
     for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex)

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h (260581 => 260582)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-04-23 17:48:58 UTC (rev 260581)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-04-23 17:49:44 UTC (rev 260582)
@@ -60,7 +60,7 @@
     TableFormattingContext::Geometry geometry() const { return Geometry(*this); }
 
     IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
-    void layoutCell(const TableGrid::Cell&, InvalidationState&, LayoutUnit availableHorizontalSpace);
+    void layoutCell(const TableGrid::Cell&, InvalidationState&, LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> usedCellHeight = WTF::nullopt);
     void positionTableCells();
     void setComputedGeometryForRows();
     void setComputedGeometryForSections();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to