Diff
Modified: trunk/Source/WebCore/ChangeLog (260509 => 260510)
--- trunk/Source/WebCore/ChangeLog 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/ChangeLog 2020-04-22 14:42:38 UTC (rev 260510)
@@ -1,3 +1,27 @@
+2020-04-22 Zalan Bujtas <[email protected]>
+
+ [LFC][TFC] Introduce TableFormattingContext::computeAndDistributeExtraVerticalSpace
+ https://bugs.webkit.org/show_bug.cgi?id=210830
+
+ Reviewed by Antti Koivisto.
+
+ Add a dedicated function to compute preferred heights for the table rows.
+ This is in preparation for the 2 pass layout required to finalize row height.
+
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::computeBorderAndPadding):
+ * layout/FormattingContext.h:
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::FormattingContext::Geometry::computedPadding const):
+ * layout/tableformatting/TableFormattingContext.cpp:
+ (WebCore::Layout::TableFormattingContext::layoutInFlowContent):
+ (WebCore::Layout::TableFormattingContext::layoutCell):
+ (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
+ (WebCore::Layout::TableFormattingContext::setComputedGeometryForRows):
+ (WebCore::Layout::TableFormattingContext::setComputedGeometryForSections):
+ (WebCore::Layout::TableFormattingContext::positionTableCells): Deleted.
+ * layout/tableformatting/TableFormattingContext.h:
+
2020-04-22 Claudio Saavedra <[email protected]>
[GTK4] Several fixes to GdkEvent APIs for GTK4
Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (260509 => 260510)
--- trunk/Source/WebCore/layout/FormattingContext.cpp 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp 2020-04-22 14:42:38 UTC (rev 260510)
@@ -130,7 +130,7 @@
{
auto& displayBox = formattingState().displayBox(layoutBox);
displayBox.setBorder(geometry().computedBorder(layoutBox));
- displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint));
+ displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint.logicalWidth));
}
void FormattingContext::layoutOutOfFlowContent(InvalidationState& invalidationState, const OutOfFlowHorizontalConstraints& rootHorizontalConstraints, const VerticalConstraints& rootVerticalConstraints)
Modified: trunk/Source/WebCore/layout/FormattingContext.h (260509 => 260510)
--- trunk/Source/WebCore/layout/FormattingContext.h 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContext.h 2020-04-22 14:42:38 UTC (rev 260510)
@@ -128,7 +128,7 @@
LayoutUnit shrinkToFitWidth(const Box&, LayoutUnit availableWidth);
Edges computedBorder(const Box&) const;
- Optional<Edges> computedPadding(const Box&, const HorizontalConstraints&) const;
+ Optional<Edges> computedPadding(const Box&, LayoutUnit containingBlockWidth) const;
ComputedHorizontalMargin computedHorizontalMargin(const Box&, const HorizontalConstraints&) const;
ComputedVerticalMargin computedVerticalMargin(const Box&, const HorizontalConstraints&) const;
Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (260509 => 260510)
--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2020-04-22 14:42:38 UTC (rev 260510)
@@ -1049,13 +1049,12 @@
};
}
-Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const LayoutUnit containingBlockWidth) const
{
if (!layoutBox.isPaddingApplicable())
return WTF::nullopt;
auto& style = layoutBox.style();
- auto containingBlockWidth = horizontalConstraints.logicalWidth;
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
return Edges {
{ valueForLength(style.paddingLeft(), containingBlockWidth), valueForLength(style.paddingRight(), containingBlockWidth) },
Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (260509 => 260510)
--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp 2020-04-22 14:42:38 UTC (rev 260510)
@@ -61,55 +61,53 @@
{
}
-void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints&)
+void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
{
auto& grid = formattingState().tableGrid();
- auto& columns = grid.columns();
-
+ auto& columnList = grid.columns().list();
+ auto& rowList = grid.rows().list();
+ // 1. Compute width and height for the grid.
computeAndDistributeExtraHorizontalSpace(horizontalConstraints.logicalWidth);
- // 1. Position each column.
- // FIXME: This should also deal with collapsing borders etc.
+ computeAndDistributeExtraVerticalSpace(horizontalConstraints.logicalWidth, verticalConstraints.logicalHeight);
+ // 2. Position columns.
auto horizontalSpacing = grid.horizontalSpacing();
auto columnLogicalLeft = horizontalSpacing;
- for (auto& column : columns.list()) {
+ for (auto& column : columnList) {
column.setLogicalLeft(columnLogicalLeft);
- columnLogicalLeft += (column.logicalWidth() + horizontalSpacing);
+ columnLogicalLeft += column.logicalWidth() + horizontalSpacing;
}
-
- // 2. Layout each table cell (and compute row height as well).
+ // 3. Position rows.
+ auto verticalSpacing = grid.verticalSpacing();
+ auto rowLogicalTop = verticalSpacing;
+ for (auto& row : rowList) {
+ row.setLogicalTop(rowLogicalTop);
+ rowLogicalTop += row.logicalHeight() + verticalSpacing;
+ }
+ // 4. Position cells.
+ for (auto& cell : grid.cells()) {
+ auto& cellDisplayBox = formattingState().displayBox(cell->box());
+ cellDisplayBox.setTop(rowList[cell->startRow()].logicalTop());
+ cellDisplayBox.setLeft(columnList[cell->startColumn()].logicalLeft());
+ }
+ // 5. Final table cell layout. At this point all percentage values can be resolved.
auto& cellList = grid.cells();
ASSERT(!cellList.isEmpty());
- for (auto& cell : cellList) {
- auto& cellBox = cell->box();
- layoutCell(*cell, invalidationState, horizontalConstraints);
- // FIXME: Add support for column and row spanning and this requires a 2 pass layout.
- auto& row = grid.rows().list().at(cell->startRow());
- row.setLogicalHeight(std::max(row.logicalHeight(), geometryForBox(cellBox).marginBoxHeight()));
- }
- // This is after the second pass when cell heights are fully computed.
- auto rowLogicalTop = grid.verticalSpacing();
- for (auto& row : grid.rows().list()) {
- row.setLogicalTop(rowLogicalTop);
- rowLogicalTop += (row.logicalHeight() + grid.verticalSpacing());
- }
-
+ for (auto& cell : cellList)
+ layoutCell(*cell, invalidationState, horizontalConstraints.logicalWidth);
// 3. Finalize size and position.
- positionTableCells();
setComputedGeometryForSections();
setComputedGeometryForRows();
}
-void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints)
+void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, LayoutUnit availableHorizontalSpace)
{
auto& cellBox = cell.box();
- computeBorderAndPadding(cellBox, horizontalConstraints);
+ computeBorderAndPadding(cellBox, HorizontalConstraints { { }, availableHorizontalSpace });
// Margins do not apply to internal table elements.
auto& cellDisplayBox = formattingState().displayBox(cellBox);
cellDisplayBox.setHorizontalMargin({ });
cellDisplayBox.setHorizontalComputedMargin({ });
- // Don't know the actual position yet.
- cellDisplayBox.setTopLeft({ });
- auto contentWidth = [&] {
+ auto availableSpaceForContent = [&] {
auto& grid = formattingState().tableGrid();
auto& columnList = grid.columns().list();
auto logicalWidth = LayoutUnit { };
@@ -119,7 +117,7 @@
logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
return logicalWidth - cellDisplayBox.horizontalMarginBorderAndPadding();
}();
- cellDisplayBox.setContentBoxWidth(contentWidth);
+ cellDisplayBox.setContentBoxWidth(availableSpaceForContent);
ASSERT(cellBox.establishesBlockFormattingContext());
if (cellBox.hasInFlowOrFloatingChild()) {
@@ -133,46 +131,6 @@
// FIXME: Check what to do with out-of-flow content.
}
-void TableFormattingContext::positionTableCells()
-{
- auto& grid = formattingState().tableGrid();
- auto& rowList = grid.rows().list();
- auto& columnList = grid.columns().list();
- for (auto& cell : grid.cells()) {
- auto& cellDisplayBox = formattingState().displayBox(cell->box());
- cellDisplayBox.setTop(rowList.at(cell->startRow()).logicalTop());
- cellDisplayBox.setLeft(columnList.at(cell->startColumn()).logicalLeft());
- }
-}
-
-void TableFormattingContext::setComputedGeometryForRows()
-{
- auto& grid = formattingState().tableGrid();
- auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
-
- for (auto& row : grid.rows().list()) {
- auto& rowDisplayBox = formattingState().displayBox(row.box());
- initializeDisplayBoxToBlank(rowDisplayBox);
- rowDisplayBox.setContentBoxHeight(row.logicalHeight());
- rowDisplayBox.setContentBoxWidth(rowWidth);
- rowDisplayBox.setTop(row.logicalTop());
- }
-}
-
-void TableFormattingContext::setComputedGeometryForSections()
-{
- auto& grid = formattingState().tableGrid();
- auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
-
- for (auto& section : childrenOfType<Box>(root())) {
- auto& sectionDisplayBox = formattingState().displayBox(section);
- initializeDisplayBoxToBlank(sectionDisplayBox);
- // FIXME: Size table sections properly.
- sectionDisplayBox.setContentBoxWidth(sectionWidth);
- sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
- }
-}
-
FormattingContext::IntrinsicWidthConstraints TableFormattingContext::computedIntrinsicWidthConstraints()
{
// Tables have a slighty different concept of shrink to fit. It's really only different with non-auto "width" values, where
@@ -479,7 +437,63 @@
computeColumnWidths(ColumnWidthBalancingBase::MinimumWidth, horizontalSpaceToDistribute);
}
+void TableFormattingContext::computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit>)
+{
+ auto& grid = formattingState().tableGrid();
+ auto& columns = grid.columns().list();
+ auto& rows = grid.rows();
+
+ Vector<float> rownHeights;
+ // 1. Collect initial row heights.
+ for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
+ float maximumColumnHeight = 0;
+ for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
+ auto& slot = *grid.slot({ columnIndex, rowIndex });
+ if (slot.isColumnSpanned())
+ continue;
+ auto invalidationState = InvalidationState { };
+ layoutCell(slot.cell(), invalidationState, availableHorizontalSpace);
+ maximumColumnHeight = std::max<float>(maximumColumnHeight, geometryForBox(slot.cell().box()).height());
+ }
+ // <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()));
+ }
+
+ for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex)
+ grid.rows().list()[rowIndex].setLogicalHeight(LayoutUnit { rownHeights[rowIndex] });
}
+
+void TableFormattingContext::setComputedGeometryForRows()
+{
+ auto& grid = formattingState().tableGrid();
+ auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
+
+ for (auto& row : grid.rows().list()) {
+ auto& rowDisplayBox = formattingState().displayBox(row.box());
+ initializeDisplayBoxToBlank(rowDisplayBox);
+ rowDisplayBox.setContentBoxHeight(row.logicalHeight());
+ rowDisplayBox.setContentBoxWidth(rowWidth);
+ rowDisplayBox.setTop(row.logicalTop());
+ }
}
+void TableFormattingContext::setComputedGeometryForSections()
+{
+ auto& grid = formattingState().tableGrid();
+ auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
+
+ for (auto& section : childrenOfType<Box>(root())) {
+ auto& sectionDisplayBox = formattingState().displayBox(section);
+ initializeDisplayBoxToBlank(sectionDisplayBox);
+ // FIXME: Size table sections properly.
+ sectionDisplayBox.setContentBoxWidth(sectionWidth);
+ sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
+ }
+}
+
+}
+}
+
#endif
Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h (260509 => 260510)
--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h 2020-04-22 14:40:00 UTC (rev 260509)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h 2020-04-22 14:42:38 UTC (rev 260510)
@@ -60,7 +60,7 @@
TableFormattingContext::Geometry geometry() const { return Geometry(*this); }
IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
- void layoutCell(const TableGrid::Cell&, InvalidationState&, const HorizontalConstraints&);
+ void layoutCell(const TableGrid::Cell&, InvalidationState&, LayoutUnit availableHorizontalSpace);
void positionTableCells();
void setComputedGeometryForRows();
void setComputedGeometryForSections();
@@ -68,6 +68,7 @@
void ensureTableGrid();
IntrinsicWidthConstraints computedPreferredWidthForColumns();
void computeAndDistributeExtraHorizontalSpace(LayoutUnit availableHorizontalSpace);
+ void computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> availableVerticalSpace);
void initializeDisplayBoxToBlank(Display::Box&) const;