Bug 467459: make sure PresShell::Paint() uses an opaque color for the backstop; r+sr=roc

This commit is contained in:
Zack Weinberg 2008-12-13 17:07:08 +01:00
parent 106c4c79e3
commit d2971a102c

View File

@ -5409,41 +5409,54 @@ PresShell::Paint(nsIView* aView,
const nsRegion& aDirtyRegion)
{
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Paint);
nsIFrame* frame;
nsresult rv = NS_OK;
if (mIsDestroying) {
NS_ASSERTION(PR_FALSE, "A paint message was dispatched to a destroyed PresShell");
return NS_OK;
}
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
NS_ASSERTION(aView, "null view");
NS_ASSERTION(!(nsnull == aView), "null view");
// Compute the backstop color for the view. This color must be
// totally transparent if the view is within a glass or transparent
// widget; otherwise, we compose all the view managers' default
// background colors in order to get something completely opaque.
// Nested view managers might not have an opaque default, but the
// root view manager must. See bug 467459.
frame = static_cast<nsIFrame*>(aView->GetClientData());
PRBool needTransparency = PR_FALSE;
nsIViewManager *lastMgr = mViewManager;
nscolor backgroundColor;
mViewManager->GetDefaultBackgroundColor(&backgroundColor);
lastMgr->GetDefaultBackgroundColor(&backgroundColor);
for (nsIView *view = aView; view; view = view->GetParent()) {
if (view->HasWidget()) {
// Both glass and transparent windows need the transparent bg color
if (eTransparencyOpaque != view->GetWidget()->GetTransparencyMode()) {
backgroundColor = NS_RGBA(0,0,0,0);
break;
if (view->HasWidget() &&
view->GetWidget()->GetTransparencyMode() != eTransparencyOpaque) {
backgroundColor = NS_RGBA(0,0,0,0);
needTransparency = PR_TRUE;
break;
}
if (NS_GET_A(backgroundColor) < 255) {
nsIViewManager *thisMgr = view->GetViewManager();
NS_ASSERTION(thisMgr, "view without view manager");
if (lastMgr != thisMgr) {
nscolor underColor;
thisMgr->GetDefaultBackgroundColor(&underColor);
backgroundColor = NS_ComposeColors(underColor, backgroundColor);
lastMgr = thisMgr;
}
}
}
NS_ASSERTION(needTransparency || NS_GET_A(backgroundColor) == 255,
"root view manager's default background isn't opaque");
if (!frame) {
if (NS_GET_A(backgroundColor) > 0) {
aRenderingContext->SetColor(backgroundColor);
aRenderingContext->FillRect(aDirtyRegion.GetBounds());
}
return NS_OK;
nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
if (frame) {
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion,
backgroundColor);
} else if (NS_GET_A(backgroundColor) > 0) {
aRenderingContext->SetColor(backgroundColor);
aRenderingContext->FillRect(aDirtyRegion.GetBounds());
}
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion,
backgroundColor);
return rv;
return NS_OK;
}
nsIFrame*