[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

hyatt at apple.com hyatt at apple.com
Wed Dec 22 15:17:02 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 7f00156b56468256c47694fd74a192ecdc1f60c0
Author: hyatt at apple.com <hyatt at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Oct 29 20:25:42 2010 +0000

    https://bugs.webkit.org/show_bug.cgi?id=48444
    
    Reviewed by Adam Roben.
    
    Fix the dirty rect checks in RenderBoxLineList, InlineFlowBox, InlineTextBox.  They were still assuming horizontal-tb writing-mode.
    This patch makes the checks directionally abstract and also refactors the checks in RenderLineBoxList to share code.
    
    No tests yet, since the invalidation code for inlines still assumes horizontal-tb.  That will be fixed in a follow-up bug,
    and then repaint tests will be easy to write.
    
    * rendering/InlineBox.cpp:
    (WebCore::InlineBox::adjustForFlippedBlocksWritingMode):
    * rendering/InlineBox.h:
    * rendering/InlineFlowBox.cpp:
    (WebCore::InlineFlowBox::paint):
    * rendering/InlineTextBox.cpp:
    (WebCore::InlineTextBox::paint):
    * rendering/RenderBox.cpp:
    (WebCore::RenderBox::convertFromFlippedWritingMode):
    * rendering/RenderBox.h:
    * rendering/RenderLineBoxList.cpp:
    (WebCore::RenderLineBoxList::rangeIntersectsDirtyRect):
    (WebCore::RenderLineBoxList::anyLineIntersectsDirtyRect):
    (WebCore::RenderLineBoxList::lineIntersectsDirtyRect):
    (WebCore::RenderLineBoxList::paint):
    (WebCore::RenderLineBoxList::hitTest):
    * rendering/RenderLineBoxList.h:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70917 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 089e42c..825fe57 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2010-10-29  David Hyatt  <hyatt at apple.com>
+
+        Reviewed by Adam Roben.
+
+        https://bugs.webkit.org/show_bug.cgi?id=48444
+
+        Fix the dirty rect checks in RenderBoxLineList, InlineFlowBox, InlineTextBox.  They were still assuming horizontal-tb writing-mode.
+        This patch makes the checks directionally abstract and also refactors the checks in RenderLineBoxList to share code. 
+
+        No tests yet, since the invalidation code for inlines still assumes horizontal-tb.  That will be fixed in a follow-up bug,
+        and then repaint tests will be easy to write.
+
+        * rendering/InlineBox.cpp:
+        (WebCore::InlineBox::adjustForFlippedBlocksWritingMode):
+        * rendering/InlineBox.h:
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::paint):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paint):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::convertFromFlippedWritingMode):
+        * rendering/RenderBox.h:
+        * rendering/RenderLineBoxList.cpp:
+        (WebCore::RenderLineBoxList::rangeIntersectsDirtyRect):
+        (WebCore::RenderLineBoxList::anyLineIntersectsDirtyRect):
+        (WebCore::RenderLineBoxList::lineIntersectsDirtyRect):
+        (WebCore::RenderLineBoxList::paint):
+        (WebCore::RenderLineBoxList::hitTest):
+        * rendering/RenderLineBoxList.h:
+
 2010-10-29  Patrick Gansterer  <paroga at webkit.org>
 
         Reviewed by Adam Roben.
diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp
index c8236b1..1ce68f9 100644
--- a/WebCore/rendering/InlineBox.cpp
+++ b/WebCore/rendering/InlineBox.cpp
@@ -291,6 +291,18 @@ void InlineBox::adjustForFlippedBlocksWritingMode(IntPoint& point)
         point.setX(block->width() - width() - point.x());
 }
 
+void InlineBox::adjustForFlippedBlocksWritingMode(IntRect& rect)
+{
+    if (!renderer()->style()->isFlippedBlocksWritingMode())
+        return;
+    
+    RenderBlock* block = root()->block();
+    if (block->style()->isHorizontalWritingMode())
+        rect.setY(block->height() - rect.bottom());
+    else
+        rect.setX(block->width() - rect.right());
+}
+
 } // namespace WebCore
 
 #ifndef NDEBUG
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
index c3f89e0..1e4b8bf 100644
--- a/WebCore/rendering/InlineBox.h
+++ b/WebCore/rendering/InlineBox.h
@@ -291,6 +291,7 @@ public:
     }
 
     void adjustForFlippedBlocksWritingMode(IntPoint&);
+    void adjustForFlippedBlocksWritingMode(IntRect&);
 
 private:
     InlineBox* m_next; // The next element on the same line as us.
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 2fec0ac..d165231 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -681,6 +681,7 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, int tx, int ty)
 {
     IntRect overflowRect(visibleOverflowRect());
     overflowRect.inflate(renderer()->maximalOutlineSize(paintInfo.phase));
+    adjustForFlippedBlocksWritingMode(overflowRect);
     overflowRect.move(tx, ty);
     
     if (!paintInfo.rect.intersects(overflowRect))
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 909e491..43b025a 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -392,11 +392,15 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
 
     // FIXME: Technically we're potentially incorporating other visual overflow that had nothing to do with us.
     // Would it be simpler to just check our own shadow and stroke overflow by hand here?
-    int leftOverflow = parent()->x() - parent()->leftVisualOverflow();
-    int rightOverflow = parent()->rightVisualOverflow() - (parent()->x() + parent()->logicalWidth());
-    int xPos = tx + m_x - leftOverflow;
-    int w = logicalWidth() + leftOverflow + rightOverflow;
-    if (xPos >= paintInfo.rect.right() || xPos + w <= paintInfo.rect.x())
+    int logicalLeftOverflow = parent()->logicalLeft() - parent()->logicalLeftVisualOverflow();
+    int logicalRightOverflow = parent()->logicalRightVisualOverflow() - (parent()->logicalLeft() + parent()->logicalWidth());
+    int logicalStart = logicalLeft() - logicalLeftOverflow + (isVertical() ? ty : tx);
+    int logicalExtent = logicalWidth() + logicalLeftOverflow + logicalRightOverflow;
+    
+    int paintEnd = isVertical() ? paintInfo.rect.bottom() : paintInfo.rect.right();
+    int paintStart = isVertical() ? paintInfo.rect.y() : paintInfo.rect.x();
+    
+    if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
         return;
 
     bool isPrinting = textRenderer()->document()->printing();
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index b5a7328..35e597f 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -3211,6 +3211,13 @@ void RenderBox::adjustForFlippedBlocksWritingMode(RenderBox* child, IntPoint& po
         point.move(width() - child->width() - child->x() - (adjustment == ParentToChildFlippingAdjustment ? child->x() : 0), 0);
 }
 
+int RenderBox::convertFromFlippedWritingMode(int logicalPosition)
+{
+    if (!style()->isFlippedBlocksWritingMode())
+        return logicalPosition;
+    return logicalHeight() - logicalPosition;
+}
+
 IntSize RenderBox::locationOffsetIncludingFlipping()
 {
     if (!parent() || !parent()->isBox())
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 4d8e82b..7854116 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -379,6 +379,7 @@ public:
 
     enum FlippingAdjustment { ChildToParentFlippingAdjustment, ParentToChildFlippingAdjustment };
     void adjustForFlippedBlocksWritingMode(RenderBox* child, IntPoint&, FlippingAdjustment);
+    int convertFromFlippedWritingMode(int position);
     IntSize locationOffsetIncludingFlipping();
 
 protected:
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 20b6004..e5fc791 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -145,6 +145,57 @@ void RenderLineBoxList::dirtyLineBoxes()
         curr->dirtyLineBoxes();
 }
 
+bool RenderLineBoxList::rangeIntersectsDirtyRect(RenderBoxModelObject* renderer, int logicalTop, int logicalBottom, const PaintInfo& paintInfo, int tx, int ty) const
+{
+    RenderBox* block;
+    if (renderer->isBox())
+        block = toRenderBox(renderer);
+    else
+        block = renderer->containingBlock();
+    int physicalStart = block->convertFromFlippedWritingMode(logicalTop);
+    int physicalEnd = block->convertFromFlippedWritingMode(logicalBottom);
+    int physicalExtent = abs(physicalEnd - physicalStart);
+    physicalStart = min(physicalStart, physicalEnd);
+    
+    if (renderer->style()->isHorizontalWritingMode()) {
+        physicalStart += ty;
+        if (physicalStart >= paintInfo.rect.bottom() || physicalStart + physicalExtent <= paintInfo.rect.y())
+            return false;
+    } else {
+        physicalStart += tx;
+        if (physicalStart >= paintInfo.rect.right() || physicalStart + physicalExtent <= paintInfo.rect.x())
+            return false;
+    }
+    
+    return true;
+}
+
+bool RenderLineBoxList::anyLineIntersectsDirtyRect(RenderBoxModelObject* renderer, const PaintInfo& paintInfo, int tx, int ty, bool usePrintRect) const
+{
+    // We can check the first box and last box and avoid painting if we don't
+    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
+    // FIXME: This check is flawed in the following extremely obscure way:
+    // if some line in the middle has a huge overflow, it might actually extend below the last line.
+    int firstLineTop = firstLineBox()->topVisibleOverflow();
+    if (usePrintRect && !firstLineBox()->parent())
+        firstLineTop = min(firstLineTop, firstLineBox()->root()->lineTop());
+    int lastLineBottom = lastLineBox()->bottomVisibleOverflow();
+    if (usePrintRect && !lastLineBox()->parent())
+        lastLineBottom = max(lastLineBottom, lastLineBox()->root()->lineBottom());
+    int logicalTop = firstLineTop - renderer->maximalOutlineSize(paintInfo.phase);
+    int logicalBottom = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBottom;
+    
+    return rangeIntersectsDirtyRect(renderer, logicalTop, logicalBottom, paintInfo, tx, ty);
+}
+
+bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer, InlineFlowBox* box, const PaintInfo& paintInfo, int tx, int ty) const
+{
+    int logicalTop = min(box->topVisibleOverflow(), box->root()->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase);
+    int logicalBottom = box->bottomVisibleOverflow() + renderer->maximalOutlineSize(paintInfo.phase);
+    
+    return rangeIntersectsDirtyRect(renderer, logicalTop, logicalBottom, paintInfo, tx, ty);
+}
+
 void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintInfo, int tx, int ty) const
 {
     // Only paint during the foreground/selection phases.
@@ -164,20 +215,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
     RenderView* v = renderer->view();
     bool usePrintRect = !v->printRect().isEmpty();
     
-    // We can check the first box and last box and avoid painting if we don't
-    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
-    // FIXME: This check is flawed in the following extremely obscure way:
-    // if some line in the middle has a huge overflow, it might actually extend below the last line.
-    int firstLineTop = firstLineBox()->topVisibleOverflow();
-    if (usePrintRect && !firstLineBox()->parent())
-        firstLineTop = min(firstLineTop, firstLineBox()->root()->lineTop());
-    int lastLineBottom = lastLineBox()->bottomVisibleOverflow();
-    if (usePrintRect && !lastLineBox()->parent())
-        lastLineBottom = max(lastLineBottom, lastLineBox()->root()->lineBottom());
-    int yPos = firstLineTop - renderer->maximalOutlineSize(paintInfo.phase);
-    int h = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBottom - yPos;
-    yPos += ty;
-    if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
+    if (!anyLineIntersectsDirtyRect(renderer, paintInfo, tx, ty, usePrintRect))
         return;
 
     PaintInfo info(paintInfo);
@@ -189,11 +227,9 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
     // based off positions of our first line box or our last line box.
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         if (usePrintRect) {
-            // FIXME: This is a feeble effort to avoid splitting a line across two pages.
-            // It is utterly inadequate, and this should not be done at paint time at all.
-            // The whole way objects break across pages needs to be redone.
-            // Try to avoid splitting a line vertically, but only if it's less than the height
-            // of the entire page.
+            // FIXME: This is the deprecated pagination model that is still needed
+            // for embedded views inside AppKit.  AppKit is incapable of paginating vertical
+            // text pages, so we don't have to deal with vertical lines at all here.
             int topForPaginationCheck = curr->topVisibleOverflow();
             int bottomForPaginationCheck = curr->bottomVisibleOverflow();
             if (!curr->parent()) {
@@ -216,11 +252,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
             }
         }
 
-        int top = min(curr->topVisibleOverflow(), curr->root()->selectionTop()) - renderer->maximalOutlineSize(info.phase);
-        int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase);
-        h = bottom - top;
-        yPos = ty + top;
-        if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
+        if (lineIntersectsDirtyRect(renderer, curr, info, tx, ty))
             curr->paint(info, tx, ty);
     }
 
@@ -265,7 +297,7 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
     // based off positions of our first line box or our last line box.
     for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
         if (logicalPointEnd >= offset + curr->root()->logicalTopVisibleOverflow()
-         && logicalPointStart < offset + curr->root()->logicalBottomVisibleOverflow()) {
+            && logicalPointStart < offset + curr->root()->logicalBottomVisibleOverflow()) {
             bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
             if (inside) {
                 renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty));
diff --git a/WebCore/rendering/RenderLineBoxList.h b/WebCore/rendering/RenderLineBoxList.h
index f7d9960..9ffacdf 100644
--- a/WebCore/rendering/RenderLineBoxList.h
+++ b/WebCore/rendering/RenderLineBoxList.h
@@ -67,6 +67,10 @@ public:
     bool hitTest(RenderBoxModelObject*, const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction) const;
     
 private:
+    bool anyLineIntersectsDirtyRect(RenderBoxModelObject*, const PaintInfo&, int x, int y, bool usePrintRect) const;
+    bool lineIntersectsDirtyRect(RenderBoxModelObject*, InlineFlowBox*, const PaintInfo&, int x, int y) const;
+    bool rangeIntersectsDirtyRect(RenderBoxModelObject*, int logicalTop, int logicalBottom, const PaintInfo&, int x, int y) const;
+
     // For block flows, each box represents the root inline box for a line in the
     // paragraph.
     // For inline flows, each box represents a portion of that inline.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list