| 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);
|
| }
|
| }
|
|
|
|
|