Extract the logic for computing the dirty rows / columns out of RenderTableSection...
authorjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Feb 2012 01:05:10 +0000 (01:05 +0000)
committerjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Feb 2012 01:05:10 +0000 (01:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=79580

Reviewed by Eric Seidel.

Refactoring only.

* rendering/RenderTableSection.h:
(CellSpan):
(WebCore::CellSpan::CellSpan):
(WebCore::CellSpan::start):
(WebCore::CellSpan::end):
Added this class to hold the span information.

(WebCore::RenderTableSection::fullTableRowSpan):
(WebCore::RenderTableSection::fullTableColumnSpan):
Those functions return the span corresponding to the full table.

* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::dirtiedRows):
(WebCore::RenderTableSection::dirtiedColumns):
Those functions compute the rows / columns impacted by a |damageRect|. On the slow painting path, they
return the full table span.

(WebCore::RenderTableSection::paintObject):
Updated this function to call the new ones. Also we now inflate the local rectangle with the outlineSize.
This wasn't done previously and we had to manually patch some size comparison to account for the outline.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@109042 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderTableSection.h

index c79cddf..7f80d1e 100644 (file)
@@ -1,3 +1,33 @@
+2012-02-27  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Extract the logic for computing the dirty rows / columns out of RenderTableSection::paintObject
+        https://bugs.webkit.org/show_bug.cgi?id=79580
+
+        Reviewed by Eric Seidel.
+
+        Refactoring only.
+
+        * rendering/RenderTableSection.h:
+        (CellSpan):
+        (WebCore::CellSpan::CellSpan):
+        (WebCore::CellSpan::start):
+        (WebCore::CellSpan::end):
+        Added this class to hold the span information.
+
+        (WebCore::RenderTableSection::fullTableRowSpan):
+        (WebCore::RenderTableSection::fullTableColumnSpan):
+        Those functions return the span corresponding to the full table.
+
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::dirtiedRows):
+        (WebCore::RenderTableSection::dirtiedColumns):
+        Those functions compute the rows / columns impacted by a |damageRect|. On the slow painting path, they
+        return the full table span.
+
+        (WebCore::RenderTableSection::paintObject):
+        Updated this function to call the new ones. Also we now inflate the local rectangle with the outlineSize.
+        This wasn't done previously and we had to manually patch some size comparison to account for the outline.
+
 2012-02-27  Kentaro Hara  <haraken@chromium.org>
 
         Rename resolve-supplemental.pl to preprocess-idls.pl
index 3185516..6475f87 100644 (file)
@@ -993,17 +993,63 @@ void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo,
         cell->paint(paintInfo, cellPoint);
 }
 
-void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+CellSpan RenderTableSection::dirtiedRows(const LayoutRect& damageRect) const
 {
-    // Check which rows and cols are visible and only paint these.
-    unsigned totalRows = m_grid.size();
-    unsigned totalCols = table()->columns().size();
+    if (m_forceSlowPaintPathWithOverflowingCell) 
+        return fullTableRowSpan();
 
-    PaintPhase paintPhase = paintInfo.phase;
+    LayoutUnit before = style()->isHorizontalWritingMode() ? damageRect.y() : damageRect.x();
+
+    // binary search to find a row
+    unsigned startRow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), before) - m_rowPos.begin();
+
+    // The binary search above gives us the first row with
+    // a y position >= the top of the paint rect. Thus, the previous
+    // may need to be repainted as well.
+    if (startRow == m_rowPos.size() || (startRow > 0 && (m_rowPos[startRow] >  before)))
+        --startRow;
+
+    LayoutUnit after = (style()->isHorizontalWritingMode() ? damageRect.maxY() : damageRect.maxX());
+    unsigned endRow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), after) - m_rowPos.begin();
+    if (endRow == m_rowPos.size())
+        --endRow;
+
+    if (!endRow && m_rowPos[0] - table()->outerBorderBefore() <= after)
+        ++endRow;
+
+    return CellSpan(startRow, endRow);
+}
+
+
+CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const
+{
+    if (m_forceSlowPaintPathWithOverflowingCell) 
+        return fullTableColumnSpan();
+
+    // FIXME: Implement RTL.
+    if (!style()->isLeftToRightDirection())
+        return fullTableColumnSpan();
 
-    LayoutUnit os = 2 * maximalOutlineSize(paintPhase);
-    unsigned startrow = 0;
-    unsigned endrow = totalRows;
+    LayoutUnit start = style()->isHorizontalWritingMode() ? damageRect.x() : damageRect.y();
+    Vector<int>& columnPos = table()->columnPositions();
+    unsigned startCol = std::lower_bound(columnPos.begin(), columnPos.end(), start) - columnPos.begin();
+    if ((startCol == columnPos.size()) || (startCol > 0 && (columnPos[startCol] > start)))
+        --startCol;
+
+    LayoutUnit end = (style()->isHorizontalWritingMode() ? damageRect.maxX() : damageRect.maxY());
+    unsigned endCol = std::lower_bound(columnPos.begin(), columnPos.end(), end) - columnPos.begin();
+    if (endCol == columnPos.size())
+        --endCol;
+
+    if (!endCol && columnPos[0] - table()->outerBorderStart() <= end)
+        ++endCol;
+
+    return CellSpan(startCol, endCol);
+}
+
+void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+    PaintPhase paintPhase = paintInfo.phase;
 
     LayoutRect localRepaintRect = paintInfo.rect;
     localRepaintRect.moveBy(-paintOffset);
@@ -1014,56 +1060,25 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
             localRepaintRect.setX(width() - localRepaintRect.maxX());
     }
 
-    if (!m_forceSlowPaintPathWithOverflowingCell) {
-        LayoutUnit before = (style()->isHorizontalWritingMode() ? localRepaintRect.y() : localRepaintRect.x()) - os;
-        // binary search to find a row
-        startrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), before) - m_rowPos.begin();
-
-        // The binary search above gives us the first row with
-        // a y position >= the top of the paint rect. Thus, the previous
-        // may need to be repainted as well.
-        if (startrow == m_rowPos.size() || (startrow > 0 && (m_rowPos[startrow] >  before)))
-          --startrow;
+    // FIXME: Why do we double the outline size?
+    LayoutUnit outlineSize = 2 * maximalOutlineSize(paintPhase);
+    localRepaintRect.inflate(outlineSize);
 
-        LayoutUnit after = (style()->isHorizontalWritingMode() ? localRepaintRect.maxY() : localRepaintRect.maxX()) + os;
-        endrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), after) - m_rowPos.begin();
-        if (endrow == m_rowPos.size())
-          --endrow;
-
-        if (!endrow && m_rowPos[0] - table()->outerBorderBefore() <= after)
-            ++endrow;
-    }
+    CellSpan dirtiedRows = this->dirtiedRows(localRepaintRect);
+    CellSpan dirtiedColumns = this->dirtiedColumns(localRepaintRect);
 
-    unsigned startcol = 0;
-    unsigned endcol = totalCols;
-    // FIXME: Implement RTL.
-    if (!m_forceSlowPaintPathWithOverflowingCell && style()->isLeftToRightDirection()) {
-        LayoutUnit start = (style()->isHorizontalWritingMode() ? localRepaintRect.x() : localRepaintRect.y()) - os;
-        Vector<int>& columnPos = table()->columnPositions();
-        startcol = std::lower_bound(columnPos.begin(), columnPos.end(), start) - columnPos.begin();
-        if ((startcol == columnPos.size()) || (startcol > 0 && (columnPos[startcol] > start)))
-            --startcol;
-
-        LayoutUnit end = (style()->isHorizontalWritingMode() ? localRepaintRect.maxX() : localRepaintRect.maxY()) + os;
-        endcol = std::lower_bound(columnPos.begin(), columnPos.end(), end) - columnPos.begin();
-        if (endcol == columnPos.size())
-            --endcol;
-
-        if (!endcol && columnPos[0] - table()->outerBorderStart() <= end)
-            ++endcol;
-    }
-    if (startcol < endcol) {
+    if (dirtiedColumns.start() < dirtiedColumns.end()) {
         if (!m_hasMultipleCellLevels && !m_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 = endrow; r > startrow; r--) {
+                for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) {
                     unsigned row = r - 1;
-                    for (unsigned c = endcol; c > startcol; c--) {
+                    for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) {
                         unsigned col = c - 1;
                         CellStruct& current = cellAt(row, col);
                         RenderTableCell* cell = current.primaryCell();
-                        if (!cell || (row > startrow && primaryCellAt(row - 1, col) == cell) || (col > startcol && primaryCellAt(row, col - 1) == cell))
+                        if (!cell || (row > dirtiedRows.start() && primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && primaryCellAt(row, col - 1) == cell))
                             continue;
                         LayoutPoint cellPoint = flipForWritingModeForChild(cell, paintOffset);
                         cell->paintCollapsedBorders(paintInfo, cellPoint);
@@ -1071,14 +1086,14 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
                 }
             } else {
                 // Draw the dirty cells in the order that they appear.
-                for (unsigned r = startrow; r < endrow; r++) {
+                for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
                     RenderTableRow* row = m_grid[r].rowRenderer;
                     if (row && !row->hasSelfPaintingLayer())
                         row->paintOutlineForRowIfNeeded(paintInfo, paintOffset);
-                    for (unsigned c = startcol; c < endcol; c++) {
+                    for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
                         CellStruct& current = cellAt(r, c);
                         RenderTableCell* cell = current.primaryCell();
-                        if (!cell || (r > startrow && primaryCellAt(r - 1, c) == cell) || (c > startcol && primaryCellAt(r, c - 1) == cell))
+                        if (!cell || (r > dirtiedRows.start() && primaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && primaryCellAt(r, c - 1) == cell))
                             continue;
                         paintCell(cell, paintInfo, paintOffset);
                     }
@@ -1086,7 +1101,11 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
             }
         } else {
             // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet.
+#ifndef NDEBUG
+            unsigned totalRows = m_grid.size();
+            unsigned totalCols = table()->columns().size();
             ASSERT(m_overflowingCells.size() < totalRows * totalCols * gMaxAllowedOverflowingCellRatioForFastPaintPath);
+#endif
 
             // To make sure we properly repaint the section, we repaint all the overflowing cells that we collected.
             Vector<RenderTableCell*> cells;
@@ -1094,11 +1113,11 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
 
             HashSet<RenderTableCell*> spanningCells;
 
-            for (unsigned r = startrow; r < endrow; r++) {
+            for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
                 RenderTableRow* row = m_grid[r].rowRenderer;
                 if (row && !row->hasSelfPaintingLayer())
                     row->paintOutlineForRowIfNeeded(paintInfo, paintOffset);
-                for (unsigned c = startcol; c < endcol; c++) {
+                for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
                     CellStruct& current = cellAt(r, c);
                     if (!current.hasCells())
                         continue;
index d12c870..84e84eb 100644 (file)
@@ -37,6 +37,23 @@ enum CollapsedBorderSide {
     CBSEnd
 };
 
+// Helper class for paintObject.
+class CellSpan {
+public:
+    CellSpan(unsigned start, unsigned end)
+        : m_start(start)
+        , m_end(end)
+    {
+    }
+
+    unsigned start() const { return m_start; }
+    unsigned end() const { return m_end; }
+
+private:
+    unsigned m_start;
+    unsigned m_end;
+};
+
 class RenderTableCell;
 class RenderTableRow;
 
@@ -170,6 +187,12 @@ private:
 
     bool hasOverflowingCell() const { return m_overflowingCells.size() || m_forceSlowPaintPathWithOverflowingCell; }
 
+    CellSpan fullTableRowSpan() const { return CellSpan(0, m_grid.size()); }
+    CellSpan fullTableColumnSpan() const { return CellSpan(0, table()->columns().size()); }
+
+    CellSpan dirtiedRows(const LayoutRect& repaintRect) const;
+    CellSpan dirtiedColumns(const LayoutRect& repaintRect) const;
+
     RenderObjectChildList m_children;
 
     Vector<RowStruct> m_grid;