Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(774)

Unified Diff: third_party/WebKit/Source/core/paint/TableSectionPainter.cpp

Issue 2786463004: Paint backgrounds of a table section/row in one display item (Closed)
Patch Set: - Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
diff --git a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
index de40383390836b5c3a33ca986e192270964c068f..f2f9dc4605905fce8a8ae539ff1438e5bb0dd912 100644
--- a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
@@ -108,8 +108,8 @@ void TableSectionPainter::paintSection(const PaintInfo& paintInfo,
.paintOutline(paintInfo, adjustedPaintOffset);
}
-static inline bool compareCellPositions(LayoutTableCell* elem1,
- LayoutTableCell* elem2) {
+static inline bool compareCellPositions(const LayoutTableCell* elem1,
+ const LayoutTableCell* elem2) {
return elem1->rowIndex() < elem2->rowIndex();
}
@@ -117,8 +117,8 @@ static inline bool compareCellPositions(LayoutTableCell* elem1,
// unsorted array to sort. We thus need to sort both on rows and columns to
// properly issue paint invalidations.
static inline bool compareCellPositionsWithOverflowingCells(
- LayoutTableCell* elem1,
- LayoutTableCell* elem2) {
+ const LayoutTableCell* elem1,
+ const LayoutTableCell* elem2) {
if (elem1->rowIndex() != elem2->rowIndex())
return elem1->rowIndex() < elem2->rowIndex();
@@ -195,23 +195,11 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
CellSpan dirtiedColumns =
m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect);
- if (dirtiedColumns.start() >= dirtiedColumns.end())
- return;
-
PaintInfo paintInfoForDescendants = paintInfo.forDescendants();
if (shouldPaintSelfBlockBackground(paintInfo.phase)) {
- paintBoxShadow(paintInfo, paintOffset, Normal);
- for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
- for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
- if (const LayoutTableCell* cell =
- m_layoutTableSection.originatingCellAt(r, c)) {
- paintBackgroundsBehindCell(*cell, paintInfoForDescendants,
- paintOffset);
- }
- }
- }
- paintBoxShadow(paintInfo, paintOffset, Inset);
+ paintBoxDecorationBackground(paintInfo, paintOffset, dirtiedRows,
+ dirtiedColumns);
}
if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly)
@@ -220,28 +208,23 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) {
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
- // If a row has a layer, we'll paint row background in TableRowPainter.
+ // If a row has a layer, we'll paint row background though
+ // TableRowPainter::paint().
if (!row || row->hasSelfPaintingLayer())
continue;
-
- TableRowPainter rowPainter(*row);
- rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Normal);
- if (row->styleRef().hasBackground()) {
- for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end();
- c++) {
- if (const LayoutTableCell* cell =
- m_layoutTableSection.originatingCellAt(r, c)) {
- rowPainter.paintBackgroundBehindCell(*cell, paintInfoForDescendants,
- paintOffset);
- }
- }
- }
- rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset);
+ TableRowPainter(*row).paintBoxDecorationBackground(
+ paintInfoForDescendants, paintOffset, dirtiedColumns);
}
}
- const HashSet<LayoutTableCell*>& overflowingCells =
- m_layoutTableSection.overflowingCells();
+ // This is tested after background painting because during background painting
+ // we need to check validity of the previous background display item based on
+ // dirtyRows and dirtyColumns.
+ if (dirtiedRows.start() >= dirtiedRows.end() ||
+ dirtiedColumns.start() >= dirtiedColumns.end())
+ return;
+
+ const auto& overflowingCells = m_layoutTableSection.overflowingCells();
if (!m_layoutTableSection.hasMultipleCellLevels() &&
overflowingCells.isEmpty()) {
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
@@ -249,9 +232,10 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
// TODO(crbug.com/577282): This painting order is inconsistent with other
// outlines.
if (row && !row->hasSelfPaintingLayer() &&
- shouldPaintSelfOutline(paintInfoForDescendants.phase))
+ shouldPaintSelfOutline(paintInfoForDescendants.phase)) {
TableRowPainter(*row).paintOutline(paintInfoForDescendants,
paintOffset);
+ }
for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
if (const LayoutTableCell* cell =
m_layoutTableSection.originatingCellAt(r, c))
@@ -268,24 +252,24 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
// To make sure we properly paint the section, we paint all the overflowing
// cells that we collected.
- Vector<LayoutTableCell*> cells;
+ Vector<const LayoutTableCell*> cells;
copyToVector(overflowingCells, cells);
- HashSet<LayoutTableCell*> spanningCells;
+ HashSet<const LayoutTableCell*> spanningCells;
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
// TODO(crbug.com/577282): This painting order is inconsistent with other
// outlines.
if (row && !row->hasSelfPaintingLayer() &&
- shouldPaintSelfOutline(paintInfoForDescendants.phase))
+ shouldPaintSelfOutline(paintInfoForDescendants.phase)) {
TableRowPainter(*row).paintOutline(paintInfoForDescendants,
paintOffset);
+ }
unsigned nCols = m_layoutTableSection.numCols(r);
for (unsigned c = dirtiedColumns.start();
c < nCols && c < dirtiedColumns.end(); c++) {
- const LayoutTableSection::CellStruct& current =
- m_layoutTableSection.cellAt(r, c);
- for (LayoutTableCell* cell : current.cells) {
+ const auto& cellStruct = m_layoutTableSection.cellAt(r, c);
+ for (const auto* cell : cellStruct.cells) {
if (overflowingCells.contains(cell))
continue;
if (cell->rowSpan() > 1 || cell->colSpan() > 1) {
@@ -298,17 +282,73 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo,
}
// Sort the dirty cells by paint order.
- if (!overflowingCells.size())
+ if (!overflowingCells.size()) {
std::stable_sort(cells.begin(), cells.end(), compareCellPositions);
- else
+ } else {
std::sort(cells.begin(), cells.end(),
compareCellPositionsWithOverflowingCells);
+ }
- for (const LayoutTableCell* cell : cells)
+ for (const auto* cell : cells)
paintCell(*cell, paintInfoForDescendants, paintOffset);
}
}
+void TableSectionPainter::paintBoxDecorationBackground(
+ const PaintInfo& paintInfo,
+ const LayoutPoint& paintOffset,
+ const CellSpan& dirtiedRows,
+ const CellSpan& dirtiedColumns) {
+ bool mayHaveBackground = m_layoutTableSection.table()->hasColElements() ||
+ m_layoutTableSection.styleRef().hasBackground();
+ bool hasBoxShadow = m_layoutTableSection.styleRef().boxShadow();
+ if (!mayHaveBackground && !hasBoxShadow)
+ return;
+
+ PaintResult paintResult =
+ dirtiedColumns == m_layoutTableSection.fullTableEffectiveColumnSpan() &&
+ dirtiedRows == m_layoutTableSection.fullSectionRowSpan()
+ ? FullyPainted
+ : MayBeClippedByPaintDirtyRect;
+ m_layoutTableSection.getMutableForPainting().updatePaintResult(
+ paintResult, paintInfo.cullRect());
+
+ if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
+ paintInfo.context, m_layoutTableSection,
+ DisplayItem::kBoxDecorationBackground))
+ return;
+
+ LayoutRect bounds = BoxPainter(m_layoutTableSection)
+ .boundsForDrawingRecorder(paintInfo, paintOffset);
+ LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection,
+ DisplayItem::kBoxDecorationBackground,
+ bounds);
+ LayoutRect paintRect(paintOffset, m_layoutTableSection.size());
+
+ if (hasBoxShadow) {
+ BoxPainter::paintNormalBoxShadow(paintInfo, paintRect,
+ m_layoutTableSection.styleRef());
+ }
+
+ if (mayHaveBackground) {
+ PaintInfo paintInfoForCells = paintInfo.forDescendants();
+ for (auto r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
+ for (auto c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
+ if (const auto* cell = m_layoutTableSection.originatingCellAt(r, c)) {
+ paintBackgroundsBehindCell(*cell, paintInfoForCells, paintOffset);
+ }
+ }
+ }
+ }
+
+ if (hasBoxShadow) {
+ // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting
+ // paintRect by half widths of collapsed borders.
+ BoxPainter::paintInsetBoxShadow(paintInfo, paintRect,
+ m_layoutTableSection.styleRef());
+ }
+}
+
void TableSectionPainter::paintBackgroundsBehindCell(
const LayoutTableCell& cell,
const PaintInfo& paintInfoForCells,
@@ -333,20 +373,20 @@ void TableSectionPainter::paintBackgroundsBehindCell(
// transparency layer (potentially) for the table row group. Note that we
// deliberately ignore whether or not the cell has a layer, since these
// backgrounds paint "behind" the cell.
- if (columnGroup && columnGroup->styleRef().hasBackground())
+ if (columnGroup && columnGroup->styleRef().hasBackground()) {
tableCellPainter.paintContainerBackgroundBehindCell(
- paintInfoForCells, cellPoint, *columnGroup,
- DisplayItem::kTableCellBackgroundFromColumnGroup);
- if (column && column->styleRef().hasBackground())
- tableCellPainter.paintContainerBackgroundBehindCell(
- paintInfoForCells, cellPoint, *column,
- DisplayItem::kTableCellBackgroundFromColumn);
+ paintInfoForCells, cellPoint, *columnGroup);
+ }
+ if (column && column->styleRef().hasBackground()) {
+ tableCellPainter.paintContainerBackgroundBehindCell(paintInfoForCells,
+ cellPoint, *column);
+ }
// Paint the row group next.
- if (m_layoutTableSection.styleRef().hasBackground())
+ if (m_layoutTableSection.styleRef().hasBackground()) {
tableCellPainter.paintContainerBackgroundBehindCell(
- paintInfoForCells, cellPoint, m_layoutTableSection,
- DisplayItem::kTableCellBackgroundFromSection);
+ paintInfoForCells, cellPoint, m_layoutTableSection);
+ }
}
void TableSectionPainter::paintCell(const LayoutTableCell& cell,
@@ -359,34 +399,4 @@ void TableSectionPainter::paintCell(const LayoutTableCell& cell,
}
}
-void TableSectionPainter::paintBoxShadow(const PaintInfo& paintInfo,
- const LayoutPoint& paintOffset,
- ShadowStyle shadowStyle) {
- DCHECK(shouldPaintSelfBlockBackground(paintInfo.phase));
- if (!m_layoutTableSection.styleRef().boxShadow())
- return;
-
- DisplayItem::Type type = shadowStyle == Normal
- ? DisplayItem::kTableSectionBoxShadowNormal
- : DisplayItem::kTableSectionBoxShadowInset;
- if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
- paintInfo.context, m_layoutTableSection, type))
- return;
-
- LayoutRect bounds = BoxPainter(m_layoutTableSection)
- .boundsForDrawingRecorder(paintInfo, paintOffset);
- LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection,
- type, bounds);
- LayoutRect paintRect(paintOffset, m_layoutTableSection.size());
- if (shadowStyle == Normal) {
- BoxPainter::paintNormalBoxShadow(paintInfo, paintRect,
- m_layoutTableSection.styleRef());
- } else {
- // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting
- // paintRect by half widths of collapsed borders.
- BoxPainter::paintInsetBoxShadow(paintInfo, paintRect,
- m_layoutTableSection.styleRef());
- }
-}
-
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698