Bug 579258. Change IsVaryingRelativeToMovingFrame to take the 'moving frame' as a direct parameter instead of getting it from the builder. r=tnikkel,a=joe

This commit is contained in:
Robert O'Callahan 2010-08-13 21:54:37 +12:00
parent f3d089fd38
commit b004c93cb1
6 changed files with 33 additions and 42 deletions

View File

@ -752,11 +752,9 @@ nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
}
PRBool
nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder)
nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
NS_ASSERTION(aBuilder->IsMovingFrame(mFrame),
"IsVaryingRelativeToMovingFrame called on non-moving frame!");
// theme background overrides any other background and is never fixed
if (mIsThemed)
return PR_FALSE;
@ -771,14 +769,12 @@ nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuild
if (!bg->HasFixedBackground())
return PR_FALSE;
nsIFrame* movingFrame = aBuilder->GetRootMovingFrame();
// movingFrame is the frame that is going to be moved. It must be equal
// to mFrame or some ancestor of mFrame, see assertion above.
// If mFrame is in the same document as movingFrame, then mFrame
// will move relative to its viewport, which means this display item will
// change when it is moved. If they are in different documents, we do not
// want to return true because mFrame won't move relative to its viewport.
return movingFrame->PresContext() == presContext;
// If aFrame is mFrame or an ancestor in this document, and aFrame is
// not the viewport frame, then moving aFrame will move mFrame
// relative to the viewport, so our fixed-pos background will change.
return aFrame->GetParent() &&
(aFrame == mFrame ||
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame));
}
PRBool
@ -1102,10 +1098,8 @@ PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aCo
return PR_FALSE;
}
PRBool nsDisplayWrapList::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder) {
// The only existing consumer of IsVaryingRelativeToMovingFrame is
// nsLayoutUtils::ComputeRepaintRegionForCopy, which refrains from calling
// this on wrapped lists.
PRBool nsDisplayWrapList::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) {
NS_WARNING("nsDisplayWrapList::IsVaryingRelativeToMovingFrame called unexpectedly");
// We could try to do something but let's conservatively just return PR_TRUE.
return PR_TRUE;

View File

@ -542,13 +542,13 @@ public:
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return PR_FALSE; }
/**
* @return PR_FALSE if the painting performed by the item is invariant
* when frame aFrame is moved relative to aBuilder->GetRootMovingFrame().
* when the item's underlying frame is moved relative to aFrame.
* In other words, if you render the item at locations P and P', the rendering
* only differs by the translation.
* This can only be called when aBuilder->IsMovingFrame(mFrame) is true.
* It return PR_TRUE for all wrapped lists.
*/
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder)
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{ return PR_FALSE; }
/**
* @return PR_TRUE if the contents of this item are rendered fixed relative
@ -1309,7 +1309,8 @@ public:
nsRegion* aVisibleRegion,
nsRegion* aVisibleRegionBeforeMove);
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
virtual PRBool IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
@ -1444,7 +1445,8 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,

View File

@ -176,15 +176,12 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
}
nscolor color;
nsRect vis = i->GetVisibleRect();
fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s%s%s\n",
fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n",
i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
rect.x, rect.y, rect.width, rect.height,
vis.x, vis.y, vis.width, vis.height,
i->IsOpaque(aBuilder) ? " opaque" : "",
i->IsUniform(aBuilder, &color) ? " uniform" : "",
f && aBuilder->IsMovingFrame(f) ? " moving" : "",
f && aBuilder->IsMovingFrame(f) && !i->GetList() &&
i->IsVaryingRelativeToMovingFrame(aBuilder) ? " varying" : "");
i->IsUniform(aBuilder, &color) ? " uniform" : "");
nsDisplayList* list = i->GetList();
if (list) {
PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput);

View File

@ -1525,17 +1525,18 @@ CanScrollWithBlitting(nsIFrame* aFrame, nsIFrame* aDisplayRoot)
static void
InvalidateFixedBackgroundFramesFromList(nsDisplayListBuilder* aBuilder,
nsIFrame* aMovingFrame,
const nsDisplayList& aList)
{
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
nsDisplayList* sublist = item->GetList();
if (sublist) {
InvalidateFixedBackgroundFramesFromList(aBuilder, *sublist);
InvalidateFixedBackgroundFramesFromList(aBuilder, aMovingFrame, *sublist);
continue;
}
nsIFrame* f = item->GetUnderlyingFrame();
if (f && aBuilder->IsMovingFrame(f) &&
item->IsVaryingRelativeToMovingFrame(aBuilder)) {
if (f &&
item->IsVaryingRelativeToMovingFrame(aBuilder, aMovingFrame)) {
if (item->IsFixedAndCoveringViewport(aBuilder)) {
// FrameLayerBuilder takes care of scrolling these
} else {
@ -1559,7 +1560,6 @@ InvalidateFixedBackgroundFrames(nsIFrame* aRootFrame,
// Build the 'after' display list over the whole area of interest.
nsDisplayListBuilder builder(aRootFrame, PR_FALSE, PR_TRUE);
builder.EnterPresShell(aRootFrame, aUpdateRect);
builder.SetMovingFrame(aMovingFrame);
nsDisplayList list;
nsresult rv =
aRootFrame->BuildDisplayListForStackingContext(&builder, aUpdateRect, &list);
@ -1570,7 +1570,7 @@ InvalidateFixedBackgroundFrames(nsIFrame* aRootFrame,
nsRegion visibleRegion(aUpdateRect);
list.ComputeVisibility(&builder, &visibleRegion, nsnull);
InvalidateFixedBackgroundFramesFromList(&builder, list);
InvalidateFixedBackgroundFramesFromList(&builder, aMovingFrame, list);
list.DeleteAll();
}

View File

@ -1094,20 +1094,17 @@ nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) {
}
PRBool
nsDisplayTableItem::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder)
nsDisplayTableItem::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
if (!mPartHasFixedBackground)
return PR_FALSE;
// aAncestorFrame is the frame that is going to be moved.
// Check if mFrame is equal to aAncestorFrame or aAncestorFrame is an
// ancestor of mFrame in the same document. If this is true, mFrame
// will move relative to its viewport, which means this display item will
// change when it is moved. If they are in different documents, we do not
// want to return true because mFrame won't move relative to its viewport.
nsIFrame* rootMover = aBuilder->GetRootMovingFrame();
return mFrame == rootMover ||
nsLayoutUtils::IsProperAncestorFrame(rootMover, mFrame);
// If aFrame is mFrame or an ancestor in this document, and aFrame is
// not the viewport frame, then moving aFrame will move mFrame
// relative to the viewport, so our fixed-pos background will change.
return mFrame == aFrame ||
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame);
}
/* static */ void

View File

@ -79,7 +79,8 @@ public:
nsDisplayTableItem(nsIFrame* aFrame) : nsDisplayItem(aFrame),
mPartHasFixedBackground(PR_FALSE) {}
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
// With collapsed borders, parts of the collapsed border can extend outside
// the table part frames, so allow this display element to blow out to our
// overflow rect. This is also useful for row frames that have spanning