зеркало из https://github.com/mozilla/gecko-dev.git
Bug 488242. Make iframes with semi-transparent backgrounds work correctly by painting all canvas background colors using a dedicated fallback background color display item. r+sr=roc
This commit is contained in:
Родитель
9562cc802a
Коммит
8f1f1d1fd5
|
@ -310,8 +310,7 @@ static void PaintBackgroundLayer(nsPresContext* aPresContext,
|
|||
const nsRect& aBGClipRect,
|
||||
const nsStyleBackground& aBackground,
|
||||
const nsStyleBackground::Layer& aLayer,
|
||||
const nsStyleBorder& aBorder,
|
||||
PRBool aUsePrintSettings);
|
||||
const nsStyleBorder& aBorder);
|
||||
|
||||
static void DrawBorderImage(nsPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
|
@ -1332,9 +1331,9 @@ nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
|
|||
NS_PRECONDITION(aForFrame,
|
||||
"Frame is expected to be provided to PaintBackground");
|
||||
|
||||
const nsStyleBackground *color;
|
||||
if (!FindBackground(aPresContext, aForFrame, &color)) {
|
||||
// we don't want to bail out of moz-appearance is set on a root
|
||||
const nsStyleBackground *background;
|
||||
if (!FindBackground(aPresContext, aForFrame, &background)) {
|
||||
// We don't want to bail out if moz-appearance is set on a root
|
||||
// node. If it has a parent content node, bail because it's not
|
||||
// a root, other wise keep going in order to let the theme stuff
|
||||
// draw the background. The canvas really should be drawing the
|
||||
|
@ -1347,12 +1346,12 @@ nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
|
|||
if (!content || content->GetParent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = aForFrame->GetStyleBackground();
|
||||
|
||||
background = aForFrame->GetStyleBackground();
|
||||
}
|
||||
|
||||
PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
|
||||
aDirtyRect, aBorderArea, *color,
|
||||
aDirtyRect, aBorderArea, *background,
|
||||
*aForFrame->GetStyleBorder(), aFlags,
|
||||
aBGClipRect);
|
||||
}
|
||||
|
@ -1496,13 +1495,71 @@ SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
|||
}
|
||||
}
|
||||
|
||||
static nscolor
|
||||
DetermineBackgroundColorInternal(nsPresContext* aPresContext,
|
||||
const nsStyleBackground& aBackground,
|
||||
nsIFrame* aFrame,
|
||||
PRBool* aDrawBackgroundImage,
|
||||
PRBool* aDrawBackgroundColor,
|
||||
nsCOMPtr<imgIRequest>& aBottomImage)
|
||||
{
|
||||
*aDrawBackgroundImage = PR_TRUE;
|
||||
*aDrawBackgroundColor = PR_TRUE;
|
||||
|
||||
if (aFrame->HonorPrintBackgroundSettings()) {
|
||||
*aDrawBackgroundImage = aPresContext->GetBackgroundImageDraw();
|
||||
*aDrawBackgroundColor = aPresContext->GetBackgroundColorDraw();
|
||||
}
|
||||
|
||||
aBottomImage = aBackground.BottomLayer().mImage;
|
||||
|
||||
if (!aDrawBackgroundImage || !UseImageRequestForBackground(aBottomImage)) {
|
||||
aBottomImage = nsnull;
|
||||
}
|
||||
|
||||
nscolor bgColor;
|
||||
if (*aDrawBackgroundColor) {
|
||||
bgColor = aBackground.mBackgroundColor;
|
||||
if (NS_GET_A(bgColor) == 0)
|
||||
*aDrawBackgroundColor = PR_FALSE;
|
||||
} else {
|
||||
// If GetBackgroundColorDraw() is false, we are still expected to
|
||||
// draw color in the background of any frame that's not completely
|
||||
// transparent, but we are expected to use white instead of whatever
|
||||
// color was specified.
|
||||
bgColor = NS_RGB(255, 255, 255);
|
||||
if (*aDrawBackgroundImage || !aBackground.IsTransparent())
|
||||
*aDrawBackgroundColor = PR_TRUE;
|
||||
else
|
||||
bgColor = NS_RGBA(0,0,0,0);
|
||||
}
|
||||
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
nscolor
|
||||
nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
|
||||
const nsStyleBackground& aBackground,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
PRBool drawBackgroundImage;
|
||||
PRBool drawBackgroundColor;
|
||||
nsCOMPtr<imgIRequest> bottomImage;
|
||||
return DetermineBackgroundColorInternal(aPresContext,
|
||||
aBackground,
|
||||
aFrame,
|
||||
&drawBackgroundImage,
|
||||
&drawBackgroundColor,
|
||||
bottomImage);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsIFrame* aForFrame,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aBorderArea,
|
||||
const nsStyleBackground& aColor,
|
||||
const nsStyleBackground& aBackground,
|
||||
const nsStyleBorder& aBorder,
|
||||
PRUint32 aFlags,
|
||||
nsRect* aBGClipRect)
|
||||
|
@ -1526,35 +1583,25 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// For canvas frames (in the CSS sense) we draw the background color using
|
||||
// a solid color item that gets added in nsLayoutUtils::PaintFrame,
|
||||
// PresShell::RenderDocument, or nsSubDocumentFrame::BuildDisplayList
|
||||
// (bug 488242).
|
||||
PRBool isCanvasFrame = IsCanvasFrame(aForFrame);
|
||||
|
||||
// Determine whether we are drawing background images and/or
|
||||
// background colors.
|
||||
PRBool drawBackgroundImage = PR_TRUE;
|
||||
PRBool drawBackgroundColor = PR_TRUE;
|
||||
PRBool usePrintSettings = aForFrame->HonorPrintBackgroundSettings();
|
||||
if (usePrintSettings) {
|
||||
drawBackgroundImage = aPresContext->GetBackgroundImageDraw();
|
||||
drawBackgroundColor = aPresContext->GetBackgroundColorDraw();
|
||||
}
|
||||
PRBool drawBackgroundImage;
|
||||
PRBool drawBackgroundColor;
|
||||
|
||||
imgIRequest *bottomImage = aColor.BottomLayer().mImage;
|
||||
if (!drawBackgroundImage || !UseImageRequestForBackground(bottomImage)) {
|
||||
bottomImage = nsnull;
|
||||
}
|
||||
nsCOMPtr<imgIRequest> bottomImage;
|
||||
|
||||
// If GetBackgroundColorDraw() is false, we are still expected to
|
||||
// draw color in the background of any frame that's not completely
|
||||
// transparent, but we are expected to use white instead of whatever
|
||||
// color was specified.
|
||||
nscolor bgColor;
|
||||
if (drawBackgroundColor) {
|
||||
bgColor = aColor.mBackgroundColor;
|
||||
if (NS_GET_A(bgColor) == 0)
|
||||
drawBackgroundColor = PR_FALSE;
|
||||
} else {
|
||||
bgColor = NS_RGB(255, 255, 255);
|
||||
if (drawBackgroundImage || !aColor.IsTransparent())
|
||||
drawBackgroundColor = PR_TRUE;
|
||||
}
|
||||
nscolor bgColor = DetermineBackgroundColorInternal(aPresContext,
|
||||
aBackground,
|
||||
aForFrame,
|
||||
&drawBackgroundImage,
|
||||
&drawBackgroundColor,
|
||||
bottomImage);
|
||||
|
||||
// At this point, drawBackgroundImage and drawBackgroundColor are
|
||||
// true if and only if we are actually supposed to paint an image or
|
||||
|
@ -1603,7 +1650,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
// radii as the border code will.
|
||||
// The background-color is drawn based on the bottom
|
||||
// background-clip.
|
||||
currentBackgroundClip = aColor.BottomLayer().mClip;
|
||||
currentBackgroundClip = aBackground.BottomLayer().mClip;
|
||||
isSolidBorder =
|
||||
(aFlags & PAINT_WILL_PAINT_BORDER) && IsSolidBorder(aBorder);
|
||||
if (isSolidBorder)
|
||||
|
@ -1615,14 +1662,14 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// If we might be using a background color, go ahead and set it now.
|
||||
if (drawBackgroundColor)
|
||||
if (drawBackgroundColor && !isCanvasFrame)
|
||||
ctx->SetColor(gfxRGBA(bgColor));
|
||||
|
||||
// If there is no background image, draw a color. (If there is
|
||||
// neither a background image nor a color, we wouldn't have gotten
|
||||
// this far.)
|
||||
if (!drawBackgroundImage) {
|
||||
if (!dirtyRectGfx.IsEmpty()) {
|
||||
if (!dirtyRectGfx.IsEmpty() && !isCanvasFrame) {
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||
ctx->Fill();
|
||||
|
@ -1633,10 +1680,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
// Ensure we get invalidated for loads of the image. We need to do
|
||||
// this here because this might be the only code that knows about the
|
||||
// association of the style data with the frame.
|
||||
aPresContext->SetupBackgroundImageLoaders(aForFrame, &aColor);
|
||||
aPresContext->SetupBackgroundImageLoaders(aForFrame, &aBackground);
|
||||
|
||||
if (bottomImage &&
|
||||
aColor.BottomLayer().mRepeat == NS_STYLE_BG_REPEAT_XY &&
|
||||
aBackground.BottomLayer().mRepeat == NS_STYLE_BG_REPEAT_XY &&
|
||||
drawBackgroundColor) {
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
bottomImage->GetImage(getter_AddRefs(image));
|
||||
|
@ -1665,7 +1712,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
|
||||
// The background color is rendered over the entire dirty area,
|
||||
// even if the image isn't.
|
||||
if (drawBackgroundColor) {
|
||||
if (drawBackgroundColor && !isCanvasFrame) {
|
||||
if (!dirtyRectGfx.IsEmpty()) {
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||
|
@ -1674,8 +1721,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
if (drawBackgroundImage) {
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, &aColor) {
|
||||
const nsStyleBackground::Layer &layer = aColor.mLayers[i];
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, &aBackground) {
|
||||
const nsStyleBackground::Layer &layer = aBackground.mLayers[i];
|
||||
if (!aBGClipRect) {
|
||||
PRUint8 newBackgroundClip =
|
||||
isSolidBorder ? NS_STYLE_BG_CLIP_PADDING : layer.mClip;
|
||||
|
@ -1689,8 +1736,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
}
|
||||
if (!dirtyRectGfx.IsEmpty()) {
|
||||
PaintBackgroundLayer(aPresContext, aRenderingContext, aForFrame,
|
||||
dirtyRect, aBorderArea, bgClipArea, aColor,
|
||||
layer, aBorder, usePrintSettings);
|
||||
dirtyRect, aBorderArea, bgClipArea, aBackground,
|
||||
layer, aBorder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1705,8 +1752,7 @@ PaintBackgroundLayer(nsPresContext* aPresContext,
|
|||
const nsRect& aBGClipRect,
|
||||
const nsStyleBackground& aBackground,
|
||||
const nsStyleBackground::Layer& aLayer,
|
||||
const nsStyleBorder& aBorder,
|
||||
PRBool aUsePrintSettings)
|
||||
const nsStyleBorder& aBorder)
|
||||
{
|
||||
// Lookup the image
|
||||
imgIRequest *req = aLayer.mImage;
|
||||
|
|
|
@ -167,6 +167,14 @@ struct nsCSSRendering {
|
|||
FindNonTransparentBackground(nsStyleContext* aContext,
|
||||
PRBool aStartAtParent = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Determine the background color to draw taking into account print settings.
|
||||
*/
|
||||
static nscolor
|
||||
DetermineBackgroundColor(nsPresContext* aPresContext,
|
||||
const nsStyleBackground& aBackground,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Render the background for an element using css rendering rules
|
||||
* for backgrounds.
|
||||
|
@ -199,7 +207,7 @@ struct nsCSSRendering {
|
|||
nsIFrame* aForFrame,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aBorderArea,
|
||||
const nsStyleBackground& aColor,
|
||||
const nsStyleBackground& aBackground,
|
||||
const nsStyleBorder& aBorder,
|
||||
PRUint32 aFlags,
|
||||
nsRect* aBGClipRect = nsnull);
|
||||
|
|
|
@ -546,7 +546,8 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
|
|||
nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
|
||||
return PR_FALSE;
|
||||
|
||||
if (NS_GET_A(bg->mBackgroundColor) == 255)
|
||||
if (NS_GET_A(bg->mBackgroundColor) == 255 &&
|
||||
!nsCSSRendering::IsCanvasFrame(mFrame))
|
||||
return PR_TRUE;
|
||||
|
||||
if (bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY) {
|
||||
|
|
|
@ -125,11 +125,6 @@ public:
|
|||
* determine which frame is under the mouse position
|
||||
* @param aBuildCaret whether or not we should include the caret in any
|
||||
* display lists that we make.
|
||||
* @param aMovingFrame a frame whose subtree should be regarded as
|
||||
* moving; moving frames are not allowed to clip or cover (during
|
||||
* OptimizeVisibility) non-moving frames. E.g. when we're constructing
|
||||
* a display list to see what should be repainted during a scroll
|
||||
* operation, we specify the scrolled frame as the moving frame.
|
||||
*/
|
||||
nsDisplayListBuilder(nsIFrame* aReferenceFrame, PRBool aIsForEvents,
|
||||
PRBool aBuildCaret);
|
||||
|
@ -162,7 +157,10 @@ public:
|
|||
/**
|
||||
* Indicate that we'll use this display list to analyze the effects
|
||||
* of aMovingFrame moving by aMoveDelta. The move has already been
|
||||
* applied to the frame tree.
|
||||
* applied to the frame tree. Moving frames are not allowed to clip or
|
||||
* cover (during OptimizeVisibility) non-moving frames. E.g. when we're
|
||||
* constructing a display list to see what should be repainted during a
|
||||
* scroll operation, we specify the scrolled frame as the moving frame.
|
||||
*/
|
||||
void SetMovingFrame(nsIFrame* aMovingFrame, const nsPoint& aMoveDelta) {
|
||||
mMovingFrame = aMovingFrame;
|
||||
|
@ -512,9 +510,6 @@ protected:
|
|||
mAbove = nsnull;
|
||||
}
|
||||
|
||||
static PRBool ComputeVisibilityFromBounds(nsIFrame* aFrame,
|
||||
const nsRect& aRect, nsRegion& aCovered, PRBool aIsOpaque);
|
||||
|
||||
nsIFrame* mFrame;
|
||||
};
|
||||
|
||||
|
@ -1011,13 +1006,14 @@ public:
|
|||
|
||||
/**
|
||||
* A simple display item that just renders a solid color across the
|
||||
* specified bounds. Used in cases where we can't draw the frame tree but
|
||||
* we want to draw something to avoid an ugly flash of white when
|
||||
* navigating between pages. Also used as a bottom item to ensure that
|
||||
* something is painted everywhere. The bounds can differ from the frame's
|
||||
* bounds -- this is needed when a frame/iframe is loading and there is not
|
||||
* yet a frame tree to go in the frame/iframe so we use the subdoc frame
|
||||
* of the parent document as a standin.
|
||||
* specified bounds. For canvas frames (in the CSS sense) we split off the
|
||||
* drawing of the background color into this class (from nsDisplayBackground
|
||||
* via nsDisplayCanvasBackground). This is done so that we can always draw a
|
||||
* background color to avoid ugly flashes of white when we can't draw a full
|
||||
* frame tree (ie when a page is loading). The bounds can differ from the
|
||||
* frame's bounds -- this is needed when a frame/iframe is loading and there
|
||||
* is not yet a frame tree to go in the frame/iframe so we use the subdoc
|
||||
* frame of the parent document as a standin.
|
||||
*/
|
||||
class nsDisplaySolidColor : public nsDisplayItem {
|
||||
public:
|
||||
|
|
|
@ -98,14 +98,15 @@ class gfxASurface;
|
|||
class gfxContext;
|
||||
class nsPIDOMEventTarget;
|
||||
class nsIDOMEvent;
|
||||
class nsDisplayList;
|
||||
class nsDisplayListBuilder;
|
||||
|
||||
typedef short SelectionType;
|
||||
typedef PRUint32 nsFrameState;
|
||||
|
||||
// 189d234b-3823-4e8f-bbd2-63c0282b9fac
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x189d234b, 0x3823, 0x4e8f, \
|
||||
{ 0xbb, 0xd2, 0x63, 0xc0, 0x28, 0x2b, 0x9f, 0xac } }
|
||||
{ 0x5039364e, 0x6e3e, 0x4aae, \
|
||||
{ 0xb8, 0xac, 0xf1, 0xee, 0xf1, 0xcb, 0x85, 0x45 } }
|
||||
|
||||
// Constants for ScrollContentIntoView() function
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
|
@ -772,7 +773,7 @@ public:
|
|||
nsIntPoint& aPoint,
|
||||
nsIntRect* aScreenRect) = 0;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Renders a selection to a surface and returns it. This method is primarily
|
||||
* intended to create the drag feedback when dragging a selection.
|
||||
*
|
||||
|
@ -807,20 +808,34 @@ public:
|
|||
*/
|
||||
NS_IMETHOD DisableNonTestMouseEvents(PRBool aDisable) = 0;
|
||||
|
||||
/* Record the background color of the most recently loaded canvas.
|
||||
* This color is composited on top of the user's default background
|
||||
* color whenever we need to provide an "ultimate" background color.
|
||||
* See PresShell::Paint, PresShell::PaintDefaultBackground, and
|
||||
* nsDocShell::SetupNewViewer; bug 476557 and other bugs mentioned there.
|
||||
/**
|
||||
* Record the background color of the most recently drawn canvas. This color
|
||||
* is composited on top of the user's default background color and then used
|
||||
* to draw the background color of the canvas. See PresShell::Paint,
|
||||
* PresShell::PaintDefaultBackground, and nsDocShell::SetupNewViewer;
|
||||
* bug 488242, bug 476557 and other bugs mentioned there.
|
||||
*/
|
||||
void SetCanvasBackground(nscolor aColor) { mCanvasBackgroundColor = aColor; }
|
||||
nscolor GetCanvasBackground() { return mCanvasBackgroundColor; }
|
||||
|
||||
/* Use the current frame tree (if it exists) to update the background
|
||||
* color of the most recent canvas.
|
||||
/**
|
||||
* Use the current frame tree (if it exists) to update the background
|
||||
* color of the most recently drawn canvas.
|
||||
*/
|
||||
virtual void UpdateCanvasBackground() = 0;
|
||||
|
||||
/**
|
||||
* Add a solid color item to the bottom of aList with frame aFrame and
|
||||
* bounds aBounds. If aBounds is null (the default) then the bounds
|
||||
* will be derived from the frame. aBackstopColor is composed behind
|
||||
* the background color of the canvas, it is transparent by default.
|
||||
*/
|
||||
virtual nsresult AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
|
||||
nsDisplayList& aList,
|
||||
nsIFrame* aFrame,
|
||||
nsRect* aBounds = nsnull,
|
||||
nscolor aBackstopColor = NS_RGBA(0,0,0,0)) = 0;
|
||||
|
||||
void ObserveNativeAnonMutationsForPrint(PRBool aObserve)
|
||||
{
|
||||
mObservesMutationsForPrint = aObserve;
|
||||
|
|
|
@ -1047,7 +1047,7 @@ GetNextPage(nsIFrame* aPageContentFrame)
|
|||
|
||||
nsresult
|
||||
nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
|
||||
const nsRegion& aDirtyRegion, nscolor aBackground)
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop)
|
||||
{
|
||||
nsAutoDisableGetUsedXAssertions disableAssert;
|
||||
|
||||
|
@ -1055,11 +1055,12 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
|||
nsDisplayList list;
|
||||
nsRect dirtyRect = aDirtyRegion.GetBounds();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
builder.EnterPresShell(aFrame, dirtyRect);
|
||||
|
||||
nsresult rv =
|
||||
aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list);
|
||||
|
||||
rv = aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && aFrame->GetType() == nsGkAtoms::pageContentFrame) {
|
||||
// We may need to paint out-of-flow frames whose placeholders are
|
||||
// on other pages. Add those pages to our display list. Note that
|
||||
|
@ -1078,22 +1079,20 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
|||
}
|
||||
}
|
||||
|
||||
// For printing, this function is first called on an nsPageFrame, which
|
||||
// creates a display list with a PageContent item. The PageContent item's
|
||||
// paint function calls this function on the nsPageFrame's child which is
|
||||
// an nsPageContentFrame. We only want to add the canvas background color
|
||||
// item once, for the nsPageContentFrame.
|
||||
if (NS_SUCCEEDED(rv) && aFrame->GetType() != nsGkAtoms::pageFrame) {
|
||||
// Add the canvas background color.
|
||||
rv = aFrame->PresContext()->PresShell()->AddCanvasBackgroundColorItem(
|
||||
builder, list, aFrame, nsnull, aBackstop);
|
||||
}
|
||||
|
||||
builder.LeavePresShell(aFrame, dirtyRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (NS_GET_A(aBackground) > 0) {
|
||||
// Fill the visible area with a background color. In the common case,
|
||||
// the visible area is entirely covered by the background of the root
|
||||
// document (at least!) so this will be removed by the optimizer. In some
|
||||
// cases we might not have a root frame, so this will prevent garbage
|
||||
// from being drawn.
|
||||
rv = list.AppendNewToBottom(new (&builder) nsDisplaySolidColor(
|
||||
aFrame,
|
||||
nsRect(builder.ToReferenceFrame(aFrame), aFrame->GetSize()),
|
||||
aBackground));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gDumpPaintList) {
|
||||
fprintf(stderr, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",
|
||||
|
|
|
@ -474,11 +474,11 @@ public:
|
|||
* to pixel-aligned coordinates
|
||||
* @param aDirtyRegion the region that must be painted, in the coordinates
|
||||
* of aFrame
|
||||
* @param aBackground paint the dirty area with this color before drawing
|
||||
* @param aBackstop paint the dirty area with this color before drawing
|
||||
* the actual content; pass NS_RGBA(0,0,0,0) to draw no background
|
||||
*/
|
||||
static nsresult PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
|
||||
const nsRegion& aDirtyRegion, nscolor aBackground);
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop);
|
||||
|
||||
/**
|
||||
* @param aRootFrame the root frame of the tree to be displayed
|
||||
|
|
|
@ -1023,6 +1023,12 @@ public:
|
|||
|
||||
virtual void UpdateCanvasBackground();
|
||||
|
||||
virtual nsresult AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
|
||||
nsDisplayList& aList,
|
||||
nsIFrame* aFrame,
|
||||
nsRect* aBounds,
|
||||
nscolor aBackstopColor);
|
||||
|
||||
protected:
|
||||
virtual ~PresShell();
|
||||
|
||||
|
@ -1391,6 +1397,14 @@ private:
|
|||
void EnumeratePlugins(nsIDOMDocument *aDocument,
|
||||
const nsString &aPluginTag,
|
||||
nsPluginEnumCallback aCallback);
|
||||
|
||||
private:
|
||||
/*
|
||||
* Computes the backstop color for the view: transparent if in a transparent
|
||||
* widget, otherwise the PresContext default background color. This color is
|
||||
* only visible if the contents of the view as a whole are translucent.
|
||||
*/
|
||||
nscolor ComputeBackstopColor(nsIView* aView);
|
||||
};
|
||||
|
||||
class nsAutoCauseReflowNotifier
|
||||
|
@ -5278,7 +5292,14 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
|
|||
builder.SetBackgroundOnly(PR_FALSE);
|
||||
builder.EnterPresShell(rootFrame, rect);
|
||||
|
||||
nsresult rv = rootFrame->BuildDisplayListForStackingContext(&builder, rect, &list);
|
||||
// Add the canvas background color.
|
||||
nsresult rv =
|
||||
rootFrame->PresContext()->PresShell()->AddCanvasBackgroundColorItem(
|
||||
builder, list, rootFrame);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = rootFrame->BuildDisplayListForStackingContext(&builder, rect, &list);
|
||||
}
|
||||
|
||||
builder.LeavePresShell(rootFrame, rect);
|
||||
|
||||
|
@ -5679,6 +5700,21 @@ PresShell::RenderSelection(nsISelection* aSelection,
|
|||
aScreenRect);
|
||||
}
|
||||
|
||||
nsresult PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
|
||||
nsDisplayList& aList,
|
||||
nsIFrame* aFrame,
|
||||
nsRect* aBounds,
|
||||
nscolor aBackstopColor)
|
||||
{
|
||||
nscolor bgcolor = NS_ComposeColors(aBackstopColor, mCanvasBackgroundColor);
|
||||
nsRect bounds = aBounds == nsnull ?
|
||||
nsRect(aBuilder.ToReferenceFrame(aFrame), aFrame->GetSize()) : *aBounds;
|
||||
return aList.AppendNewToBottom(new (&aBuilder) nsDisplaySolidColor(
|
||||
aFrame,
|
||||
bounds,
|
||||
bgcolor));
|
||||
}
|
||||
|
||||
void PresShell::UpdateCanvasBackground()
|
||||
{
|
||||
// If we have a frame tree and it has style information that
|
||||
|
@ -5688,8 +5724,35 @@ void PresShell::UpdateCanvasBackground()
|
|||
if (rootFrame) {
|
||||
const nsStyleBackground* bgStyle =
|
||||
nsCSSRendering::FindRootFrameBackground(rootFrame);
|
||||
mCanvasBackgroundColor = bgStyle->mBackgroundColor;
|
||||
// XXX We should really be passing the canvasframe, not the root element
|
||||
// style frame but we don't have access to the canvasframe here. It isn't
|
||||
// a problem because only a few frames can return something other than true
|
||||
// and none of them would be a canvas frame or root element style frame.
|
||||
mCanvasBackgroundColor =
|
||||
nsCSSRendering::DetermineBackgroundColor(GetPresContext(), *bgStyle,
|
||||
rootFrame);
|
||||
}
|
||||
|
||||
// If the root element of the document (ie html) has style 'display: none'
|
||||
// then the document's background color does not get drawn; cache the
|
||||
// color we actually draw.
|
||||
if (!FrameConstructor()->GetRootElementFrame()) {
|
||||
mCanvasBackgroundColor = mPresContext->DefaultBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
nscolor PresShell::ComputeBackstopColor(nsIView* aView)
|
||||
{
|
||||
nsIWidget* widget = aView->GetNearestWidget(nsnull);
|
||||
if (widget && widget->GetTransparencyMode() != eTransparencyOpaque) {
|
||||
// Within a transparent widget, so the backstop color must be
|
||||
// totally transparent.
|
||||
return NS_RGBA(0,0,0,0);
|
||||
}
|
||||
// Within an opaque widget (or no widget at all), so the backstop
|
||||
// color must be totally opaque. The user's default background
|
||||
// as reported by the prescontext is guaranteed to be opaque.
|
||||
return GetPresContext()->DefaultBackgroundColor();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -5702,30 +5765,13 @@ PresShell::Paint(nsIView* aView,
|
|||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aView, "null view");
|
||||
|
||||
UpdateCanvasBackground();
|
||||
|
||||
// Compute the backstop color for the view.
|
||||
nscolor bgcolor;
|
||||
nsIWidget* widget = aView->GetNearestWidget(nsnull);
|
||||
if (widget && widget->GetTransparencyMode() != eTransparencyOpaque) {
|
||||
// Within a transparent widget, so the backstop color must be
|
||||
// totally transparent.
|
||||
bgcolor = NS_RGBA(0,0,0,0);
|
||||
} else {
|
||||
// Within an opaque widget (or no widget at all), so the backstop
|
||||
// color must be totally opaque. The cached canvas background
|
||||
// color is not guaranteed to be opaque, but the user's default
|
||||
// background as reported by the prescontext is. Composing the
|
||||
// former on top of the latter prevents window flashing in between
|
||||
// pages that use the same non-default background.
|
||||
bgcolor = NS_ComposeColors(mPresContext->DefaultBackgroundColor(),
|
||||
mCanvasBackgroundColor);
|
||||
}
|
||||
nscolor bgcolor = ComputeBackstopColor(aView);
|
||||
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
|
||||
if (frame) {
|
||||
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion, bgcolor);
|
||||
} else {
|
||||
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
|
||||
aRenderingContext->SetColor(bgcolor);
|
||||
aRenderingContext->FillRect(aDirtyRegion.GetBounds());
|
||||
}
|
||||
|
@ -5735,19 +5781,17 @@ PresShell::Paint(nsIView* aView,
|
|||
NS_IMETHODIMP
|
||||
PresShell::PaintDefaultBackground(nsIView* aView,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Paint);
|
||||
|
||||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aView, "null view");
|
||||
|
||||
// The view manager does not call this function if there is no
|
||||
// widget or it is transparent. We must not look at the frame tree,
|
||||
// so all we have to use is the canvas default color as set above,
|
||||
// or failing that, the user's default color.
|
||||
|
||||
nscolor bgcolor = NS_ComposeColors(mPresContext->DefaultBackgroundColor(),
|
||||
// We must not look at the frame tree, so all we have to use is the canvas
|
||||
// default color as set above.
|
||||
|
||||
nscolor bgcolor = NS_ComposeColors(ComputeBackstopColor(aView),
|
||||
mCanvasBackgroundColor);
|
||||
|
||||
aRenderingContext->SetColor(bgcolor);
|
||||
|
|
|
@ -348,8 +348,6 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
if (f) {
|
||||
dirty = aDirtyRect - f->GetOffsetTo(this);
|
||||
aBuilder->EnterPresShell(f, dirty);
|
||||
|
||||
rv = f->BuildDisplayListForStackingContext(aBuilder, dirty, &childItems);
|
||||
}
|
||||
|
||||
// Get the bounds of subdocView relative to the reference frame.
|
||||
|
@ -357,22 +355,20 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
mInnerView->GetPosition() +
|
||||
GetOffsetTo(aBuilder->ReferenceFrame());
|
||||
|
||||
if (NS_SUCCEEDED(rv) && (!f || suppressed) &&
|
||||
!aBuilder->IsForEventDelivery()) {
|
||||
// If we don't have a frame or painting of the PresShell is suppressed,
|
||||
// try to draw the default background color. (Bug 485275)
|
||||
rv = childItems.AppendNewToBottom(
|
||||
new (aBuilder) nsDisplaySolidColor(
|
||||
f ? f : this,
|
||||
shellBounds,
|
||||
presShell->GetCanvasBackground()));
|
||||
if (!aBuilder->IsForEventDelivery()) {
|
||||
// Add the canvas background color.
|
||||
rv = presShell->AddCanvasBackgroundColorItem(
|
||||
*aBuilder, childItems, f ? f : this, &shellBounds);
|
||||
}
|
||||
|
||||
if (f && NS_SUCCEEDED(rv)) {
|
||||
rv = f->BuildDisplayListForStackingContext(aBuilder, dirty, &childItems);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Clip children to the child root frame's rectangle
|
||||
rv = aLists.Content()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayClip(this, this, &childItems,
|
||||
shellBounds));
|
||||
new (aBuilder) nsDisplayClip(this, this, &childItems, shellBounds));
|
||||
}
|
||||
// delete childItems in case of OOM
|
||||
childItems.DeleteAll();
|
||||
|
|
|
@ -427,8 +427,6 @@ public:
|
|||
CanvasFrame* frame = static_cast<CanvasFrame*>(mFrame);
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(mFrame);
|
||||
nsRect bgClipRect = frame->CanvasArea() + offset;
|
||||
// XXXzw This is the only use of the bgClipRect argument. Does this
|
||||
// path need the propagation-of-root-background-to-viewport logic?
|
||||
nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
|
||||
aDirtyRect,
|
||||
nsRect(offset, mFrame->GetSize()),
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<!-- contents of iframe <html style="background-color: rgba(255,0,0,0.50196)">-->
|
||||
<iframe src="data:text/html,%3Chtml%20style%3D%22background-color%3A%20rgba%28255%2C0%2C0%2C0.50196%29%22%3E"
|
||||
style="position: absolute; top: 0; left: 0; width: 100px; height: 100px; border: none">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; width: 100px; height: 100px; background-color: rgba(255,0,0,0.50196)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 105 B |
|
@ -3,6 +3,16 @@
|
|||
== layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml
|
||||
== layers-layer-count-cascade-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
== layers-layer-count-inheritance-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
== viewport-translucent-color-1.html viewport-translucent-color-ref.html
|
||||
== viewport-translucent-color-2.html viewport-translucent-color-ref.html
|
||||
== viewport-translucent-color-3.html viewport-translucent-color-ref.html
|
||||
!= viewport-translucent-color-ref.html about:blank
|
||||
== iframe-translucent-color-1.html iframe-translucent-color-ref.html
|
||||
== translucent-color-1.html translucent-color-ref.html
|
||||
== translucent-color-2.html translucent-color-ref.html
|
||||
== translucent-color-3.html translucent-color-ref.html
|
||||
!= translucent-color-ref.html about:blank
|
||||
== root-element-display-none-1.html root-element-display-none-ref.html
|
||||
== continuous-inline-1a.html continuous-inline-1-ref.html
|
||||
== continuous-inline-1b.html continuous-inline-1-ref.html
|
||||
== continuous-inline-1c.html continuous-inline-1-ref.html
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html id="theroot" style="background-color: red" class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function dodisplaynone() {
|
||||
document.getElementById('theroot').style.display = 'none';
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", dodisplaynone, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; width: 32px; height: 32px; background-color: rgba(255,0,0,0.50196)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; width: 32px; height: 32px; background-image: url(red-128-alpha-32x32.png)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; width: 32px; height: 32px; background-color: rgb(255,0,0); opacity: 0.50196;">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<img style="position:absolute; top: 0; left: 0; width: 32px; height: 32px;" src="red-128-alpha-32x32.png">
|
||||
</img>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="background-color: rgba(255,0,0,0.50196)">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; background-image: url(red-128-alpha-32x32.png)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="background-image: url(red-128-alpha-32x32.png)">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; background-color: rgba(255,0,0,0.50196)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3841,7 +3841,9 @@ CSSParserImpl::ParseColorOpacity(PRUint8& aOpacity)
|
|||
}
|
||||
|
||||
PRUint8 value = nsStyleUtil::FloatToColorComponent(mToken.mNumber);
|
||||
NS_ASSERTION(fabs(mToken.mNumber - value/255.0f) <= 0.5f,
|
||||
// Need to compare to something slightly larger
|
||||
// than 0.5 due to floating point inaccuracies.
|
||||
NS_ASSERTION(fabs(255.0f*mToken.mNumber - value) <= 0.51f,
|
||||
"FloatToColorComponent did something weird");
|
||||
|
||||
if (!ExpectSymbol(')', PR_TRUE)) {
|
||||
|
|
|
@ -1053,18 +1053,15 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
|||
nsRect damRect =
|
||||
damIntRect.ToAppUnits(mContext->AppUnitsPerDevPixel());
|
||||
|
||||
nsIWidget* widget = view->GetNearestWidget(nsnull);
|
||||
if (widget && widget->GetTransparencyMode() == eTransparencyOpaque) {
|
||||
nsCOMPtr<nsIRenderingContext> context = event->renderingContext;
|
||||
if (!context)
|
||||
context = CreateRenderingContext(*view);
|
||||
nsCOMPtr<nsIRenderingContext> context = event->renderingContext;
|
||||
if (!context)
|
||||
context = CreateRenderingContext(*view);
|
||||
|
||||
if (context)
|
||||
mObserver->PaintDefaultBackground(view, context, damRect);
|
||||
else
|
||||
NS_WARNING("nsViewManager: no rc for default refresh");
|
||||
|
||||
if (context)
|
||||
mObserver->PaintDefaultBackground(view, context, damRect);
|
||||
else
|
||||
NS_WARNING("nsViewManager: no rc for default refresh");
|
||||
}
|
||||
|
||||
// Clients like the editor can trigger multiple
|
||||
// reflows during what the user perceives as a single
|
||||
// edit operation, so it disables view manager
|
||||
|
|
Загрузка…
Ссылка в новой задаче