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

This commit is contained in:
Timothy Nikkel 2009-09-19 12:20:42 +02:00
Родитель 767df7d61e
Коммит d584f6c4d4
5 изменённых файлов: 239 добавлений и 117 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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.

Просмотреть файл

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=514127
-->
<head>
<title>Test for Bug 514127</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=514127">Mozilla Bug 514127</a></p>
<!--
iframe source is
<html><body style='background: rgb(0,0,255); width: 100px; height: 50100px;'></body></html>
-->
<iframe id="source" width="50" height="50"
src="data:text/html,%3Chtml%3E%3Cbody%20style%3D%27background%3A%20rgb%280%2C0%2C255%29%3B%20width%3A%20100px%3B%20height%3A%2050100px%3B%27%3E%3C%2Fbody%3E%3C%2Fhtml%3E"></iframe>
<canvas id="scratch" width="50" height="50"></canvas>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 514127 **/
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var canvas = document.getElementById('scratch');
var source = document.getElementById('source').contentWindow;
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawWindow(source, 25, 50000, canvas.width, canvas.height,
"transparent");
var data = context.getImageData(0, 0, canvas.width, canvas.height).data;
var failed = false;
for (var i = 0; i < data.length; i+=4) {
if (data[i] != 0 || data[i+1] != 0 || data[i+2] != 255 || data[i+3] != 255) {
failed = true;
break;
}
}
ok(!failed, "all pixels blue");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -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<nsIWidget::Configuration>* 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<nsIViewManager> 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)

Просмотреть файл

@ -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<nsIWidget::Configuration>* 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<nsIViewManager> mViewManager;
nsAbsoluteContainingBlock mAbsoluteContainer;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
#endif /* nsHTMLFrame_h___ */