| 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 |