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/LayoutTableCell.h" | 7 #include "core/layout/LayoutTableCell.h" |
8 #include "core/layout/LayoutTableCol.h" | 8 #include "core/layout/LayoutTableCol.h" |
9 #include "core/layout/LayoutTableRow.h" | 9 #include "core/layout/LayoutTableRow.h" |
10 #include "core/paint/BoxClipper.h" | 10 #include "core/paint/BoxClipper.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 const CollapsedBorderValue& currentBorderValue, | 46 const CollapsedBorderValue& currentBorderValue, |
47 ItemToPaint itemToPaint) { | 47 ItemToPaint itemToPaint) { |
48 if (!m_layoutTableSection.isRepeatingHeaderGroup()) | 48 if (!m_layoutTableSection.isRepeatingHeaderGroup()) |
49 return; | 49 return; |
50 | 50 |
51 LayoutTable* table = m_layoutTableSection.table(); | 51 LayoutTable* table = m_layoutTableSection.table(); |
52 LayoutPoint paginationOffset = paintOffset; | 52 LayoutPoint paginationOffset = paintOffset; |
53 LayoutUnit pageHeight = table->pageLogicalHeightForOffset(LayoutUnit()); | 53 LayoutUnit pageHeight = table->pageLogicalHeightForOffset(LayoutUnit()); |
54 | 54 |
55 // Move paginationOffset to the top of the next page. | 55 // Move paginationOffset to the top of the next page. |
56 // The header may have a pagination strut before it so we need to account for
that when establishing its position. | 56 // The header may have a pagination strut before it so we need to account for |
| 57 // that when establishing its position. |
57 LayoutUnit headerGroupOffset = table->pageLogicalOffset(); | 58 LayoutUnit headerGroupOffset = table->pageLogicalOffset(); |
58 if (LayoutTableRow* row = m_layoutTableSection.firstRow()) | 59 if (LayoutTableRow* row = m_layoutTableSection.firstRow()) |
59 headerGroupOffset += row->paginationStrut(); | 60 headerGroupOffset += row->paginationStrut(); |
60 LayoutUnit offsetToNextPage = | 61 LayoutUnit offsetToNextPage = |
61 pageHeight - intMod(headerGroupOffset, pageHeight); | 62 pageHeight - intMod(headerGroupOffset, pageHeight); |
62 paginationOffset.move(0, offsetToNextPage.toInt()); | 63 paginationOffset.move(0, offsetToNextPage.toInt()); |
63 // Now move paginationOffset to the top of the page the cull rect starts on. | 64 // Now move paginationOffset to the top of the page the cull rect starts on. |
64 if (paintInfo.cullRect().m_rect.y() > paginationOffset.y()) | 65 if (paintInfo.cullRect().m_rect.y() > paginationOffset.y()) |
65 paginationOffset.move( | 66 paginationOffset.move( |
66 0, pageHeight.toInt() * | 67 0, pageHeight.toInt() * |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 if (shouldPaintSelfOutline(paintInfo.phase)) | 119 if (shouldPaintSelfOutline(paintInfo.phase)) |
119 ObjectPainter(m_layoutTableSection) | 120 ObjectPainter(m_layoutTableSection) |
120 .paintOutline(paintInfo, adjustedPaintOffset); | 121 .paintOutline(paintInfo, adjustedPaintOffset); |
121 } | 122 } |
122 | 123 |
123 static inline bool compareCellPositions(LayoutTableCell* elem1, | 124 static inline bool compareCellPositions(LayoutTableCell* elem1, |
124 LayoutTableCell* elem2) { | 125 LayoutTableCell* elem2) { |
125 return elem1->rowIndex() < elem2->rowIndex(); | 126 return elem1->rowIndex() < elem2->rowIndex(); |
126 } | 127 } |
127 | 128 |
128 // This comparison is used only when we have overflowing cells as we have an uns
orted array to sort. We thus need | 129 // This comparison is used only when we have overflowing cells as we have an |
129 // to sort both on rows and columns to properly issue paint invalidations. | 130 // unsorted array to sort. We thus need to sort both on rows and columns to |
| 131 // properly issue paint invalidations. |
130 static inline bool compareCellPositionsWithOverflowingCells( | 132 static inline bool compareCellPositionsWithOverflowingCells( |
131 LayoutTableCell* elem1, | 133 LayoutTableCell* elem1, |
132 LayoutTableCell* elem2) { | 134 LayoutTableCell* elem2) { |
133 if (elem1->rowIndex() != elem2->rowIndex()) | 135 if (elem1->rowIndex() != elem2->rowIndex()) |
134 return elem1->rowIndex() < elem2->rowIndex(); | 136 return elem1->rowIndex() < elem2->rowIndex(); |
135 | 137 |
136 return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex(); | 138 return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex(); |
137 } | 139 } |
138 | 140 |
139 void TableSectionPainter::paintCollapsedBorders( | 141 void TableSectionPainter::paintCollapsedBorders( |
(...skipping 28 matching lines...) Expand all Loading... |
168 m_layoutTableSection.logicalRectForWritingModeAndDirection( | 170 m_layoutTableSection.logicalRectForWritingModeAndDirection( |
169 localPaintInvalidationRect); | 171 localPaintInvalidationRect); |
170 | 172 |
171 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); | 173 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
172 CellSpan dirtiedColumns = | 174 CellSpan dirtiedColumns = |
173 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); | 175 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); |
174 | 176 |
175 if (dirtiedColumns.start() >= dirtiedColumns.end()) | 177 if (dirtiedColumns.start() >= dirtiedColumns.end()) |
176 return; | 178 return; |
177 | 179 |
178 // Collapsed borders are painted from the bottom right to the top left so that
precedence | 180 // Collapsed borders are painted from the bottom right to the top left so that |
179 // due to cell position is respected. | 181 // precedence due to cell position is respected. |
180 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { | 182 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { |
181 unsigned row = r - 1; | 183 unsigned row = r - 1; |
182 for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) { | 184 for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) { |
183 unsigned col = c - 1; | 185 unsigned col = c - 1; |
184 const LayoutTableSection::CellStruct& current = | 186 const LayoutTableSection::CellStruct& current = |
185 m_layoutTableSection.cellAt(row, col); | 187 m_layoutTableSection.cellAt(row, col); |
186 const LayoutTableCell* cell = current.primaryCell(); | 188 const LayoutTableCell* cell = current.primaryCell(); |
187 if (!cell || (row > dirtiedRows.start() && | 189 if (!cell || (row > dirtiedRows.start() && |
188 m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || | 190 m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || |
189 (col > dirtiedColumns.start() && | 191 (col > dirtiedColumns.start() && |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset); | 255 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset); |
254 } | 256 } |
255 } | 257 } |
256 | 258 |
257 const HashSet<LayoutTableCell*>& overflowingCells = | 259 const HashSet<LayoutTableCell*>& overflowingCells = |
258 m_layoutTableSection.overflowingCells(); | 260 m_layoutTableSection.overflowingCells(); |
259 if (!m_layoutTableSection.hasMultipleCellLevels() && | 261 if (!m_layoutTableSection.hasMultipleCellLevels() && |
260 overflowingCells.isEmpty()) { | 262 overflowingCells.isEmpty()) { |
261 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 263 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
262 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 264 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
263 // TODO(crbug.com/577282): This painting order is inconsistent with other
outlines. | 265 // TODO(crbug.com/577282): This painting order is inconsistent with other |
| 266 // outlines. |
264 if (row && !row->hasSelfPaintingLayer() && | 267 if (row && !row->hasSelfPaintingLayer() && |
265 shouldPaintSelfOutline(paintInfoForDescendants.phase)) | 268 shouldPaintSelfOutline(paintInfoForDescendants.phase)) |
266 TableRowPainter(*row).paintOutline(paintInfoForDescendants, | 269 TableRowPainter(*row).paintOutline(paintInfoForDescendants, |
267 paintOffset); | 270 paintOffset); |
268 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 271 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
269 if (const LayoutTableCell* cell = | 272 if (const LayoutTableCell* cell = |
270 primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns)) | 273 primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns)) |
271 paintCell(*cell, paintInfoForDescendants, paintOffset); | 274 paintCell(*cell, paintInfoForDescendants, paintOffset); |
272 } | 275 } |
273 } | 276 } |
274 } else { | 277 } else { |
275 // The overflowing cells should be scarce to avoid adding a lot of cells to
the HashSet. | 278 // The overflowing cells should be scarce to avoid adding a lot of cells to |
| 279 // the HashSet. |
276 DCHECK(overflowingCells.size() < | 280 DCHECK(overflowingCells.size() < |
277 m_layoutTableSection.numRows() * | 281 m_layoutTableSection.numRows() * |
278 m_layoutTableSection.table()->effectiveColumns().size() * | 282 m_layoutTableSection.table()->effectiveColumns().size() * |
279 gMaxAllowedOverflowingCellRatioForFastPaintPath); | 283 gMaxAllowedOverflowingCellRatioForFastPaintPath); |
280 | 284 |
281 // To make sure we properly paint the section, we paint all the overflowing
cells that we collected. | 285 // To make sure we properly paint the section, we paint all the overflowing |
| 286 // cells that we collected. |
282 Vector<LayoutTableCell*> cells; | 287 Vector<LayoutTableCell*> cells; |
283 copyToVector(overflowingCells, cells); | 288 copyToVector(overflowingCells, cells); |
284 | 289 |
285 HashSet<LayoutTableCell*> spanningCells; | 290 HashSet<LayoutTableCell*> spanningCells; |
286 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 291 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
287 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 292 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
288 // TODO(crbug.com/577282): This painting order is inconsistent with other
outlines. | 293 // TODO(crbug.com/577282): This painting order is inconsistent with other |
| 294 // outlines. |
289 if (row && !row->hasSelfPaintingLayer() && | 295 if (row && !row->hasSelfPaintingLayer() && |
290 shouldPaintSelfOutline(paintInfoForDescendants.phase)) | 296 shouldPaintSelfOutline(paintInfoForDescendants.phase)) |
291 TableRowPainter(*row).paintOutline(paintInfoForDescendants, | 297 TableRowPainter(*row).paintOutline(paintInfoForDescendants, |
292 paintOffset); | 298 paintOffset); |
293 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 299 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
294 const LayoutTableSection::CellStruct& current = | 300 const LayoutTableSection::CellStruct& current = |
295 m_layoutTableSection.cellAt(r, c); | 301 m_layoutTableSection.cellAt(r, c); |
296 for (LayoutTableCell* cell : current.cells) { | 302 for (LayoutTableCell* cell : current.cells) { |
297 if (overflowingCells.contains(cell)) | 303 if (overflowingCells.contains(cell)) |
298 continue; | 304 continue; |
(...skipping 18 matching lines...) Expand all Loading... |
317 } | 323 } |
318 } | 324 } |
319 | 325 |
320 void TableSectionPainter::paintBackgroundsBehindCell( | 326 void TableSectionPainter::paintBackgroundsBehindCell( |
321 const LayoutTableCell& cell, | 327 const LayoutTableCell& cell, |
322 const PaintInfo& paintInfoForCells, | 328 const PaintInfo& paintInfoForCells, |
323 const LayoutPoint& paintOffset) { | 329 const LayoutPoint& paintOffset) { |
324 LayoutPoint cellPoint = | 330 LayoutPoint cellPoint = |
325 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); | 331 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); |
326 | 332 |
327 // We need to handle painting a stack of backgrounds. This stack (from bottom
to top) consists of | 333 // We need to handle painting a stack of backgrounds. This stack (from bottom |
328 // the column group, column, row group, row, and then the cell. | 334 // to top) consists of the column group, column, row group, row, and then the |
| 335 // cell. |
329 | 336 |
330 LayoutTable::ColAndColGroup colAndColGroup = | 337 LayoutTable::ColAndColGroup colAndColGroup = |
331 m_layoutTableSection.table()->colElementAtAbsoluteColumn( | 338 m_layoutTableSection.table()->colElementAtAbsoluteColumn( |
332 cell.absoluteColumnIndex()); | 339 cell.absoluteColumnIndex()); |
333 LayoutTableCol* column = colAndColGroup.col; | 340 LayoutTableCol* column = colAndColGroup.col; |
334 LayoutTableCol* columnGroup = colAndColGroup.colgroup; | 341 LayoutTableCol* columnGroup = colAndColGroup.colgroup; |
335 TableCellPainter tableCellPainter(cell); | 342 TableCellPainter tableCellPainter(cell); |
336 | 343 |
337 // Column groups and columns first. | 344 // Column groups and columns first. |
338 // FIXME: Columns and column groups do not currently support opacity, and they
are being painted "too late" in | 345 // FIXME: Columns and column groups do not currently support opacity, and they |
339 // the stack, since we have already opened a transparency layer (potentially)
for the table row group. | 346 // are being painted "too late" in the stack, since we have already opened a |
340 // Note that we deliberately ignore whether or not the cell has a layer, since
these backgrounds paint "behind" the | 347 // transparency layer (potentially) for the table row group. Note that we |
341 // cell. | 348 // deliberately ignore whether or not the cell has a layer, since these |
| 349 // backgrounds paint "behind" the cell. |
342 if (columnGroup && columnGroup->styleRef().hasBackground()) | 350 if (columnGroup && columnGroup->styleRef().hasBackground()) |
343 tableCellPainter.paintContainerBackgroundBehindCell( | 351 tableCellPainter.paintContainerBackgroundBehindCell( |
344 paintInfoForCells, cellPoint, *columnGroup, | 352 paintInfoForCells, cellPoint, *columnGroup, |
345 DisplayItem::kTableCellBackgroundFromColumnGroup); | 353 DisplayItem::kTableCellBackgroundFromColumnGroup); |
346 if (column && column->styleRef().hasBackground()) | 354 if (column && column->styleRef().hasBackground()) |
347 tableCellPainter.paintContainerBackgroundBehindCell( | 355 tableCellPainter.paintContainerBackgroundBehindCell( |
348 paintInfoForCells, cellPoint, *column, | 356 paintInfoForCells, cellPoint, *column, |
349 DisplayItem::kTableCellBackgroundFromColumn); | 357 DisplayItem::kTableCellBackgroundFromColumn); |
350 | 358 |
351 // Paint the row group next. | 359 // Paint the row group next. |
(...skipping 30 matching lines...) Expand all Loading... |
382 LayoutRect bounds = BoxPainter(m_layoutTableSection) | 390 LayoutRect bounds = BoxPainter(m_layoutTableSection) |
383 .boundsForDrawingRecorder(paintInfo, paintOffset); | 391 .boundsForDrawingRecorder(paintInfo, paintOffset); |
384 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection, | 392 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection, |
385 type, bounds); | 393 type, bounds); |
386 BoxPainter::paintBoxShadow( | 394 BoxPainter::paintBoxShadow( |
387 paintInfo, LayoutRect(paintOffset, m_layoutTableSection.size()), | 395 paintInfo, LayoutRect(paintOffset, m_layoutTableSection.size()), |
388 m_layoutTableSection.styleRef(), shadowStyle); | 396 m_layoutTableSection.styleRef(), shadowStyle); |
389 } | 397 } |
390 | 398 |
391 } // namespace blink | 399 } // namespace blink |
OLD | NEW |