From d584f6c4d4d0979139ff16f14a48d25e08771ae6 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sat, 19 Sep 2009 12:20:42 +0200 Subject: [PATCH] Bug 514127. Draw the canvas background color on the whole canvas area instead of just the viewport when RenderDocument is called with ignore scrolling flag. r=roc --- layout/base/nsPresShell.cpp | 16 ++- layout/base/tests/Makefile.in | 1 + layout/base/tests/test_bug514127.html | 50 ++++++++ layout/generic/nsHTMLFrame.cpp | 117 +----------------- layout/generic/nsHTMLFrame.h | 172 ++++++++++++++++++++++++++ 5 files changed, 239 insertions(+), 117 deletions(-) create mode 100644 layout/base/tests/test_bug514127.html create mode 100644 layout/generic/nsHTMLFrame.h diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 07bea3313013..c5040ade303b 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -197,6 +197,7 @@ #endif #include "nsPlaceholderFrame.h" +#include "nsHTMLFrame.h" // Content viewer interfaces #include "nsIContentViewer.h" @@ -5247,12 +5248,23 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags, (aFlags & RENDER_CARET) != 0); nsDisplayList list; + nsRect canvasArea( + builder.ToReferenceFrame(rootFrame), rootFrame->GetSize()); + nsRect rect(aRect); nsIFrame* rootScrollFrame = GetRootScrollFrame(); if ((aFlags & RENDER_IGNORE_VIEWPORT_SCROLLING) && rootScrollFrame) { - nsPoint pos = GetRootScrollFrameAsScrollable()->GetScrollPosition(); + nsIScrollableFrame* rootScrollableFrame = + GetRootScrollFrameAsScrollable(); + nsPoint pos = rootScrollableFrame->GetScrollPosition(); rect.MoveBy(-pos); builder.SetIgnoreScrollFrame(rootScrollFrame); + + CanvasFrame* canvasFrame = + do_QueryFrame(rootScrollableFrame->GetScrolledFrame()); + if (canvasFrame) { + canvasArea = canvasFrame->CanvasArea(); + } } builder.SetBackgroundOnly(PR_FALSE); @@ -5262,7 +5274,7 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags, // Add the canvas background color. nsresult rv = rootFrame->PresContext()->PresShell()->AddCanvasBackgroundColorItem( - builder, list, rootFrame); + builder, list, rootFrame, &canvasArea); if (NS_SUCCEEDED(rv)) { rv = rootFrame->BuildDisplayListForStackingContext(&builder, rect, &list); diff --git a/layout/base/tests/Makefile.in b/layout/base/tests/Makefile.in index 97d00e0ccd02..fabba21e2003 100644 --- a/layout/base/tests/Makefile.in +++ b/layout/base/tests/Makefile.in @@ -78,6 +78,7 @@ _TEST_FILES = \ decoration_line_rendering.js \ test_bug495648.xul \ bug495648.rdf \ + test_bug514127.html \ $(NULL) # test_bug396024.html is currently disabled because it interacts badly with # the "You can't print-preview while the page is loading" dialog. diff --git a/layout/base/tests/test_bug514127.html b/layout/base/tests/test_bug514127.html new file mode 100644 index 000000000000..b640cc43cb13 --- /dev/null +++ b/layout/base/tests/test_bug514127.html @@ -0,0 +1,50 @@ + + + + + Test for Bug 514127 + + + + + +

Mozilla Bug 514127

+ + + + + +
+
+
+ + diff --git a/layout/generic/nsHTMLFrame.cpp b/layout/generic/nsHTMLFrame.cpp index 5927e245762b..cb95bb2a74cf 100644 --- a/layout/generic/nsHTMLFrame.cpp +++ b/layout/generic/nsHTMLFrame.cpp @@ -37,6 +37,7 @@ /* rendering object that goes directly inside the document's scrollbars */ +#include "nsHTMLFrame.h" #include "nsIServiceManager.h" #include "nsHTMLParts.h" #include "nsHTMLContainerFrame.h" @@ -70,121 +71,6 @@ #define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC -// Interface IDs - -/** - * Root frame class. - * - * The root frame is the parent frame for the document element's frame. - * It only supports having a single child frame which must be an area - * frame - */ -class CanvasFrame : public nsHTMLContainerFrame, - public nsIScrollPositionListener, - public nsICanvasFrame { -public: - CanvasFrame(nsStyleContext* aContext) - : nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE), - mAbsoluteContainer(nsGkAtoms::absoluteList) {} - - NS_DECL_QUERYFRAME - NS_DECL_FRAMEARENA_HELPERS - - // nsISupports (nsIScrollPositionListener) - NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); - - NS_IMETHOD Init(nsIContent* aContent, - nsIFrame* aParent, - nsIFrame* aPrevInFlow); - virtual void Destroy(); - - NS_IMETHOD SetInitialChildList(nsIAtom* aListName, - nsFrameList& aChildList); - NS_IMETHOD AppendFrames(nsIAtom* aListName, - nsFrameList& aFrameList); - NS_IMETHOD InsertFrames(nsIAtom* aListName, - nsIFrame* aPrevFrame, - nsFrameList& aFrameList); - NS_IMETHOD RemoveFrame(nsIAtom* aListName, - nsIFrame* aOldFrame); - - virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const; - virtual nsFrameList GetChildList(nsIAtom* aListName) const; - - virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext); - virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext); - NS_IMETHOD Reflow(nsPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); - virtual PRBool IsContainingBlock() const { return PR_TRUE; } - virtual PRBool IsFrameOfType(PRUint32 aFlags) const - { - return nsHTMLContainerFrame::IsFrameOfType(aFlags & - ~(nsIFrame::eCanContainOverflowContainers)); - } - - NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists); - - void PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt); - - // nsIScrollPositionListener - NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY); - virtual void ViewPositionDidChange(nsIScrollableView* aScrollable, - nsTArray* aConfigurations) {} - NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY); - - // nsICanvasFrame - NS_IMETHOD SetHasFocus(PRBool aHasFocus); - - /** - * Get the "type" of the frame - * - * @see nsGkAtoms::canvasFrame - */ - virtual nsIAtom* GetType() const; - - virtual nsresult StealFrame(nsPresContext* aPresContext, - nsIFrame* aChild, - PRBool aForceNormal) - { - NS_ASSERTION(!aForceNormal, "No-one should be passing this in here"); - - // CanvasFrame keeps overflow container continuations of its child - // frame in main child list - nsresult rv = nsContainerFrame::StealFrame(aPresContext, aChild, PR_TRUE); - if (NS_FAILED(rv)) { - rv = nsContainerFrame::StealFrame(aPresContext, aChild); - } - return rv; - } - -#ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; -#endif - NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, - nsIContent** aContent); - - nsRect CanvasArea() const; - -protected: - virtual PRIntn GetSkipSides() const; - - // Data members - PRPackedBool mDoPaintFocus; - nsCOMPtr mViewManager; - nsAbsoluteContainingBlock mAbsoluteContainer; - -private: - NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } - NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } -}; - - -//---------------------------------------------------------------------- nsIFrame* NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) @@ -197,6 +83,7 @@ NS_IMPL_FRAMEARENA_HELPERS(CanvasFrame) NS_IMPL_QUERY_INTERFACE1(CanvasFrame, nsIScrollPositionListener) NS_QUERYFRAME_HEAD(CanvasFrame) + NS_QUERYFRAME_ENTRY(CanvasFrame) NS_QUERYFRAME_ENTRY(nsICanvasFrame) NS_QUERYFRAME_TAIL_INHERITING(nsHTMLContainerFrame) diff --git a/layout/generic/nsHTMLFrame.h b/layout/generic/nsHTMLFrame.h new file mode 100644 index 000000000000..2110bbd9cb0a --- /dev/null +++ b/layout/generic/nsHTMLFrame.h @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * 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"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* rendering object that goes directly inside the document's scrollbars */ + +#ifndef nsHTMLFrame_h___ +#define nsHTMLFrame_h___ + + +#include "nsHTMLContainerFrame.h" +#include "nsPresContext.h" +#include "nsStyleContext.h" +#include "nsIView.h" +#include "nsIViewManager.h" +#include "nsIRenderingContext.h" +#include "nsGUIEvent.h" +#include "nsGkAtoms.h" +#include "nsIScrollPositionListener.h" +#include "nsDisplayList.h" +#include "nsAbsoluteContainingBlock.h" + +// for focus +#include "nsIScrollableView.h" +#include "nsICanvasFrame.h" + +/** + * Root frame class. + * + * The root frame is the parent frame for the document element's frame. + * It only supports having a single child frame which must be an area + * frame + */ +class CanvasFrame : public nsHTMLContainerFrame, + public nsIScrollPositionListener, + public nsICanvasFrame { +public: + CanvasFrame(nsStyleContext* aContext) + : nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE), + mAbsoluteContainer(nsGkAtoms::absoluteList) {} + + NS_DECL_QUERYFRAME_TARGET(CanvasFrame) + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS + + // nsISupports (nsIScrollPositionListener) + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + NS_IMETHOD Init(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame* aPrevInFlow); + virtual void Destroy(); + + NS_IMETHOD SetInitialChildList(nsIAtom* aListName, + nsFrameList& aChildList); + NS_IMETHOD AppendFrames(nsIAtom* aListName, + nsFrameList& aFrameList); + NS_IMETHOD InsertFrames(nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList); + NS_IMETHOD RemoveFrame(nsIAtom* aListName, + nsIFrame* aOldFrame); + + virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const; + virtual nsFrameList GetChildList(nsIAtom* aListName) const; + + virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext); + virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext); + NS_IMETHOD Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + virtual PRBool IsContainingBlock() const { return PR_TRUE; } + virtual PRBool IsFrameOfType(PRUint32 aFlags) const + { + return nsHTMLContainerFrame::IsFrameOfType(aFlags & + ~(nsIFrame::eCanContainOverflowContainers)); + } + + NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists); + + void PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt); + + // nsIScrollPositionListener + NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY); + virtual void ViewPositionDidChange(nsIScrollableView* aScrollable, + nsTArray* aConfigurations) {} + NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY); + + // nsICanvasFrame + NS_IMETHOD SetHasFocus(PRBool aHasFocus); + + /** + * Get the "type" of the frame + * + * @see nsGkAtoms::canvasFrame + */ + virtual nsIAtom* GetType() const; + + virtual nsresult StealFrame(nsPresContext* aPresContext, + nsIFrame* aChild, + PRBool aForceNormal) + { + NS_ASSERTION(!aForceNormal, "No-one should be passing this in here"); + + // CanvasFrame keeps overflow container continuations of its child + // frame in main child list + nsresult rv = nsContainerFrame::StealFrame(aPresContext, aChild, PR_TRUE); + if (NS_FAILED(rv)) { + rv = nsContainerFrame::StealFrame(aPresContext, aChild); + } + return rv; + } + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsAString& aResult) const; +#endif + NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, + nsEvent* aEvent, + nsIContent** aContent); + + nsRect CanvasArea() const; + +protected: + virtual PRIntn GetSkipSides() const; + + // Data members + PRPackedBool mDoPaintFocus; + nsCOMPtr mViewManager; + nsAbsoluteContainingBlock mAbsoluteContainer; + +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } +}; + +#endif /* nsHTMLFrame_h___ */