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:
Timothy Nikkel 2009-07-04 21:30:59 +12:00
Родитель 9562cc802a
Коммит 8f1f1d1fd5
26 изменённых файлов: 369 добавлений и 149 удалений

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

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

Двоичные данные
layout/reftests/backgrounds/red-128-alpha-32x32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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