diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 004aea7f6fc..fb374dfbf6b 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -3028,35 +3028,6 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, aResult.y = y; } -// Returns the root scrollable frame, which is the first child of the root -// frame. -static nsIScrollableFrame* -GetRootScrollableFrame(nsPresContext* aPresContext, nsIFrame* aRootFrame) -{ - nsIScrollableFrame* scrollableFrame = nsnull; - - if (nsGkAtoms::viewportFrame == aRootFrame->GetType()) { - nsIFrame* childFrame = aRootFrame->GetFirstChild(nsnull); - - if (childFrame) { - if (nsGkAtoms::scrollFrame == childFrame->GetType()) { - // Use this frame, even if we are using GFX frames for the - // viewport, which contains another scroll frame below this - // frame, since the GFX scrollport frame does not implement - // nsIScrollableFrame. - CallQueryInterface(childFrame, &scrollableFrame); - } - } - } -#ifdef DEBUG - else { - NS_WARNING("aRootFrame is not a viewport frame"); - } -#endif // DEBUG - - return scrollableFrame; -} - const nsStyleBackground* nsCSSRendering::FindNonTransparentBackground(nsStyleContext* aContext, PRBool aStartAtParent /*= PR_FALSE*/) @@ -3604,44 +3575,32 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, // relative to the origin of aForFrame nsPoint anchor; if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { - // If it's a fixed background attachment, then the image is placed - // relative to the viewport - nsIView* viewportView = nsnull; - nsRect viewportArea; + // If it's a fixed background attachment, then the image is placed + // relative to the viewport, which is the area of the root frame + // in a screen context or the page content frame in a print context. // Remember that we've drawn position-varying content in this prescontext aPresContext->SetRenderedPositionVaryingContent(); - nsIFrame* rootFrame = + nsIFrame* topFrame = aPresContext->PresShell()->FrameManager()->GetRootFrame(); - NS_ASSERTION(rootFrame, "no root frame"); - + NS_ASSERTION(topFrame, "no root frame"); if (aPresContext->IsPaginated()) { - nsIFrame* page = nsLayoutUtils::GetPageFrame(aForFrame); - NS_ASSERTION(page, "no page"); - rootFrame = page; + nsIFrame* pageContentFrame = + nsLayoutUtils::GetClosestFrameOfType(aForFrame, nsGkAtoms::pageContentFrame); + if (pageContentFrame) { + topFrame = pageContentFrame; + } + // else this is an embedded shell and its root frame is what we want } - viewportView = rootFrame->GetView(); - NS_ASSERTION(viewportView, "no viewport view"); - viewportArea = viewportView->GetBounds(); - viewportArea.x = 0; - viewportArea.y = 0; - - nsIScrollableFrame* scrollableFrame = - GetRootScrollableFrame(aPresContext, rootFrame); - - if (scrollableFrame) { - nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes(); - viewportArea.Deflate(scrollbars); - } - - // Get the anchor point, relative to rootFrame + // Get the anchor point, relative to the viewport. + nsRect viewportArea = topFrame->GetRect(); ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor); - // Convert the anchor point from viewport coordinates (relative to aRootFrame) to - // relative to aForFrame - anchor -= aForFrame->GetOffsetTo(rootFrame); + // Convert the anchor point from viewport coordinates to aForFrame + // coordinates. + anchor -= aForFrame->GetOffsetTo(topFrame); } else { if (frameType == nsGkAtoms::canvasFrame) { // If the frame is the canvas, the image is placed relative to diff --git a/mozilla/layout/base/nsLayoutUtils.cpp b/mozilla/layout/base/nsLayoutUtils.cpp index 9e8297481f3..6ba589bba91 100644 --- a/mozilla/layout/base/nsLayoutUtils.cpp +++ b/mozilla/layout/base/nsLayoutUtils.cpp @@ -22,6 +22,7 @@ * * Contributor(s): * L. David Baron , Mozilla Corporation + * Mats Palmgren * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -185,10 +186,10 @@ nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame) // static nsIFrame* -nsLayoutUtils::GetPageFrame(nsIFrame* aFrame) +nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType) { for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) { - if (frame->GetType() == nsGkAtoms::pageFrame) { + if (frame->GetType() == aFrameType) { return frame; } } diff --git a/mozilla/layout/base/nsLayoutUtils.h b/mozilla/layout/base/nsLayoutUtils.h index c5e22d899da..24d860bffc5 100644 --- a/mozilla/layout/base/nsLayoutUtils.h +++ b/mozilla/layout/base/nsLayoutUtils.h @@ -22,6 +22,7 @@ * Contributor(s): * Boris Zbarsky (original author) * L. David Baron , Mozilla Corporation + * Mats Palmgren * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -91,13 +92,27 @@ public: /** * Given a frame, search up the frame tree until we find an - * ancestor "Page" frame, if any. + * ancestor that (or the frame itself) is of type aFrameType, if any. * - * @param the frame to start at + * @param aFrame the frame to start at + * @param aFrameType the frame type to look for + * @return a frame of the given type or nsnull if no + * such ancestor exists + */ + static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType); + + /** + * Given a frame, search up the frame tree until we find an + * ancestor that (or the frame itself) is a "Page" frame, if any. + * + * @param aFrame the frame to start at * @return a frame of type nsGkAtoms::pageFrame or nsnull if no * such ancestor exists */ - static nsIFrame* GetPageFrame(nsIFrame* aFrame); + static nsIFrame* GetPageFrame(nsIFrame* aFrame) + { + return GetClosestFrameOfType(aFrame, nsGkAtoms::pageFrame); + } /** * IsGeneratedContentFor returns PR_TRUE if aFrame is generated