[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