https://bugs.webkit.org/show_bug.cgi?id=67739
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Sep 2011 00:50:24 +0000 (00:50 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Sep 2011 00:50:24 +0000 (00:50 +0000)
adjustRectForColumns is O(# of columns) when it can be O(1). Fix the slow performance of this
function by removing the loop and just computing the start and end column for a repaint rect
and uniting everything in between.

Reviewed by Dan Bernstein.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::adjustRectForColumns):

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlock.cpp

index 925291a..6d141cd 100644 (file)
@@ -1,3 +1,16 @@
+2011-09-07  David Hyatt  <hyatt@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=67739
+
+        adjustRectForColumns is O(# of columns) when it can be O(1). Fix the slow performance of this
+        function by removing the loop and just computing the start and end column for a repaint rect
+        and uniting everything in between.
+
+        Reviewed by Dan Bernstein.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::adjustRectForColumns):
+
 2011-09-07  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r94714 and r94723.
index 840330e..e3aa142 100644 (file)
@@ -4607,32 +4607,44 @@ void RenderBlock::adjustRectForColumns(LayoutRect& r) const
         return;
     
     ColumnInfo* colInfo = columnInfo();
-
-    // Begin with a result rect that is empty.
-    LayoutRect result;
     
     // Determine which columns we intersect.
     unsigned colCount = columnCount(colInfo);
     if (!colCount)
         return;
-    
-    LayoutUnit logicalLeft = logicalLeftOffsetForContent();
-    LayoutUnit currLogicalOffset = 0;
 
-    for (unsigned i = 0; i < colCount; i++) {
-        LayoutRect colRect = columnRectAt(colInfo, i);
+    // Begin with a result rect that is empty.
+    LayoutRect result;
+
+    bool isHorizontal = isHorizontalWritingMode();
+    LayoutUnit beforeBorderPadding = borderBefore() + paddingBefore();
+    LayoutUnit colHeight = colInfo->columnHeight();
+    if (!colHeight)
+        return;
+
+    LayoutUnit startOffset = max(isHorizontal ? r.y() : r.x(), beforeBorderPadding);
+    LayoutUnit endOffset = min<LayoutUnit>(isHorizontal ? r.maxY() : r.maxX(), beforeBorderPadding + colCount * colHeight);
+    
+    unsigned startColumn = (startOffset - beforeBorderPadding) / colHeight;
+    unsigned endColumn = (endOffset - beforeBorderPadding) / colHeight;
+
+    if (startColumn == endColumn) {
+        // The rect is fully contained within one column. Adjust for our offsets
+        // and repaint only that portion.
+        LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent();
+        LayoutRect colRect = columnRectAt(colInfo, startColumn);
         LayoutRect repaintRect = r;
-        if (isHorizontalWritingMode()) {
-            LayoutUnit currXOffset = colRect.x() - logicalLeft;
-            repaintRect.move(currXOffset, currLogicalOffset);
-            currLogicalOffset -= colRect.height();
-        } else {
-            LayoutUnit currYOffset = colRect.y() - logicalLeft;
-            repaintRect.move(currLogicalOffset, currYOffset);
-            currLogicalOffset -= colRect.width();
-        }
+        if (isHorizontal)
+            repaintRect.move(colRect.x() - logicalLeftOffset, -startColumn * colHeight);
+        else
+            repaintRect.move(-startColumn * colHeight, colRect.y() - logicalLeftOffset);
         repaintRect.intersect(colRect);
         result.unite(repaintRect);
+    } else {
+        // We span multiple columns. We can just unite the start and end column to get the final
+        // repaint rect.
+        result.unite(columnRectAt(colInfo, startColumn));
+        result.unite(columnRectAt(colInfo, endColumn));
     }
 
     r = result;