Changeset 260510 in webkit


Ignore:
Timestamp:
Apr 22, 2020 7:42:38 AM (4 years ago)
Author:
Alan Bujtas
Message:

[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:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r260508 r260510  
     12020-04-22  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][TFC] Introduce TableFormattingContext::computeAndDistributeExtraVerticalSpace
     4        https://bugs.webkit.org/show_bug.cgi?id=210830
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add a dedicated function to compute preferred heights for the table rows.
     9        This is in preparation for the 2 pass layout required to finalize row height.
     10
     11        * layout/FormattingContext.cpp:
     12        (WebCore::Layout::FormattingContext::computeBorderAndPadding):
     13        * layout/FormattingContext.h:
     14        * layout/FormattingContextGeometry.cpp:
     15        (WebCore::Layout::FormattingContext::Geometry::computedPadding const):
     16        * layout/tableformatting/TableFormattingContext.cpp:
     17        (WebCore::Layout::TableFormattingContext::layoutInFlowContent):
     18        (WebCore::Layout::TableFormattingContext::layoutCell):
     19        (WebCore::Layout::TableFormattingContext::computeAndDistributeExtraVerticalSpace):
     20        (WebCore::Layout::TableFormattingContext::setComputedGeometryForRows):
     21        (WebCore::Layout::TableFormattingContext::setComputedGeometryForSections):
     22        (WebCore::Layout::TableFormattingContext::positionTableCells): Deleted.
     23        * layout/tableformatting/TableFormattingContext.h:
     24
    1252020-04-22  Claudio Saavedra  <csaavedra@igalia.com>
    226
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r258904 r260510  
    131131    auto& displayBox = formattingState().displayBox(layoutBox);
    132132    displayBox.setBorder(geometry().computedBorder(layoutBox));
    133     displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint));
     133    displayBox.setPadding(geometry().computedPadding(layoutBox, horizontalConstraint.logicalWidth));
    134134}
    135135
  • trunk/Source/WebCore/layout/FormattingContext.h

    r260337 r260510  
    129129
    130130        Edges computedBorder(const Box&) const;
    131         Optional<Edges> computedPadding(const Box&, const HorizontalConstraints&) const;
     131        Optional<Edges> computedPadding(const Box&, LayoutUnit containingBlockWidth) const;
    132132
    133133        ComputedHorizontalMargin computedHorizontalMargin(const Box&, const HorizontalConstraints&) const;
  • trunk/Source/WebCore/layout/FormattingContextGeometry.cpp

    r259180 r260510  
    10501050}
    10511051
    1052 Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
     1052Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const LayoutUnit containingBlockWidth) const
    10531053{
    10541054    if (!layoutBox.isPaddingApplicable())
     
    10561056
    10571057    auto& style = layoutBox.style();
    1058     auto containingBlockWidth = horizontalConstraints.logicalWidth;
    10591058    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
    10601059    return Edges {
  • trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp

    r260368 r260510  
    6262}
    6363
    64 void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints&)
    65 {
    66     auto& grid = formattingState().tableGrid();
    67     auto& columns = grid.columns();
    68 
     64void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
     65{
     66    auto& grid = formattingState().tableGrid();
     67    auto& columnList = grid.columns().list();
     68    auto& rowList = grid.rows().list();
     69    // 1. Compute width and height for the grid.
    6970    computeAndDistributeExtraHorizontalSpace(horizontalConstraints.logicalWidth);
    70     // 1. Position each column.
    71     // FIXME: This should also deal with collapsing borders etc.
     71    computeAndDistributeExtraVerticalSpace(horizontalConstraints.logicalWidth, verticalConstraints.logicalHeight);
     72    // 2. Position columns.
    7273    auto horizontalSpacing = grid.horizontalSpacing();
    7374    auto columnLogicalLeft = horizontalSpacing;
    74     for (auto& column : columns.list()) {
     75    for (auto& column : columnList) {
    7576        column.setLogicalLeft(columnLogicalLeft);
    76         columnLogicalLeft += (column.logicalWidth() + horizontalSpacing);
    77     }
    78 
    79     // 2. Layout each table cell (and compute row height as well).
     77        columnLogicalLeft += column.logicalWidth() + horizontalSpacing;
     78    }
     79    // 3. Position rows.
     80    auto verticalSpacing = grid.verticalSpacing();
     81    auto rowLogicalTop = verticalSpacing;
     82    for (auto& row : rowList) {
     83        row.setLogicalTop(rowLogicalTop);
     84        rowLogicalTop += row.logicalHeight() + verticalSpacing;
     85    }
     86    // 4. Position cells.
     87    for (auto& cell : grid.cells()) {
     88        auto& cellDisplayBox = formattingState().displayBox(cell->box());
     89        cellDisplayBox.setTop(rowList[cell->startRow()].logicalTop());
     90        cellDisplayBox.setLeft(columnList[cell->startColumn()].logicalLeft());
     91    }
     92    // 5. Final table cell layout. At this point all percentage values can be resolved.
    8093    auto& cellList = grid.cells();
    8194    ASSERT(!cellList.isEmpty());
    82     for (auto& cell : cellList) {
    83         auto& cellBox = cell->box();
    84         layoutCell(*cell, invalidationState, horizontalConstraints);
    85         // FIXME: Add support for column and row spanning and this requires a 2 pass layout.
    86         auto& row = grid.rows().list().at(cell->startRow());
    87         row.setLogicalHeight(std::max(row.logicalHeight(), geometryForBox(cellBox).marginBoxHeight()));
    88     }
    89     // This is after the second pass when cell heights are fully computed.
    90     auto rowLogicalTop = grid.verticalSpacing();
    91     for (auto& row : grid.rows().list()) {
    92         row.setLogicalTop(rowLogicalTop);
    93         rowLogicalTop += (row.logicalHeight() + grid.verticalSpacing());
    94     }
    95 
     95    for (auto& cell : cellList)
     96        layoutCell(*cell, invalidationState, horizontalConstraints.logicalWidth);
    9697    // 3. Finalize size and position.
    97     positionTableCells();
    9898    setComputedGeometryForSections();
    9999    setComputedGeometryForRows();
    100100}
    101101
    102 void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints)
     102void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, LayoutUnit availableHorizontalSpace)
    103103{
    104104    auto& cellBox = cell.box();
    105     computeBorderAndPadding(cellBox, horizontalConstraints);
     105    computeBorderAndPadding(cellBox, HorizontalConstraints { { }, availableHorizontalSpace });
    106106    // Margins do not apply to internal table elements.
    107107    auto& cellDisplayBox = formattingState().displayBox(cellBox);
    108108    cellDisplayBox.setHorizontalMargin({ });
    109109    cellDisplayBox.setHorizontalComputedMargin({ });
    110     // Don't know the actual position yet.
    111     cellDisplayBox.setTopLeft({ });
    112     auto contentWidth = [&] {
     110    auto availableSpaceForContent = [&] {
    113111        auto& grid = formattingState().tableGrid();
    114112        auto& columnList = grid.columns().list();
     
    120118        return logicalWidth - cellDisplayBox.horizontalMarginBorderAndPadding();
    121119    }();
    122     cellDisplayBox.setContentBoxWidth(contentWidth);
     120    cellDisplayBox.setContentBoxWidth(availableSpaceForContent);
    123121
    124122    ASSERT(cellBox.establishesBlockFormattingContext());
     
    132130    cellDisplayBox.setContentBoxHeight(geometry().tableCellHeightAndMargin(cellBox).contentHeight);
    133131    // FIXME: Check what to do with out-of-flow content.
    134 }
    135 
    136 void TableFormattingContext::positionTableCells()
    137 {
    138     auto& grid = formattingState().tableGrid();
    139     auto& rowList = grid.rows().list();
    140     auto& columnList = grid.columns().list();
    141     for (auto& cell : grid.cells()) {
    142         auto& cellDisplayBox = formattingState().displayBox(cell->box());
    143         cellDisplayBox.setTop(rowList.at(cell->startRow()).logicalTop());
    144         cellDisplayBox.setLeft(columnList.at(cell->startColumn()).logicalLeft());
    145     }
    146 }
    147 
    148 void TableFormattingContext::setComputedGeometryForRows()
    149 {
    150     auto& grid = formattingState().tableGrid();
    151     auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
    152 
    153     for (auto& row : grid.rows().list()) {
    154         auto& rowDisplayBox = formattingState().displayBox(row.box());
    155         initializeDisplayBoxToBlank(rowDisplayBox);
    156         rowDisplayBox.setContentBoxHeight(row.logicalHeight());
    157         rowDisplayBox.setContentBoxWidth(rowWidth);
    158         rowDisplayBox.setTop(row.logicalTop());
    159     }
    160 }
    161 
    162 void TableFormattingContext::setComputedGeometryForSections()
    163 {
    164     auto& grid = formattingState().tableGrid();
    165     auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
    166 
    167     for (auto& section : childrenOfType<Box>(root())) {
    168         auto& sectionDisplayBox = formattingState().displayBox(section);
    169         initializeDisplayBoxToBlank(sectionDisplayBox);
    170         // FIXME: Size table sections properly.
    171         sectionDisplayBox.setContentBoxWidth(sectionWidth);
    172         sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
    173     }
    174132}
    175133
     
    480438}
    481439
     440void TableFormattingContext::computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit>)
     441{
     442    auto& grid = formattingState().tableGrid();
     443    auto& columns = grid.columns().list();
     444    auto& rows = grid.rows();
     445
     446    Vector<float> rownHeights;
     447    // 1. Collect initial row heights.
     448    for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex) {
     449        float maximumColumnHeight = 0;
     450        for (size_t columnIndex = 0; columnIndex < columns.size(); ++columnIndex) {
     451            auto& slot = *grid.slot({ columnIndex, rowIndex });
     452            if (slot.isColumnSpanned())
     453                continue;
     454            auto invalidationState = InvalidationState { };
     455            layoutCell(slot.cell(), invalidationState, availableHorizontalSpace);
     456            maximumColumnHeight = std::max<float>(maximumColumnHeight, geometryForBox(slot.cell().box()).height());
     457        }
     458        // <tr style="height: 10px"> is considered as min height.
     459        auto computedRowHeight = geometry().computedContentHeight(rows.list()[rowIndex].box(), { }).valueOr(LayoutUnit { });
     460        // FIXME: add support for baseline syncing.
     461        rownHeights.append(std::max(maximumColumnHeight, computedRowHeight.toFloat()));
     462    }
     463
     464    for (size_t rowIndex = 0; rowIndex < rows.size(); ++rowIndex)
     465        grid.rows().list()[rowIndex].setLogicalHeight(LayoutUnit { rownHeights[rowIndex] });
     466}
     467
     468void TableFormattingContext::setComputedGeometryForRows()
     469{
     470    auto& grid = formattingState().tableGrid();
     471    auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
     472
     473    for (auto& row : grid.rows().list()) {
     474        auto& rowDisplayBox = formattingState().displayBox(row.box());
     475        initializeDisplayBoxToBlank(rowDisplayBox);
     476        rowDisplayBox.setContentBoxHeight(row.logicalHeight());
     477        rowDisplayBox.setContentBoxWidth(rowWidth);
     478        rowDisplayBox.setTop(row.logicalTop());
     479    }
     480}
     481
     482void TableFormattingContext::setComputedGeometryForSections()
     483{
     484    auto& grid = formattingState().tableGrid();
     485    auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
     486
     487    for (auto& section : childrenOfType<Box>(root())) {
     488        auto& sectionDisplayBox = formattingState().displayBox(section);
     489        initializeDisplayBoxToBlank(sectionDisplayBox);
     490        // FIXME: Size table sections properly.
     491        sectionDisplayBox.setContentBoxWidth(sectionWidth);
     492        sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
     493    }
     494}
     495
    482496}
    483497}
  • trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h

    r260342 r260510  
    6161
    6262    IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
    63     void layoutCell(const TableGrid::Cell&, InvalidationState&, const HorizontalConstraints&);
     63    void layoutCell(const TableGrid::Cell&, InvalidationState&, LayoutUnit availableHorizontalSpace);
    6464    void positionTableCells();
    6565    void setComputedGeometryForRows();
     
    6969    IntrinsicWidthConstraints computedPreferredWidthForColumns();
    7070    void computeAndDistributeExtraHorizontalSpace(LayoutUnit availableHorizontalSpace);
     71    void computeAndDistributeExtraVerticalSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> availableVerticalSpace);
    7172
    7273    void initializeDisplayBoxToBlank(Display::Box&) const;
Note: See TracChangeset for help on using the changeset viewer.