Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / layout / LayoutTableSection.h
blobf6d5a9345db2d84b2af8ea08e63c5f86f905db51
1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 #ifndef LayoutTableSection_h
26 #define LayoutTableSection_h
28 #include "core/CoreExport.h"
29 #include "core/layout/LayoutTable.h"
30 #include "wtf/Vector.h"
32 namespace blink {
34 // This variable is used to balance the memory consumption vs the paint invalidation time on big tables.
35 const float gMaxAllowedOverflowingCellRatioForFastPaintPath = 0.1f;
37 enum CollapsedBorderSide {
38 CBSBefore,
39 CBSAfter,
40 CBSStart,
41 CBSEnd
44 // Helper class for paintObject.
45 class CellSpan {
46 STACK_ALLOCATED();
47 public:
48 CellSpan(unsigned start, unsigned end)
49 : m_start(start)
50 , m_end(end)
54 unsigned start() const { return m_start; }
55 unsigned end() const { return m_end; }
57 void decreaseStart() { --m_start; }
58 void increaseEnd() { ++m_end; }
60 void ensureConsistency(const unsigned);
62 private:
63 unsigned m_start;
64 unsigned m_end;
67 class LayoutTableCell;
68 class LayoutTableRow;
70 // LayoutTableSection is used to represent table row group (display:
71 // table-row-group), header group (display: table-header-group) and footer group
72 // (display: table-footer-group).
74 // The object holds the internal representation of the rows (m_grid). See
75 // recalcCells() below for some extra explanation.
77 // A lot of the complexity in this class is related to handling rowspan, colspan
78 // or just non-regular tables.
80 // Example of rowspan / colspan leading to overlapping cells (rowspan and
81 // colspan are overlapping):
82 // <table>
83 // <tr>
84 // <td>first row</td>
85 // <td rowspan="2">rowspan</td>
86 // </tr>
87 // <tr>
88 // <td colspan="2">colspan</td>
89 // </tr>
90 // </table>
92 // Example of non-regular table (missing one cell in the first row):
93 // <!DOCTYPE html>
94 // <table>
95 // <tr><td>First row only child.</td></tr>
96 // <tr>
97 // <td>Second row first child</td>
98 // <td>Second row second child</td>
99 // </tr>
100 // </table>
102 // LayoutTableSection is responsible for laying out LayoutTableRows and
103 // LayoutTableCells (see layoutRows()). However it is not their containing
104 // block, the enclosing LayoutTable (this object's parent()) is. This is why
105 // this class inherits from LayoutBox and not LayoutBlock.
106 class CORE_EXPORT LayoutTableSection final : public LayoutBox {
107 public:
108 LayoutTableSection(Element*);
109 ~LayoutTableSection() override;
111 LayoutTableRow* firstRow() const;
112 LayoutTableRow* lastRow() const;
114 const LayoutObjectChildList* children() const { return &m_children; }
115 LayoutObjectChildList* children() { return &m_children; }
117 void addChild(LayoutObject* child, LayoutObject* beforeChild = nullptr) override;
119 int firstLineBoxBaseline() const override;
121 void addCell(LayoutTableCell*, LayoutTableRow*);
123 int calcRowLogicalHeight();
124 void layoutRows();
125 void computeOverflowFromCells();
127 LayoutTable* table() const { return toLayoutTable(parent()); }
129 typedef Vector<LayoutTableCell*, 2> SpanningLayoutTableCells;
131 struct CellStruct {
132 ALLOW_ONLY_INLINE_ALLOCATION();
133 public:
134 Vector<LayoutTableCell*, 1> cells;
135 bool inColSpan; // true for columns after the first in a colspan
137 CellStruct()
138 : inColSpan(false)
142 LayoutTableCell* primaryCell()
144 return hasCells() ? cells[cells.size() - 1] : 0;
147 const LayoutTableCell* primaryCell() const
149 return hasCells() ? cells[cells.size() - 1] : 0;
152 bool hasCells() const { return cells.size() > 0; }
155 typedef Vector<CellStruct> Row;
157 struct RowStruct {
158 ALLOW_ONLY_INLINE_ALLOCATION();
159 public:
160 RowStruct()
161 : rowLayoutObject(nullptr)
162 , baseline(-1)
166 Row row;
167 LayoutTableRow* rowLayoutObject;
168 LayoutUnit baseline;
169 Length logicalHeight;
172 struct SpanningRowsHeight {
173 STACK_ALLOCATED();
174 WTF_MAKE_NONCOPYABLE(SpanningRowsHeight);
176 public:
177 SpanningRowsHeight()
178 : totalRowsHeight(0)
179 , spanningCellHeightIgnoringBorderSpacing(0)
180 , isAnyRowWithOnlySpanningCells(false)
184 Vector<int> rowHeight;
185 int totalRowsHeight;
186 int spanningCellHeightIgnoringBorderSpacing;
187 bool isAnyRowWithOnlySpanningCells;
190 const BorderValue& borderAdjoiningTableStart() const
192 if (hasSameDirectionAs(table()))
193 return style()->borderStart();
195 return style()->borderEnd();
198 const BorderValue& borderAdjoiningTableEnd() const
200 if (hasSameDirectionAs(table()))
201 return style()->borderEnd();
203 return style()->borderStart();
206 const BorderValue& borderAdjoiningStartCell(const LayoutTableCell*) const;
207 const BorderValue& borderAdjoiningEndCell(const LayoutTableCell*) const;
209 const LayoutTableCell* firstRowCellAdjoiningTableStart() const;
210 const LayoutTableCell* firstRowCellAdjoiningTableEnd() const;
212 CellStruct& cellAt(unsigned row, unsigned col) { return m_grid[row].row[col]; }
213 const CellStruct& cellAt(unsigned row, unsigned col) const { return m_grid[row].row[col]; }
214 LayoutTableCell* primaryCellAt(unsigned row, unsigned col)
216 CellStruct& c = m_grid[row].row[col];
217 return c.primaryCell();
220 LayoutTableRow* rowLayoutObjectAt(unsigned row) const { return m_grid[row].rowLayoutObject; }
222 void appendColumn(unsigned pos);
223 void splitColumn(unsigned pos, unsigned first);
225 enum BlockBorderSide { BorderBefore, BorderAfter };
226 int calcBlockDirectionOuterBorder(BlockBorderSide) const;
227 enum InlineBorderSide { BorderStart, BorderEnd };
228 int calcInlineDirectionOuterBorder(InlineBorderSide) const;
229 void recalcOuterBorder();
231 int outerBorderBefore() const { return m_outerBorderBefore; }
232 int outerBorderAfter() const { return m_outerBorderAfter; }
233 int outerBorderStart() const { return m_outerBorderStart; }
234 int outerBorderEnd() const { return m_outerBorderEnd; }
236 unsigned numRows() const { return m_grid.size(); }
237 unsigned numColumns() const;
239 // recalcCells() is used when we are not sure about the section's structure
240 // and want to do an expensive (but safe) reconstruction of m_grid from
241 // scratch.
242 // An example of this is inserting a new cell in the middle of an existing
243 // row or removing a row.
245 // Accessing m_grid when m_needsCellRecalc is set is UNSAFE as pointers can
246 // be left dangling. Thus care should be taken in the code to check
247 // m_needsCellRecalc before accessing m_grid.
248 void recalcCells();
249 void recalcCellsIfNeeded()
251 if (m_needsCellRecalc)
252 recalcCells();
255 bool needsCellRecalc() const { return m_needsCellRecalc; }
256 void setNeedsCellRecalc();
258 LayoutUnit rowBaseline(unsigned row) { return m_grid[row].baseline; }
260 void rowLogicalHeightChanged(LayoutTableRow*);
262 void removeCachedCollapsedBorders(const LayoutTableCell*);
263 // Returns true if any collapsed borders of the cell changed.
264 bool setCachedCollapsedBorder(const LayoutTableCell*, CollapsedBorderSide, const CollapsedBorderValue&);
265 const CollapsedBorderValue& cachedCollapsedBorder(const LayoutTableCell*, CollapsedBorderSide) const;
267 // distributeExtraLogicalHeightToRows methods return the *consumed* extra logical height.
268 // FIXME: We may want to introduce a structure holding the in-flux layout information.
269 int distributeExtraLogicalHeightToRows(int extraLogicalHeight);
271 static LayoutTableSection* createAnonymousWithParent(const LayoutObject*);
272 LayoutBox* createAnonymousBoxWithSameTypeAs(const LayoutObject* parent) const override
274 return createAnonymousWithParent(parent);
277 void paint(const PaintInfo&, const LayoutPoint&) override;
279 // Flip the rect so it aligns with the coordinates used by the rowPos and columnPos vectors.
280 LayoutRect logicalRectForWritingModeAndDirection(const LayoutRect&) const;
282 CellSpan dirtiedRows(const LayoutRect& paintInvalidationRect) const;
283 CellSpan dirtiedColumns(const LayoutRect& paintInvalidationRect) const;
284 HashSet<LayoutTableCell*>& overflowingCells() { return m_overflowingCells; }
285 bool hasMultipleCellLevels() { return m_hasMultipleCellLevels; }
287 const char* name() const override { return "LayoutTableSection"; }
289 protected:
290 void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override;
291 bool nodeAtPoint(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
293 private:
294 LayoutObjectChildList* virtualChildren() override { return children(); }
295 const LayoutObjectChildList* virtualChildren() const override { return children(); }
297 bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectTableSection || LayoutBox::isOfType(type); }
299 void willBeRemovedFromTree() override;
301 void layout() override;
303 void imageChanged(WrappedImagePtr, const IntRect* = nullptr) override;
305 int borderSpacingForRow(unsigned row) const { return m_grid[row].rowLayoutObject ? table()->vBorderSpacing() : 0; }
307 void ensureRows(unsigned);
309 bool rowHasOnlySpanningCells(unsigned);
310 unsigned calcRowHeightHavingOnlySpanningCells(unsigned, int&, unsigned, unsigned&, Vector<int>&);
311 void updateRowsHeightHavingOnlySpanningCells(LayoutTableCell*, struct SpanningRowsHeight&, unsigned&, Vector<int>&);
313 void populateSpanningRowsHeightFromCell(LayoutTableCell*, struct SpanningRowsHeight&);
314 void distributeExtraRowSpanHeightToPercentRows(LayoutTableCell*, int, int&, Vector<int>&);
315 void distributeWholeExtraRowSpanHeightToPercentRows(LayoutTableCell*, float, int&, Vector<int>&);
316 void distributeExtraRowSpanHeightToAutoRows(LayoutTableCell*, int, int&, Vector<int>&);
317 void distributeExtraRowSpanHeightToRemainingRows(LayoutTableCell*, int, int&, Vector<int>&);
318 void distributeRowSpanHeightToRows(SpanningLayoutTableCells& rowSpanCells);
320 void distributeExtraLogicalHeightToPercentRows(int& extraLogicalHeight, int totalPercent);
321 void distributeExtraLogicalHeightToAutoRows(int& extraLogicalHeight, unsigned autoRowsCount);
322 void distributeRemainingExtraLogicalHeight(int& extraLogicalHeight);
324 void updateBaselineForCell(LayoutTableCell*, unsigned row, LayoutUnit& baselineDescent);
326 bool hasOverflowingCell() const { return m_overflowingCells.size() || m_forceSlowPaintPathWithOverflowingCell; }
328 void computeOverflowFromCells(unsigned totalRows, unsigned nEffCols);
330 CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
331 CellSpan fullTableColumnSpan() const { return CellSpan(0, table()->columns().size()); }
333 // These two functions take a rectangle as input that has been flipped by logicalRectForWritingModeAndDirection.
334 // The returned span of rows or columns is end-exclusive, and empty if start==end.
335 CellSpan spannedRows(const LayoutRect& flippedRect) const;
336 CellSpan spannedColumns(const LayoutRect& flippedRect) const;
338 void setLogicalPositionForCell(LayoutTableCell*, unsigned effectiveColumn) const;
340 LayoutObjectChildList m_children;
342 // The representation of the rows and their cells (CellStruct).
343 Vector<RowStruct> m_grid;
345 // The logical offset of each row from the top of the section.
347 // Note that this Vector has one more entry than the number of rows so that
348 // we can keep track of the final size of the section
349 // (m_rowPos[m_grid.size() + 1]).
351 // To know a row's height at |rowIndex|, use the formula:
352 // m_rowPos[rowIndex + 1] - m_rowPos[rowIndex]
353 Vector<int> m_rowPos;
355 // The current insertion position in the grid.
356 // The position is used when inserting a new cell into the section to
357 // know where it should be inserted and expand our internal structure.
359 // The reason for them is that we process cells as we discover them
360 // during parsing or during recalcCells (ie in DOM order). This means
361 // that we can discover changes in the structure later (e.g. due to
362 // colspans, extra cells, ...).
364 // Do not use outside of recalcCells and addChild.
365 unsigned m_cCol;
366 unsigned m_cRow;
368 int m_outerBorderStart;
369 int m_outerBorderEnd;
370 int m_outerBorderBefore;
371 int m_outerBorderAfter;
373 bool m_needsCellRecalc;
375 // This HashSet holds the overflowing cells for faster painting.
376 // If we have more than gMaxAllowedOverflowingCellRatio * total cells, it will be empty
377 // and m_forceSlowPaintPathWithOverflowingCell will be set to save memory.
378 HashSet<LayoutTableCell*> m_overflowingCells;
379 bool m_forceSlowPaintPathWithOverflowingCell;
381 bool m_hasMultipleCellLevels;
383 // This map holds the collapsed border values for cells with collapsed borders.
384 // It is held at LayoutTableSection level to spare memory consumption by table cells.
385 using CellsCollapsedBordersMap = HashMap<pair<const LayoutTableCell*, int>, CollapsedBorderValue>;
386 CellsCollapsedBordersMap m_cellsCollapsedBorders;
389 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTableSection, isTableSection());
391 } // namespace blink
393 #endif // LayoutTableSection_h