OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/TableSectionPainter.h" | 5 #include "core/paint/TableSectionPainter.h" |
6 | 6 |
7 #include "core/layout/LayoutTable.h" | 7 #include "core/layout/LayoutTable.h" |
8 #include "core/layout/LayoutTableCell.h" | 8 #include "core/layout/LayoutTableCell.h" |
9 #include "core/layout/LayoutTableCol.h" | 9 #include "core/layout/LayoutTableCol.h" |
10 #include "core/layout/LayoutTableRow.h" | 10 #include "core/layout/LayoutTableRow.h" |
11 #include "core/paint/BlockPainter.h" | 11 #include "core/paint/BlockPainter.h" |
12 #include "core/paint/BoxClipper.h" | 12 #include "core/paint/BoxClipper.h" |
13 #include "core/paint/LayoutObjectDrawingRecorder.h" | 13 #include "core/paint/LayoutObjectDrawingRecorder.h" |
14 #include "core/paint/ObjectPainter.h" | 14 #include "core/paint/ObjectPainter.h" |
15 #include "core/paint/PaintInfo.h" | 15 #include "core/paint/PaintInfo.h" |
16 #include "core/paint/TableCellPainter.h" | 16 #include "core/paint/TableCellPainter.h" |
17 #include "core/paint/TableRowPainter.h" | 17 #include "core/paint/TableRowPainter.h" |
18 #include <algorithm> | 18 #include <algorithm> |
19 | 19 |
20 namespace blink { | 20 namespace blink { |
21 | 21 |
22 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p
aintOffset) | 22 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p
aintOffset) |
23 { | 23 { |
24 ASSERT(!m_layoutTableSection.needsLayout()); | 24 ASSERT(!m_layoutTableSection.needsLayout()); |
25 // avoid crashing on bugs that cause us to paint with dirty layout | 25 // avoid crashing on bugs that cause us to paint with dirty layout |
26 if (m_layoutTableSection.needsLayout()) | 26 if (m_layoutTableSection.needsLayout()) |
27 return; | 27 return; |
28 | 28 |
29 // Table sections don't paint self background. The cells paint table section
's background | |
30 // behind them when needed during PaintPhaseBlockBackground or PaintPhaseDes
cendantBlockBackgroundOnly. | |
31 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) | |
32 return; | |
33 | |
34 unsigned totalRows = m_layoutTableSection.numRows(); | 29 unsigned totalRows = m_layoutTableSection.numRows(); |
35 unsigned totalCols = m_layoutTableSection.table()->columns().size(); | 30 unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
36 | 31 |
37 if (!totalRows || !totalCols) | 32 if (!totalRows || !totalCols) |
38 return; | 33 return; |
39 | 34 |
40 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableSection.locatio
n(); | 35 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableSection.locatio
n(); |
41 | 36 |
42 if (paintInfo.phase != PaintPhaseSelfOutlineOnly) { | 37 if (paintInfo.phase != PaintPhaseSelfOutlineOnly) { |
43 BoxClipper boxClipper(m_layoutTableSection, paintInfo, adjustedPaintOffs
et, ForceContentsClip); | 38 Optional<BoxClipper> boxClipper; |
| 39 if (paintInfo.phase != PaintPhaseSelfBlockBackgroundOnly) |
| 40 boxClipper.emplace(m_layoutTableSection, paintInfo, adjustedPaintOff
set, ForceContentsClip); |
44 paintObject(paintInfo, adjustedPaintOffset); | 41 paintObject(paintInfo, adjustedPaintOffset); |
45 } | 42 } |
46 | 43 |
47 if (shouldPaintSelfOutline(paintInfo.phase)) | 44 if (shouldPaintSelfOutline(paintInfo.phase)) |
48 ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, adjustedPain
tOffset); | 45 ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, adjustedPain
tOffset); |
49 } | 46 } |
50 | 47 |
51 static inline bool compareCellPositions(LayoutTableCell* elem1, LayoutTableCell*
elem2) | 48 static inline bool compareCellPositions(LayoutTableCell* elem1, LayoutTableCell*
elem2) |
52 { | 49 { |
53 return elem1->rowIndex() < elem2->rowIndex(); | 50 return elem1->rowIndex() < elem2->rowIndex(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 115 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
119 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r
); | 116 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r
); |
120 // TODO(wangxianzhu): This painting order is inconsistent with other
outlines. crbug.com/577282. | 117 // TODO(wangxianzhu): This painting order is inconsistent with other
outlines. crbug.com/577282. |
121 if (row && !row->hasSelfPaintingLayer()) | 118 if (row && !row->hasSelfPaintingLayer()) |
122 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain
tOffset); | 119 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain
tOffset); |
123 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end();
c++) { | 120 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end();
c++) { |
124 const LayoutTableSection::CellStruct& current = m_layoutTableSec
tion.cellAt(r, c); | 121 const LayoutTableSection::CellStruct& current = m_layoutTableSec
tion.cellAt(r, c); |
125 const LayoutTableCell* cell = current.primaryCell(); | 122 const LayoutTableCell* cell = current.primaryCell(); |
126 if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.pr
imaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSe
ction.primaryCellAt(r, c - 1) == cell)) | 123 if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.pr
imaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSe
ction.primaryCellAt(r, c - 1) == cell)) |
127 continue; | 124 continue; |
128 paintCell(*cell, paintInfoForCells, paintOffset); | 125 paintCell(*cell, paintInfo.phase, paintInfoForCells, paintOffset
); |
129 } | 126 } |
130 } | 127 } |
131 } else { | 128 } else { |
132 // The overflowing cells should be scarce to avoid adding a lot of cells
to the HashSet. | 129 // The overflowing cells should be scarce to avoid adding a lot of cells
to the HashSet. |
133 #if ENABLE(ASSERT) | 130 #if ENABLE(ASSERT) |
134 unsigned totalRows = m_layoutTableSection.numRows(); | 131 unsigned totalRows = m_layoutTableSection.numRows(); |
135 unsigned totalCols = m_layoutTableSection.table()->columns().size(); | 132 unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
136 ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOver
flowingCellRatioForFastPaintPath); | 133 ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOver
flowingCellRatioForFastPaintPath); |
137 #endif | 134 #endif |
138 | 135 |
(...skipping 26 matching lines...) Expand all Loading... |
165 } | 162 } |
166 } | 163 } |
167 | 164 |
168 // Sort the dirty cells by paint order. | 165 // Sort the dirty cells by paint order. |
169 if (!overflowingCells.size()) | 166 if (!overflowingCells.size()) |
170 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); | 167 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); |
171 else | 168 else |
172 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl
owingCells); | 169 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl
owingCells); |
173 | 170 |
174 for (unsigned i = 0; i < cells.size(); ++i) | 171 for (unsigned i = 0; i < cells.size(); ++i) |
175 paintCell(*cells[i], paintInfoForCells, paintOffset); | 172 paintCell(*cells[i], paintInfo.phase, paintInfoForCells, paintOffset
); |
176 } | 173 } |
177 } | 174 } |
178 | 175 |
179 void TableSectionPainter::paintCell(const LayoutTableCell& cell, const PaintInfo
& paintInfo, const LayoutPoint& paintOffset) | 176 void TableSectionPainter::paintCell(const LayoutTableCell& cell, PaintPhase orig
inalPaintPhase, const PaintInfo& paintInfoForCells, const LayoutPoint& paintOffs
et) |
180 { | 177 { |
181 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel
l, paintOffset); | 178 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel
l, paintOffset); |
182 PaintPhase paintPhase = paintInfo.phase; | |
183 const LayoutTableRow* row = toLayoutTableRow(cell.parent()); | 179 const LayoutTableRow* row = toLayoutTableRow(cell.parent()); |
184 | 180 |
185 if (shouldPaintSelfBlockBackground(paintPhase) | 181 if (!BlockPainter(cell).intersectsPaintRect(paintInfoForCells, paintOffset +
cell.location())) |
186 && BlockPainter(cell).intersectsPaintRect(paintInfo, paintOffset + cell.
location())) { | 182 return; |
| 183 |
| 184 if (shouldPaintSelfBlockBackground(originalPaintPhase)) { |
187 // We need to handle painting a stack of backgrounds. This stack (from b
ottom to top) consists of | 185 // We need to handle painting a stack of backgrounds. This stack (from b
ottom to top) consists of |
188 // the column group, column, row group, row, and then the cell. | 186 // the column group, column, row group, row, and then the cell. |
189 | 187 |
190 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table(
)->colElement(cell.col()); | 188 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table(
)->colElement(cell.col()); |
191 LayoutTableCol* column = colAndColGroup.col; | 189 LayoutTableCol* column = colAndColGroup.col; |
192 LayoutTableCol* columnGroup = colAndColGroup.colgroup; | 190 LayoutTableCol* columnGroup = colAndColGroup.colgroup; |
193 TableCellPainter tableCellPainter(cell); | 191 TableCellPainter tableCellPainter(cell); |
194 | 192 |
195 // Column groups and columns first. | 193 // Column groups and columns first. |
196 // FIXME: Columns and column groups do not currently support opacity, an
d they are being painted "too late" in | 194 // FIXME: Columns and column groups do not currently support opacity, an
d they are being painted "too late" in |
197 // the stack, since we have already opened a transparency layer (potenti
ally) for the table row group. | 195 // the stack, since we have already opened a transparency layer (potenti
ally) for the table row group. |
198 // Note that we deliberately ignore whether or not the cell has a layer,
since these backgrounds paint "behind" the | 196 // Note that we deliberately ignore whether or not the cell has a layer,
since these backgrounds paint "behind" the |
199 // cell. | 197 // cell. |
200 if (columnGroup && columnGroup->hasBackground()) | 198 if (columnGroup && columnGroup->hasBackground()) |
201 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, co
lumnGroup, DisplayItem::TableCellBackgroundFromColumnGroup); | 199 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP
oint, columnGroup, DisplayItem::TableCellBackgroundFromColumnGroup); |
202 if (column && column->hasBackground()) | 200 if (column && column->hasBackground()) |
203 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, co
lumn, DisplayItem::TableCellBackgroundFromColumn); | 201 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP
oint, column, DisplayItem::TableCellBackgroundFromColumn); |
204 | 202 |
205 // Paint the row group next. | 203 // Paint the row group next. |
206 if (m_layoutTableSection.hasBackground()) | 204 if (m_layoutTableSection.hasBackground()) |
207 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, &m
_layoutTableSection, DisplayItem::TableCellBackgroundFromSection); | 205 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP
oint, &m_layoutTableSection, DisplayItem::TableCellBackgroundFromSection); |
| 206 } |
208 | 207 |
| 208 if (shouldPaintDescendantBlockBackgrounds(originalPaintPhase)) { |
209 // Paint the row next, but only if it doesn't have a layer. If a row has
a layer, it will be responsible for | 209 // Paint the row next, but only if it doesn't have a layer. If a row has
a layer, it will be responsible for |
210 // painting the row background for the cell. | 210 // painting the row background for the cell. |
211 if (row->hasBackground() && !row->hasSelfPaintingLayer()) | 211 if (row->hasBackground() && !row->hasSelfPaintingLayer()) |
212 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, ro
w, DisplayItem::TableCellBackgroundFromRow); | 212 TableCellPainter(cell).paintBackgroundsBehindCell(paintInfoForCells,
cellPoint, row, DisplayItem::TableCellBackgroundFromRow); |
213 } | 213 } |
214 if ((!cell.hasSelfPaintingLayer() && !row->hasSelfPaintingLayer())) | 214 |
215 cell.paint(paintInfo, cellPoint); | 215 if (originalPaintPhase != PaintPhaseSelfBlockBackgroundOnly && !cell.hasSelf
PaintingLayer() && !row->hasSelfPaintingLayer()) |
| 216 cell.paint(paintInfoForCells, cellPoint); |
216 } | 217 } |
217 | 218 |
218 } // namespace blink | 219 } // namespace blink |
OLD | NEW |