⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278294 in webkit


Ignore:
Timestamp:
May 31, 2021, 9:31:04 PM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][TFC] Decouple stretching and final cell layouts
https://bugs.webkit.org/show_bug.cgi?id=226452

Reviewed by Antti Koivisto.

Stretching layout is slightly different from the final cell layout.

  • layout/formattingContexts/table/TableFormattingContext.cpp:

(WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
(WebCore::Layout::TableFormattingContext::computeAndDistributeExtraSpace):
(WebCore::Layout::TableFormattingContext::layoutCell): Deleted.

  • layout/formattingContexts/table/TableFormattingContext.h:
  • layout/formattingContexts/table/TableFormattingGeometry.cpp:

(WebCore::Layout::TableFormattingGeometry::horizontalSpaceForCellContent const):
(WebCore::Layout::TableFormattingGeometry::verticalSpaceForCellContent const):

  • layout/formattingContexts/table/TableFormattingGeometry.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r278292 r278294  
     12021-05-31  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][TFC] Decouple stretching and final cell layouts
     4        https://bugs.webkit.org/show_bug.cgi?id=226452
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Stretching layout is slightly different from the final cell layout.
     9
     10        * layout/formattingContexts/table/TableFormattingContext.cpp:
     11        (WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
     12        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraSpace):
     13        (WebCore::Layout::TableFormattingContext::layoutCell): Deleted.
     14        * layout/formattingContexts/table/TableFormattingContext.h:
     15        * layout/formattingContexts/table/TableFormattingGeometry.cpp:
     16        (WebCore::Layout::TableFormattingGeometry::horizontalSpaceForCellContent const):
     17        (WebCore::Layout::TableFormattingGeometry::verticalSpaceForCellContent const):
     18        * layout/formattingContexts/table/TableFormattingGeometry.h:
     19
    1202021-05-31  Alan Bujtas  <zalan@apple.com>
    221
  • trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.cpp

    r278292 r278294  
    8282    auto& columnList = grid.columns().list();
    8383    auto& rowList = grid.rows().list();
     84    auto& formattingGeometry = this->formattingGeometry();
    8485    // Final table cell layout. At this point all percentage values can be resolved.
    8586    auto sectionOffset = LayoutUnit { };
     
    9495            sectionOffset = rowList[cell->startRow()].logicalTop();
    9596        }
     97        // Internal table elements do not have margins.
     98        cellBoxGeometry.setHorizontalMargin({ });
     99        cellBoxGeometry.setVerticalMargin({ });
     100
     101        cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(*cell));
     102        cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
    96103        cellBoxGeometry.setLogicalTop(rowList[cell->startRow()].logicalTop() - sectionOffset);
    97104        cellBoxGeometry.setLogicalLeft(columnList[cell->startColumn()].logicalLeft());
    98 
    99         auto availableVerticalSpace = rowList[cell->startRow()].logicalHeight();
    100         for (size_t rowIndex = cell->startRow() + 1; rowIndex < cell->endRow(); ++rowIndex)
    101             availableVerticalSpace += rowList[rowIndex].logicalHeight();
    102         availableVerticalSpace += (cell->rowSpan() - 1) * grid.verticalSpacing();
    103         layoutCell(*cell, availableHorizontalSpace);
     105        cellBoxGeometry.setContentBoxWidth(formattingGeometry.horizontalSpaceForCellContent(*cell));
     106
     107        if (cellBox.hasInFlowOrFloatingChild()) {
     108            auto invalidationState = InvalidationState { };
     109            // FIXME: This should probably be part of the invalidation state to indicate when we re-layout the cell multiple times as part of the multi-pass table algorithm.
     110            auto& floatingStateForCellContent = layoutState().ensureBlockFormattingState(cellBox).floatingState();
     111            floatingStateForCellContent.clear();
     112            LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, formattingGeometry.constraintsForInFlowContent(cellBox));
     113        }
     114        cellBoxGeometry.setContentBoxHeight(formattingGeometry.verticalSpaceForCellContent(*cell));
    104115
    105116        auto computeIntrinsicVerticalPaddingForCell = [&] {
     117            auto cellLogicalHeight = rowList[cell->startRow()].logicalHeight();
     118            for (size_t rowIndex = cell->startRow() + 1; rowIndex < cell->endRow(); ++rowIndex)
     119                cellLogicalHeight += rowList[rowIndex].logicalHeight();
     120            cellLogicalHeight += (cell->rowSpan() - 1) * grid.verticalSpacing();
    106121            // Intrinsic padding is the extra padding for the cell box when it is shorter than the row. Cell boxes have to
    107122            // fill the available vertical space
     
    118133            switch (cellBox.style().verticalAlign()) {
    119134            case VerticalAlign::Middle: {
    120                 auto intrinsicVerticalPadding = std::max(0_lu, availableVerticalSpace - cellBoxGeometry.verticalMarginBorderAndPadding() - cellBoxGeometry.contentBoxHeight());
     135                auto intrinsicVerticalPadding = std::max(0_lu, cellLogicalHeight - cellBoxGeometry.verticalMarginBorderAndPadding() - cellBoxGeometry.contentBoxHeight());
    121136                intrinsicPaddingTop = intrinsicVerticalPadding / 2;
    122137                intrinsicPaddingBottom = intrinsicVerticalPadding / 2;
     
    127142                auto cellBaseline = LayoutUnit { cell->baseline() };
    128143                intrinsicPaddingTop = std::max(0_lu, rowBaseline - cellBaseline - cellBoxGeometry.borderTop());
    129                 intrinsicPaddingBottom = std::max(0_lu, availableVerticalSpace - cellBoxGeometry.verticalMarginBorderAndPadding() - intrinsicPaddingTop - cellBoxGeometry.contentBoxHeight());
     144                intrinsicPaddingBottom = std::max(0_lu, cellLogicalHeight - cellBoxGeometry.verticalMarginBorderAndPadding() - intrinsicPaddingTop - cellBoxGeometry.contentBoxHeight());
    130145                break;
    131146            }
     
    279294}
    280295
    281 void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, LayoutUnit availableHorizontalSpace)
    282 {
    283     ASSERT(cell.box().establishesBlockFormattingContext());
    284 
    285     auto& formattingGeometry = this->formattingGeometry();
    286     auto& grid = formattingState().tableGrid();
    287     auto& cellBox = cell.box();
    288     auto& cellBoxGeometry = formattingState().boxGeometry(cellBox);
    289 
    290     cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(cell));
    291     cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
    292     // Internal table elements do not have margins.
    293     cellBoxGeometry.setHorizontalMargin({ });
    294     cellBoxGeometry.setVerticalMargin({ });
    295 
    296     auto availableSpaceForContent = [&] {
    297         auto& columnList = grid.columns().list();
    298         auto logicalWidth = LayoutUnit { };
    299         for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
    300             logicalWidth += columnList.at(columnIndex).logicalWidth();
    301         // No column spacing when spanning.
    302         logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
    303         return logicalWidth - cellBoxGeometry.horizontalMarginBorderAndPadding();
    304     }();
    305     cellBoxGeometry.setContentBoxWidth(availableSpaceForContent);
    306 
    307     if (cellBox.hasInFlowOrFloatingChild()) {
    308         auto constraintsForCellContent = formattingGeometry.constraintsForInFlowContent(cellBox);
    309         auto invalidationState = InvalidationState { };
    310         // FIXME: This should probably be part of the invalidation state to indicate when we re-layout the cell multiple times as part of the multi-pass table algorithm.
    311         auto& floatingStateForCellContent = layoutState().ensureBlockFormattingState(cellBox).floatingState();
    312         floatingStateForCellContent.clear();
    313         LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, constraintsForCellContent);
    314     }
    315     auto contentBoxHeight = formattingGeometry.cellBoxContentHeight(cellBox);
    316     if (auto computedHeight = formattingGeometry.computedHeight(cellBox)) {
    317         auto heightUsesBorderBox = layoutState().inQuirksMode() || cellBox.style().boxSizing() == BoxSizing::BorderBox;
    318         if (heightUsesBorderBox)
    319             *computedHeight -= cellBoxGeometry.verticalMarginBorderAndPadding();
    320         contentBoxHeight = std::max(contentBoxHeight, *computedHeight);
    321     }
    322     cellBoxGeometry.setContentBoxHeight(contentBoxHeight);
    323 }
    324 
    325296IntrinsicWidthConstraints TableFormattingContext::computedIntrinsicWidthConstraints()
    326297{
     
    455426    }
    456427
     428    auto& formattingGeometry = this->formattingGeometry();
    457429    // Rows second.
    458430    auto& rows = grid.rows().list();
     
    462434            if (slot.isRowSpanned())
    463435                continue;
    464             layoutCell(slot.cell(), availableHorizontalSpace);
     436            auto layoutCellContent = [&](auto& cell) {
     437                auto& cellBox = cell.box();
     438                auto& cellBoxGeometry = formattingState().boxGeometry(cellBox);
     439                cellBoxGeometry.setBorder(formattingGeometry.computedCellBorder(cell));
     440                cellBoxGeometry.setPadding(formattingGeometry.computedPadding(cellBox, availableHorizontalSpace));
     441                cellBoxGeometry.setContentBoxWidth(formattingGeometry.horizontalSpaceForCellContent(cell));
     442
     443                if (cellBox.hasInFlowOrFloatingChild()) {
     444                    auto invalidationState = InvalidationState { };
     445                    LayoutContext::createFormattingContext(cellBox, layoutState())->layoutInFlowContent(invalidationState, formattingGeometry.constraintsForInFlowContent(cellBox));
     446                }
     447                cellBoxGeometry.setContentBoxHeight(formattingGeometry.verticalSpaceForCellContent(cell));
     448            };
     449            layoutCellContent(slot.cell());
    465450            if (slot.hasRowSpan())
    466451                continue;
     
    468453            // linebox containing the cells originating in the row.
    469454            auto& cell = slot.cell();
    470             cell.setBaseline(formattingGeometry().usedBaselineForCell(cell.box()));
     455            cell.setBaseline(formattingGeometry.usedBaselineForCell(cell.box()));
    471456        }
    472457    }
  • trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingContext.h

    r278292 r278294  
    7373
    7474    IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
    75     void layoutCell(const TableGrid::Cell&, LayoutUnit availableHorizontalSpace);
    7675    void setUsedGeometryForCells(LayoutUnit availableHorizontalSpace);
    7776    void setUsedGeometryForRows(LayoutUnit availableHorizontalSpace);
  • trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp

    r278253 r278294  
    167167}
    168168
     169LayoutUnit TableFormattingGeometry::horizontalSpaceForCellContent(const TableGrid::Cell& cell) const
     170{
     171    auto& grid = formattingContext().formattingState().tableGrid();
     172    auto& columnList = grid.columns().list();
     173    auto logicalWidth = LayoutUnit { };
     174    for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
     175        logicalWidth += columnList.at(columnIndex).logicalWidth();
     176    // No column spacing when spanning.
     177    logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
     178    auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
     179    logicalWidth -= (cellBoxGeometry.horizontalBorder() + cellBoxGeometry.horizontalPadding().value_or(0));
     180    return logicalWidth;
     181}
     182
     183LayoutUnit TableFormattingGeometry::verticalSpaceForCellContent(const TableGrid::Cell& cell) const
     184{
     185    auto& cellBox = cell.box();
     186    auto contentHeight = cellBoxContentHeight(cellBox);
     187    auto computedHeight = this->computedHeight(cellBox);
     188    if (!computedHeight)
     189        return contentHeight;
     190    auto heightUsesBorderBox = layoutState().inQuirksMode() || cellBox.style().boxSizing() == BoxSizing::BorderBox;
     191    if (heightUsesBorderBox) {
     192        auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
     193        *computedHeight -= (cellBoxGeometry.verticalBorder() + cellBoxGeometry.verticalPadding().value_or(0));
     194    }
     195    return std::max(contentHeight, *computedHeight);
     196}
     197
    169198}
    170199}
  • trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h

    r278253 r278294  
    4545    IntrinsicWidthConstraints intrinsicWidthConstraintsForCell(const TableGrid::Cell&) const;
    4646    InlineLayoutUnit usedBaselineForCell(const ContainerBox& cellBox) const;
     47    LayoutUnit horizontalSpaceForCellContent(const TableGrid::Cell&) const;
     48    LayoutUnit verticalSpaceForCellContent(const TableGrid::Cell&) const;
    4749
    4850private:
Note: See TracChangeset for help on using the changeset viewer.