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 33dea95ba7d6b81d167c6218dbdeabb8e4045c5c..4bc6376712b00f534853f413128c74cd51dcef04 100644 |
--- a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp |
+++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp |
@@ -57,6 +57,41 @@ static inline bool compareCellPositionsWithOverflowingCells(LayoutTableCell* ele |
return elem1->col() < elem2->col(); |
} |
+void TableSectionPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, const CollapsedBorderValue& currentBorderValue) |
+{ |
+ if (!m_layoutTableSection.numRows() || !m_layoutTableSection.table()->columns().size()) |
+ return; |
+ |
+ LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableSection.location(); |
+ BoxClipper boxClipper(m_layoutTableSection, paintInfo, adjustedPaintOffset, ForceContentsClip); |
+ |
+ LayoutRect localPaintInvalidationRect = LayoutRect(paintInfo.rect); |
+ localPaintInvalidationRect.moveBy(-adjustedPaintOffset); |
+ |
+ LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingModeAndDirection(localPaintInvalidationRect); |
+ |
+ CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
+ CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRect); |
+ |
+ if (dirtiedColumns.start() >= dirtiedColumns.end()) |
+ return; |
+ |
+ // Collapsed borders are painted from the bottom right to the top left so that precedence |
+ // due to cell position is respected. |
+ for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { |
+ unsigned row = r - 1; |
+ for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) { |
+ unsigned col = c - 1; |
+ const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(row, col); |
+ const LayoutTableCell* cell = current.primaryCell(); |
+ if (!cell || (row > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(row, col - 1) == cell)) |
+ continue; |
+ LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(cell, adjustedPaintOffset); |
+ TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint, currentBorderValue); |
+ } |
+ } |
+} |
+ |
void TableSectionPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
{ |
LayoutRect localPaintInvalidationRect = LayoutRect(paintInfo.rect); |
@@ -67,91 +102,68 @@ void TableSectionPainter::paintObject(const PaintInfo& paintInfo, const LayoutPo |
CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRect); |
+ if (dirtiedColumns.start() >= dirtiedColumns.end()) |
+ return; |
+ |
const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.overflowingCells(); |
- if (dirtiedColumns.start() < dirtiedColumns.end()) { |
- if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size()) { |
- if (paintInfo.phase == PaintPhaseCollapsedTableBorders) { |
- // Collapsed borders are painted from the bottom right to the top left so that precedence |
- // due to cell position is respected. |
- for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { |
- unsigned row = r - 1; |
- for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) { |
- unsigned col = c - 1; |
- const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(row, col); |
- const LayoutTableCell* cell = current.primaryCell(); |
- if (!cell || (row > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(row, col - 1) == cell)) |
- continue; |
- LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(cell, paintOffset); |
- TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint); |
- } |
- } |
- } else { |
- // Draw the dirty cells in the order that they appear. |
- for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
- const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
- if (row && !row->hasSelfPaintingLayer()) |
- TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset); |
- for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
- const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c); |
- const LayoutTableCell* cell = current.primaryCell(); |
- if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(r, c - 1) == cell)) |
- continue; |
- paintCell(*cell, paintInfo, paintOffset); |
- } |
- } |
+ if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size()) { |
+ // Draw the dirty cells in the order that they appear. |
+ for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
+ const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
+ if (row && !row->hasSelfPaintingLayer()) |
+ TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset); |
+ for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
+ const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c); |
+ const LayoutTableCell* cell = current.primaryCell(); |
+ if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(r, c - 1) == cell)) |
+ continue; |
+ paintCell(*cell, paintInfo, paintOffset); |
} |
- } else { |
- // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet. |
+ } |
+ } else { |
+ // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet. |
#if ENABLE(ASSERT) |
- unsigned totalRows = m_layoutTableSection.numRows(); |
- unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
- ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOverflowingCellRatioForFastPaintPath); |
+ unsigned totalRows = m_layoutTableSection.numRows(); |
+ unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
+ ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOverflowingCellRatioForFastPaintPath); |
#endif |
- // To make sure we properly paint invalidate the section, we paint invalidated all the overflowing cells that we collected. |
- Vector<LayoutTableCell*> cells; |
- copyToVector(overflowingCells, cells); |
- |
- HashSet<LayoutTableCell*> spanningCells; |
- |
- for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
- const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
- if (row && !row->hasSelfPaintingLayer()) |
- TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset); |
- for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
- const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c); |
- if (!current.hasCells()) |
+ // To make sure we properly paint invalidate the section, we paint invalidated all the overflowing cells that we collected. |
+ Vector<LayoutTableCell*> cells; |
+ copyToVector(overflowingCells, cells); |
+ |
+ HashSet<LayoutTableCell*> spanningCells; |
+ |
+ for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
+ const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
+ if (row && !row->hasSelfPaintingLayer()) |
+ TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset); |
+ for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
+ const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c); |
+ if (!current.hasCells()) |
+ continue; |
+ for (unsigned i = 0; i < current.cells.size(); ++i) { |
+ if (overflowingCells.contains(current.cells[i])) |
continue; |
- for (unsigned i = 0; i < current.cells.size(); ++i) { |
- if (overflowingCells.contains(current.cells[i])) |
- continue; |
- |
- if (current.cells[i]->rowSpan() > 1 || current.cells[i]->colSpan() > 1) { |
- if (!spanningCells.add(current.cells[i]).isNewEntry) |
- continue; |
- } |
- cells.append(current.cells[i]); |
+ if (current.cells[i]->rowSpan() > 1 || current.cells[i]->colSpan() > 1) { |
+ if (!spanningCells.add(current.cells[i]).isNewEntry) |
+ continue; |
} |
- } |
- } |
- |
- // Sort the dirty cells by paint order. |
- if (!overflowingCells.size()) |
- std::stable_sort(cells.begin(), cells.end(), compareCellPositions); |
- else |
- std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverflowingCells); |
- if (paintInfo.phase == PaintPhaseCollapsedTableBorders) { |
- for (unsigned i = cells.size(); i > 0; --i) { |
- LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(cells[i - 1], paintOffset); |
- TableCellPainter(*cells[i - 1]).paintCollapsedBorders(paintInfo, cellPoint); |
+ cells.append(current.cells[i]); |
} |
- } else { |
- for (unsigned i = 0; i < cells.size(); ++i) |
- paintCell(*cells[i], paintInfo, paintOffset); |
} |
} |
+ |
+ // Sort the dirty cells by paint order. |
+ if (!overflowingCells.size()) |
+ std::stable_sort(cells.begin(), cells.end(), compareCellPositions); |
+ else |
+ std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverflowingCells); |
+ |
+ for (unsigned i = 0; i < cells.size(); ++i) |
+ paintCell(*cells[i], paintInfo, paintOffset); |
} |
} |