Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (259977 => 259978)
--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp 2020-04-12 13:27:28 UTC (rev 259977)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp 2020-04-12 15:46:50 UTC (rev 259978)
@@ -64,7 +64,7 @@
void TableFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints&)
{
auto& grid = formattingState().tableGrid();
- auto& columnsContext = grid.columnsContext();
+ auto& columns = grid.columns();
computeAndDistributeExtraHorizontalSpace(horizontalConstraints.logicalWidth);
// 1. Position each column.
@@ -71,7 +71,7 @@
// FIXME: This should also deal with collapsing borders etc.
auto horizontalSpacing = grid.horizontalSpacing();
auto columnLogicalLeft = horizontalSpacing;
- for (auto& column : columnsContext.columns()) {
+ for (auto& column : columns.list()) {
column.setLogicalLeft(columnLogicalLeft);
columnLogicalLeft += (column.logicalWidth() + horizontalSpacing);
}
@@ -80,15 +80,15 @@
auto& cellList = grid.cells();
ASSERT(!cellList.isEmpty());
for (auto& cell : cellList) {
- auto& cellLayoutBox = cell->tableCellBox;
- layoutTableCellBox(*cell, invalidationState, horizontalConstraints);
+ 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().at(cell->startRow());
- row.setLogicalHeight(std::max(row.logicalHeight(), geometryForBox(cellLayoutBox).marginBoxHeight()));
+ 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()) {
+ for (auto& row : grid.rows().list()) {
row.setLogicalTop(rowLogicalTop);
rowLogicalTop += (row.logicalHeight() + grid.verticalSpacing());
}
@@ -99,12 +99,12 @@
setComputedGeometryForRows();
}
-void TableFormattingContext::layoutTableCellBox(const TableGrid::CellInfo& cell, InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints)
+void TableFormattingContext::layoutCell(const TableGrid::Cell& cell, InvalidationState& invalidationState, const HorizontalConstraints& horizontalConstraints)
{
- auto& cellLayoutBox = cell.tableCellBox;
- computeBorderAndPadding(cellLayoutBox, horizontalConstraints);
+ auto& cellBox = cell.box();
+ computeBorderAndPadding(cellBox, horizontalConstraints);
// Margins do not apply to internal table elements.
- auto& cellDisplayBox = formattingState().displayBox(cellLayoutBox);
+ auto& cellDisplayBox = formattingState().displayBox(cellBox);
cellDisplayBox.setHorizontalMargin({ });
cellDisplayBox.setHorizontalComputedMargin({ });
// Don't know the actual position yet.
@@ -111,7 +111,7 @@
cellDisplayBox.setTopLeft({ });
auto contentWidth = [&] {
auto& grid = formattingState().tableGrid();
- auto& columnList = grid.columnsContext().columns();
+ auto& columnList = grid.columns().list();
auto logicalWidth = LayoutUnit { };
for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
logicalWidth += columnList.at(columnIndex).logicalWidth();
@@ -121,9 +121,9 @@
}();
cellDisplayBox.setContentBoxWidth(contentWidth);
- ASSERT(cellLayoutBox.establishesBlockFormattingContext());
- if (is<ContainerBox>(cellLayoutBox) && downcast<ContainerBox>(cellLayoutBox).hasInFlowOrFloatingChild()) {
- auto& formattingContextRoot = downcast<ContainerBox>(cellLayoutBox);
+ ASSERT(cellBox.establishesBlockFormattingContext());
+ if (is<ContainerBox>(cellBox) && downcast<ContainerBox>(cellBox).hasInFlowOrFloatingChild()) {
+ auto& formattingContextRoot = downcast<ContainerBox>(cellBox);
auto formattingContextForCellContent = LayoutContext::createFormattingContext(formattingContextRoot, layoutState());
auto horizontalConstraintsForCellContent = Geometry::horizontalConstraintsForInFlow(cellDisplayBox);
auto verticalConstraintsForCellContent = Geometry::verticalConstraintsForInFlow(cellDisplayBox);
@@ -130,7 +130,7 @@
formattingContextForCellContent->layoutInFlowContent(invalidationState, horizontalConstraintsForCellContent, verticalConstraintsForCellContent);
}
cellDisplayBox.setVerticalMargin({ { }, { } });
- cellDisplayBox.setContentBoxHeight(geometry().tableCellHeightAndMargin(cellLayoutBox).contentHeight);
+ cellDisplayBox.setContentBoxHeight(geometry().tableCellHeightAndMargin(cellBox).contentHeight);
// FIXME: Check what to do with out-of-flow content.
}
@@ -137,10 +137,10 @@
void TableFormattingContext::positionTableCells()
{
auto& grid = formattingState().tableGrid();
- auto& rowList = grid.rows();
- auto& columnList = grid.columnsContext().columns();
+ auto& rowList = grid.rows().list();
+ auto& columnList = grid.columns().list();
for (auto& cell : grid.cells()) {
- auto& cellDisplayBox = formattingState().displayBox(cell->tableCellBox);
+ auto& cellDisplayBox = formattingState().displayBox(cell->box());
cellDisplayBox.setTop(rowList.at(cell->startRow()).logicalTop());
cellDisplayBox.setLeft(columnList.at(cell->startColumn()).logicalLeft());
}
@@ -149,10 +149,9 @@
void TableFormattingContext::setComputedGeometryForRows()
{
auto& grid = formattingState().tableGrid();
- auto rowWidth = grid.columnsContext().logicalWidth() + 2 * grid.horizontalSpacing();
+ auto rowWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
- auto& rowList = grid.rows();
- for (auto& row : rowList) {
+ for (auto& row : grid.rows().list()) {
auto& rowDisplayBox = formattingState().displayBox(row.box());
initializeDisplayBoxToBlank(rowDisplayBox);
rowDisplayBox.setContentBoxHeight(row.logicalHeight());
@@ -164,7 +163,7 @@
void TableFormattingContext::setComputedGeometryForSections()
{
auto& grid = formattingState().tableGrid();
- auto sectionWidth = grid.columnsContext().logicalWidth() + 2 * grid.horizontalSpacing();
+ auto sectionWidth = grid.columns().logicalWidth() + 2 * grid.horizontalSpacing();
for (auto& section : childrenOfType<Box>(root())) {
auto& sectionDisplayBox = formattingState().displayBox(section);
@@ -171,7 +170,7 @@
initializeDisplayBoxToBlank(sectionDisplayBox);
// FIXME: Size table sections properly.
sectionDisplayBox.setContentBoxWidth(sectionWidth);
- sectionDisplayBox.setContentBoxHeight(grid.rows().last().logicalBottom() + grid.verticalSpacing());
+ sectionDisplayBox.setContentBoxHeight(grid.rows().list().last().logicalBottom() + grid.verticalSpacing());
}
}
@@ -211,13 +210,13 @@
colgroup = colgroupCandidate;
if (colgroup) {
- auto& columnsContext = tableGrid.columnsContext();
+ auto& columns = tableGrid.columns();
for (auto* column = downcast<ContainerBox>(*colgroup).firstChild(); column; column = column->nextSibling()) {
ASSERT(column->isTableColumn());
auto columnSpanCount = column->columnSpan();
ASSERT(columnSpanCount > 0);
while (columnSpanCount--)
- columnsContext.addColumn(column);
+ columns.addColumn(*column);
}
}
@@ -244,25 +243,25 @@
// If the specified 'width' (W) of the cell is greater than MCW, W is the minimum cell width. A value of 'auto' means that MCW is the minimum cell width.
// Also, calculate the "maximum" cell width of each cell: formatting the content without breaking lines other than where explicit line breaks occur.
for (auto& cell : grid.cells()) {
- auto& tableCellBox = cell->tableCellBox;
- ASSERT(tableCellBox.establishesFormattingContext());
+ auto& cellBox = cell->box();
+ ASSERT(cellBox.establishesFormattingContext());
- auto intrinsicWidth = formattingState.intrinsicWidthConstraintsForBox(tableCellBox);
+ auto intrinsicWidth = formattingState.intrinsicWidthConstraintsForBox(cellBox);
if (!intrinsicWidth) {
intrinsicWidth = IntrinsicWidthConstraints { };
- if (is<ContainerBox>(tableCellBox) && downcast<ContainerBox>(tableCellBox).hasInFlowOrFloatingChild())
- intrinsicWidth = LayoutContext::createFormattingContext(downcast<ContainerBox>(tableCellBox), layoutState())->computedIntrinsicWidthConstraints();
- intrinsicWidth = geometry().constrainByMinMaxWidth(tableCellBox, *intrinsicWidth);
- auto border = geometry().computedBorder(tableCellBox);
- auto padding = *geometry().computedPadding(tableCellBox, { });
+ if (is<ContainerBox>(cellBox) && downcast<ContainerBox>(cellBox).hasInFlowOrFloatingChild())
+ intrinsicWidth = LayoutContext::createFormattingContext(downcast<ContainerBox>(cellBox), layoutState())->computedIntrinsicWidthConstraints();
+ intrinsicWidth = geometry().constrainByMinMaxWidth(cellBox, *intrinsicWidth);
+ auto border = geometry().computedBorder(cellBox);
+ auto padding = *geometry().computedPadding(cellBox, { });
intrinsicWidth->expand(border.horizontal.width() + padding.horizontal.width());
- formattingState.setIntrinsicWidthConstraintsForBox(tableCellBox, *intrinsicWidth);
+ formattingState.setIntrinsicWidthConstraintsForBox(cellBox, *intrinsicWidth);
}
- auto columnSpan = cell->size.width();
+ auto columnSpan = cell->size().width();
auto slotIntrinsicWidth = FormattingContext::IntrinsicWidthConstraints { intrinsicWidth->minimum / columnSpan, intrinsicWidth->maximum / columnSpan };
- auto initialPosition = cell->position;
+ auto initialPosition = cell->position();
for (auto i = 0; i < columnSpan; ++i)
grid.slot({ initialPosition.x() + i, initialPosition.y() })->widthConstraints = slotIntrinsicWidth;
}
@@ -269,9 +268,9 @@
// 2. For each column, determine a maximum and minimum column width from the cells that span only that column.
// The minimum is that required by the cell with the largest minimum cell width (or the column 'width', whichever is larger).
// The maximum is that required by the cell with the largest maximum cell width (or the column 'width', whichever is larger).
- auto& columns = grid.columnsContext().columns();
+ auto& columnList = grid.columns().list();
int numberOfRows = grid.rows().size();
- int numberOfColumns = columns.size();
+ int numberOfColumns = columnList.size();
for (int columnIndex = 0; columnIndex < numberOfColumns; ++columnIndex) {
auto columnIntrinsicWidths = FormattingContext::IntrinsicWidthConstraints { };
for (int rowIndex = 0; rowIndex < numberOfRows; ++rowIndex) {
@@ -280,13 +279,13 @@
columnIntrinsicWidths.maximum = std::max(slot->widthConstraints.maximum, columnIntrinsicWidths.maximum);
}
// Now that we have the content driven min/max widths, check if <col> sets a preferred width on this column.
- if (auto* columnBox = columns[columnIndex].columnBox()) {
+ if (auto* columnBox = columnList[columnIndex].box()) {
if (auto columnPreferredWidth = geometry().computedColumnWidth(*columnBox)) {
// Let's stay at least as wide as the preferred width.
columnIntrinsicWidths.minimum = std::max(columnIntrinsicWidths.minimum, *columnPreferredWidth);
}
}
- columns[columnIndex].setWidthConstraints(columnIntrinsicWidths);
+ columnList[columnIndex].setWidthConstraints(columnIntrinsicWidths);
}
}
@@ -304,17 +303,17 @@
// CAPMIN, and MIN. However, if either CAPMIN or the maximum width required by the columns plus cell spacing or borders (MAX) is
// less than that of the containing block, use max(MAX, CAPMIN).
auto distributeExtraHorizontalSpace = [&](auto extraHorizontalSpace) {
- auto& columns = grid.columnsContext().columns();
- ASSERT(!columns.isEmpty());
+ auto& columnList = grid.columns().list();
+ ASSERT(!columnList.isEmpty());
auto tableMinimumContentWidth = tableWidthConstraints.minimum - grid.totalHorizontalSpacing();
auto adjustabledHorizontalSpace = tableMinimumContentWidth;
- auto numberOfColumns = columns.size();
+ auto numberOfColumns = columnList.size();
// Fixed width columns don't participate in available space distribution.
- for (auto& column : columns) {
+ for (auto& column : columnList) {
if (!column.hasFixedWidth())
continue;
- auto columnFixedWidth = *column.columnBox()->columnWidth();
+ auto columnFixedWidth = *column.box()->columnWidth();
column.setLogicalWidth(columnFixedWidth);
--numberOfColumns;
@@ -324,7 +323,7 @@
return;
// FIXME: Right now just distribute the extra space equaly among the columns using the minimum width.
ASSERT(adjustabledHorizontalSpace > 0);
- for (auto& column : columns) {
+ for (auto& column : columnList) {
if (column.hasFixedWidth())
continue;
auto columnExtraSpace = extraHorizontalSpace / adjustabledHorizontalSpace * column.widthConstraints().minimum;
@@ -349,10 +348,10 @@
void TableFormattingContext::useAsContentLogicalWidth(WidthConstraintsType type)
{
- auto& columns = formattingState().tableGrid().columnsContext().columns();
- ASSERT(!columns.isEmpty());
+ auto& columnList = formattingState().tableGrid().columns().list();
+ ASSERT(!columnList.isEmpty());
- for (auto& column : columns)
+ for (auto& column : columnList)
column.setLogicalWidth(type == WidthConstraintsType::Minimum ? column.widthConstraints().minimum : column.widthConstraints().maximum);
}
Modified: trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp (259977 => 259978)
--- trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp 2020-04-12 13:27:28 UTC (rev 259977)
+++ trunk/Source/WebCore/layout/tableformatting/TableGrid.cpp 2020-04-12 15:46:50 UTC (rev 259978)
@@ -36,7 +36,7 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(TableGrid);
TableGrid::Column::Column(const Box* columnBox)
- : m_columnBox(makeWeakPtr(columnBox))
+ : m_layoutBox(makeWeakPtr(columnBox))
{
}
@@ -85,27 +85,37 @@
bool TableGrid::Column::hasFixedWidth() const
{
// FIXME: This only covers the <col> attribute case.
- return columnBox() && columnBox()->columnWidth();
+ return box() && box()->columnWidth();
}
-void TableGrid::ColumnsContext::addColumn(const Box* columnBox)
+void TableGrid::Columns::addColumn(const Box& columnBox)
{
- m_columns.append({ columnBox });
+ m_columnList.append({ &columnBox });
}
+void TableGrid::Columns::addAnonymousColumn()
+{
+ m_columnList.append({ nullptr });
+}
+
+void TableGrid::Rows::addRow(const Box& rowBox)
+{
+ m_rowList.append({ rowBox });
+}
+
TableGrid::Row::Row(const Box& rowBox)
- : m_layoutBox(rowBox)
+ : m_layoutBox(makeWeakPtr(rowBox))
{
}
-TableGrid::CellInfo::CellInfo(const Box& tableCellBox, SlotPosition position, CellSize size)
- : tableCellBox(tableCellBox)
- , position(position)
- , size(size)
+TableGrid::Cell::Cell(const Box& cellBox, SlotPosition position, CellSize size)
+ : m_layoutBox(makeWeakPtr(cellBox))
+ , m_position(position)
+ , m_size(size)
{
}
-TableGrid::SlotInfo::SlotInfo(CellInfo& cell)
+TableGrid::Slot::Slot(Cell& cell)
: cell(makeWeakPtr(cell))
{
}
@@ -114,21 +124,21 @@
{
}
-TableGrid::SlotInfo* TableGrid::slot(SlotPosition position)
+TableGrid::Slot* TableGrid::slot(SlotPosition position)
{
return m_slotMap.get(position);
}
-void TableGrid::appendCell(const Box& tableCellBox)
+void TableGrid::appendCell(const Box& cellBox)
{
- int rowSpan = tableCellBox.rowSpan();
- int columnSpan = tableCellBox.columnSpan();
- auto isInNewRow = !tableCellBox.previousSibling();
+ int rowSpan = cellBox.rowSpan();
+ int columnSpan = cellBox.columnSpan();
+ auto isInNewRow = !cellBox.previousSibling();
auto initialSlotPosition = SlotPosition { };
- if (!m_cellList.isEmpty()) {
- auto& lastCell = m_cellList.last();
- auto lastSlotPosition = lastCell->position;
+ if (!m_cells.isEmpty()) {
+ auto& lastCell = m_cells.last();
+ auto lastSlotPosition = lastCell->position();
// First table cell in this row?
if (isInNewRow)
initialSlotPosition = SlotPosition { 0, lastSlotPosition.y() + 1 };
@@ -142,35 +152,35 @@
initialSlotPosition.move(1, 0);
}
}
- auto cellInfo = makeUnique<CellInfo>(tableCellBox, initialSlotPosition, CellSize { columnSpan, rowSpan });
+ auto cell = makeUnique<Cell>(cellBox, initialSlotPosition, CellSize { columnSpan, rowSpan });
// Row and column spanners create additional slots.
for (int row = 1; row <= rowSpan; ++row) {
for (int column = 1; column <= columnSpan; ++column) {
auto position = SlotPosition { initialSlotPosition.x() + column - 1, initialSlotPosition.y() + row - 1 };
ASSERT(!m_slotMap.contains(position));
- m_slotMap.add(position, makeUnique<SlotInfo>(*cellInfo));
+ m_slotMap.add(position, makeUnique<Slot>(*cell));
}
}
// Initialize columns/rows if needed.
- auto missingNumberOfColumns = std::max<int>(0, initialSlotPosition.x() + columnSpan - m_columnsContext.columns().size());
+ auto missingNumberOfColumns = std::max<int>(0, initialSlotPosition.x() + columnSpan - m_columns.size());
for (auto column = 0; column < missingNumberOfColumns; ++column)
- m_columnsContext.addColumn();
+ m_columns.addAnonymousColumn();
if (isInNewRow)
- m_rows.append({ tableCellBox.parent() });
+ m_rows.addRow(cellBox.parent());
- m_cellList.add(WTFMove(cellInfo));
+ m_cells.add(WTFMove(cell));
}
-void TableGrid::insertCell(const Box& tableCellBox, const Box& before)
+void TableGrid::insertCell(const Box& cellBox, const Box& before)
{
- UNUSED_PARAM(tableCellBox);
+ UNUSED_PARAM(cellBox);
UNUSED_PARAM(before);
}
-void TableGrid::removeCell(const Box& tableCellBox)
+void TableGrid::removeCell(const Box& cellBox)
{
- UNUSED_PARAM(tableCellBox);
+ UNUSED_PARAM(cellBox);
}
FormattingContext::IntrinsicWidthConstraints TableGrid::widthConstraints()
@@ -180,7 +190,7 @@
return *m_intrinsicWidthConstraints;
m_intrinsicWidthConstraints = FormattingContext::IntrinsicWidthConstraints { };
- for (auto& column : m_columnsContext.columns())
+ for (auto& column : m_columns.list())
*m_intrinsicWidthConstraints += column.widthConstraints();
m_intrinsicWidthConstraints->expand(totalHorizontalSpacing());
return *m_intrinsicWidthConstraints;
Modified: trunk/Source/WebCore/layout/tableformatting/TableGrid.h (259977 => 259978)
--- trunk/Source/WebCore/layout/tableformatting/TableGrid.h 2020-04-12 13:27:28 UTC (rev 259977)
+++ trunk/Source/WebCore/layout/tableformatting/TableGrid.h 2020-04-12 15:46:50 UTC (rev 259978)
@@ -31,6 +31,7 @@
#include "IntPointHash.h"
#include <wtf/HashMap.h>
#include <wtf/IsoMalloc.h>
+#include <wtf/IsoMallocInlines.h>
#include <wtf/ListHashSet.h>
#include <wtf/WeakPtr.h>
@@ -49,39 +50,19 @@
void setHorizontalSpacing(LayoutUnit horizontalSpacing) { m_horizontalSpacing = horizontalSpacing; }
LayoutUnit horizontalSpacing() const { return m_horizontalSpacing; }
- LayoutUnit totalHorizontalSpacing() const { return (columnsContext().columns().size() + 1) * horizontalSpacing(); }
+ LayoutUnit totalHorizontalSpacing() const { return (columns().size() + 1) * horizontalSpacing(); }
void setVerticalSpacing(LayoutUnit verticalSpacing) { m_verticalSpacing = verticalSpacing; }
LayoutUnit verticalSpacing() const { return m_verticalSpacing; }
- using SlotPosition = IntPoint;
+ bool hasComputedWidthConstraints() const { return m_intrinsicWidthConstraints.hasValue(); }
+ FormattingContext::IntrinsicWidthConstraints widthConstraints();
- // Cell represents a <td> or <th>. It can span multiple slots in the grid.
- using CellSize = IntSize;
- struct CellInfo : public CanMakeWeakPtr<CellInfo> {
- WTF_MAKE_STRUCT_FAST_ALLOCATED;
- CellInfo(const Box& tableCellBox, SlotPosition, CellSize);
-
- size_t startColumn() const { return position.x(); }
- size_t endColumn() const { return position.x() + size.width(); }
-
- size_t startRow() const { return position.y(); }
- size_t endRow() const { return position.y() + size.height(); }
-
- size_t columnSpan() const { return size.width(); }
- size_t rowSpan() const { return size.height(); }
-
- const Box& tableCellBox;
- SlotPosition position;
- CellSize size;
- };
- using CellList = WTF::ListHashSet<std::unique_ptr<CellInfo>>;
- CellList& cells() { return m_cellList; }
-
// Column represents a vertical set of slots in the grid. A column has min/max and final width.
- class ColumnsContext;
class Column {
public:
+ Column(const Box*);
+
void setWidthConstraints(FormattingContext::IntrinsicWidthConstraints);
FormattingContext::IntrinsicWidthConstraints widthConstraints() const;
@@ -93,16 +74,13 @@
bool hasFixedWidth() const;
- const Box* columnBox() const { return m_columnBox.get(); }
+ const Box* box() const { return m_layoutBox.get(); }
private:
- friend class ColumnsContext;
- Column(const Box* columnBox);
-
FormattingContext::IntrinsicWidthConstraints m_widthConstraints;
LayoutUnit m_computedLogicalWidth;
LayoutUnit m_computedLogicalLeft;
- WeakPtr<const Box> m_columnBox;
+ WeakPtr<const Box> m_layoutBox;
#if ASSERT_ENABLED
bool m_hasWidthConstraints { false };
@@ -111,65 +89,111 @@
#endif
};
- class ColumnsContext {
+ class Columns {
public:
using ColumnList = Vector<Column>;
- ColumnList& columns() { return m_columns; }
- const ColumnList& columns() const { return m_columns; }
- void addColumn(const Box* columnBox = nullptr);
+ ColumnList& list() { return m_columnList; }
+ const ColumnList& list() const { return m_columnList; }
+ size_t size() const { return m_columnList.size(); }
- LayoutUnit logicalWidth() const { return columns().last().logicalRight() - columns().first().logicalLeft(); }
+ void addColumn(const Box&);
+ void addAnonymousColumn();
+ LayoutUnit logicalWidth() const { return m_columnList.last().logicalRight() - m_columnList.first().logicalLeft(); }
+
private:
- friend class TableGrid;
-
- ColumnList m_columns;
+ ColumnList m_columnList;
};
- const ColumnsContext& columnsContext() const { return m_columnsContext; }
- ColumnsContext& columnsContext() { return m_columnsContext; }
- struct Row {
+ class Row {
public:
Row(const Box&);
- const Box& box() const { return m_layoutBox; }
-
void setLogicalTop(LayoutUnit logicalTop) { m_logicalTop = logicalTop; }
LayoutUnit logicalTop() const { return m_logicalTop; }
+ LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
void setLogicalHeight(LayoutUnit logicalHeight) { m_logicalHeight = logicalHeight; }
LayoutUnit logicalHeight() const { return m_logicalHeight; }
- LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
+ const Box& box() const { return *m_layoutBox.get(); }
private:
LayoutUnit m_logicalTop;
LayoutUnit m_logicalHeight;
- const Box& m_layoutBox;
+ WeakPtr<const Box> m_layoutBox;
};
- using RowList = WTF::Vector<Row>;
- RowList& rows() { return m_rows; }
- struct SlotInfo {
+ class Rows {
+ public:
+ using RowList = Vector<Row>;
+ RowList& list() { return m_rowList; }
+ const RowList& rowList() const { return m_rowList; }
+
+ void addRow(const Box&);
+
+ size_t size() const { return m_rowList.size(); }
+
+ private:
+ RowList m_rowList;
+ };
+
+ using SlotPosition = IntPoint;
+ using CellSize = IntSize;
+ // Cell represents a <td> or <th>. It can span multiple slots in the grid.
+ class Cell : public CanMakeWeakPtr<Cell> {
+ WTF_MAKE_ISO_ALLOCATED_INLINE(Cell);
+ public:
+ Cell(const Box&, SlotPosition, CellSize);
+
+ size_t startColumn() const { return m_position.x(); }
+ size_t endColumn() const { return m_position.x() + m_size.width(); }
+
+ size_t startRow() const { return m_position.y(); }
+ size_t endRow() const { return m_position.y() + m_size.height(); }
+
+ size_t columnSpan() const { return m_size.width(); }
+ size_t rowSpan() const { return m_size.height(); }
+
+ SlotPosition position() const { return m_position; }
+ CellSize size() const { return m_size; }
+
+ const Box& box() const { return *m_layoutBox.get(); }
+
+ private:
+ WeakPtr<const Box> m_layoutBox;
+ SlotPosition m_position;
+ CellSize m_size;
+ };
+
+ struct Slot {
WTF_MAKE_STRUCT_FAST_ALLOCATED;
- SlotInfo() = default;
- SlotInfo(CellInfo&);
+ Slot() = default;
+ Slot(Cell&);
- WeakPtr<CellInfo> cell;
+ WeakPtr<Cell> cell;
FormattingContext::IntrinsicWidthConstraints widthConstraints;
};
- SlotInfo* slot(SlotPosition);
- bool hasComputedWidthConstraints() const { return m_intrinsicWidthConstraints.hasValue(); }
- FormattingContext::IntrinsicWidthConstraints widthConstraints();
+ const Columns& columns() const { return m_columns; }
+ Columns& columns() { return m_columns; }
+ const Rows& rows() const { return m_rows; }
+ Rows& rows() { return m_rows; }
+
+ using Cells = WTF::ListHashSet<std::unique_ptr<Cell>>;
+ Cells& cells() { return m_cells; }
+
+ Slot* slot(SlotPosition);
+
private:
- using SlotMap = WTF::HashMap<SlotPosition, std::unique_ptr<SlotInfo>>;
+ using SlotMap = WTF::HashMap<SlotPosition, std::unique_ptr<Slot>>;
+ Columns m_columns;
+ Rows m_rows;
+ Cells m_cells;
SlotMap m_slotMap;
- CellList m_cellList;
- ColumnsContext m_columnsContext;
- RowList m_rows;
+
LayoutUnit m_horizontalSpacing;
LayoutUnit m_verticalSpacing;
Optional<FormattingContext::IntrinsicWidthConstraints> m_intrinsicWidthConstraints;