Bug 564991. Part 44: Move IsFixedAndCoveringViewport implementation to nsDisplayBackground so it can work on any frame, not just the canvas background. r=tnikkel

This commit is contained in:
Robert O'Callahan 2010-07-16 09:08:12 +12:00
parent 42220d0841
commit 286ba76cc0
4 changed files with 50 additions and 34 deletions

View File

@ -57,6 +57,7 @@
#include "nsSVGIntegrationUtils.h"
#endif
#include "nsLayoutUtils.h"
#include "nsIScrollableFrame.h"
#include "imgIContainer.h"
#include "nsIInterfaceRequestorUtils.h"
@ -709,6 +710,10 @@ nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuild
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;
nsPresContext* presContext = mFrame->PresContext();
nsStyleContext *bgSC;
PRBool hasBG =
@ -729,6 +734,46 @@ nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuild
return movingFrame->PresContext() == presContext;
}
PRBool
nsDisplayBackground::IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder)
{
if (mIsThemed)
return PR_FALSE;
nsPresContext* presContext = mFrame->PresContext();
nsStyleContext* bgSC;
PRBool hasBG =
nsCSSRendering::FindBackground(presContext, mFrame, &bgSC);
if (!hasBG)
return PR_FALSE;
const nsStyleBackground* bg = bgSC->GetStyleBackground();
if (!bg->HasFixedBackground())
return PR_FALSE;
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
const nsStyleBackground::Layer& layer = bg->mLayers[i];
if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED &&
!layer.mImage.IsEmpty()) {
return PR_FALSE;
}
if (layer.mClip != NS_STYLE_BG_CLIP_BORDER)
return PR_FALSE;
}
if (nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
return PR_FALSE;
nsRect bounds = GetBounds(aBuilder);
nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
if (!rootScrollFrame)
return PR_FALSE;
nsIScrollableFrame* scrollable = do_QueryFrame(rootScrollFrame);
nsRect scrollport = scrollable->GetScrollPortRect() +
aBuilder->ToReferenceFrame(rootScrollFrame);
return bounds.Contains(scrollport);
}
void
nsDisplayBackground::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx) {

View File

@ -542,6 +542,8 @@ public:
/**
* @return PR_FALSE if the painting performed by the item is invariant
* when frame aFrame is moved relative to aBuilder->GetRootMovingFrame().
* 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.
*/
@ -549,8 +551,8 @@ public:
{ return PR_FALSE; }
/**
* @return PR_TRUE if the contents of this item are rendered fixed relative
* to the nearest viewport *and* they cover the viewport. Only return true
* if the contents actually vary when scrolling in the viewport.
* to the nearest viewport *and* they cover the viewport's scrollport.
* Only return true if the contents actually vary when scrolling in the viewport.
*/
virtual PRBool IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder)
{ return PR_FALSE; }
@ -1311,6 +1313,7 @@ public:
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder);
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
virtual PRBool IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)

View File

@ -249,37 +249,6 @@ nsRect nsCanvasFrame::CanvasArea() const
return result;
}
PRBool
nsDisplayCanvasBackground::IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder)
{
if (mIsThemed)
return PR_FALSE;
nsPresContext* presContext = mFrame->PresContext();
nsStyleContext* bgSC;
PRBool hasBG =
nsCSSRendering::FindBackground(presContext, mFrame, &bgSC);
NS_ASSERTION(hasBG, "This item should have been pruned if it has no real background");
if (!hasBG)
return PR_FALSE;
const nsStyleBackground* bg = bgSC->GetStyleBackground();
if (!bg->HasFixedBackground())
return PR_FALSE;
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
const nsStyleBackground::Layer& layer = bg->mLayers[i];
if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED &&
!layer.mImage.IsEmpty()) {
return PR_FALSE;
}
}
// The canvas background always covers the (scrolled) area of the
// viewport
return PR_TRUE;
}
void
nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx)

View File

@ -184,7 +184,6 @@ public:
return NS_GET_A(mExtraBackgroundColor) == 255 ||
nsDisplayBackground::IsOpaque(aBuilder);
}
virtual PRBool IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder);
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
{
nscolor background;