Bug 324896. Always paint some kind of background when we're asked to paint, for non-translucent windows. r+sr=dbaron

This commit is contained in:
roc+%cs.cmu.edu 2006-02-06 20:38:47 +00:00
parent 901266b73a
commit 1481564ee4
4 changed files with 93 additions and 20 deletions

View File

@ -441,6 +441,17 @@ public:
return NS_OK;
}
/**
* Append a new item to the bottom of the list. If the item is null we return
* NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...);
*/
nsresult AppendNewToBottom(nsDisplayItem* aItem) {
if (!aItem)
return NS_ERROR_OUT_OF_MEMORY;
AppendToBottom(aItem);
return NS_OK;
}
/**
* Append a new item to the bottom of the list. The item must be non-null
* and not already in a list.

View File

@ -611,9 +611,42 @@ nsLayoutUtils::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt)
return result;
}
/**
* A simple display item that just renders a solid color across the entire
* visible area.
*/
MOZ_DECL_CTOR_COUNTER(nsDisplaySolidColor)
class nsDisplaySolidColor : public nsDisplayItem {
public:
nsDisplaySolidColor(nsIFrame* aFrame, nscolor aColor)
: mFrame(aFrame), mColor(aColor) {
MOZ_COUNT_CTOR(nsDisplaySolidColor);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplaySolidColor() {
MOZ_COUNT_DTOR(nsDisplaySolidColor);
}
#endif
virtual nsIFrame* GetUnderlyingFrame() { return mFrame; }
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
const nsRect& aDirtyRect);
NS_DISPLAY_DECL_NAME("SolidColor")
private:
nsIFrame* mFrame;
nscolor mColor;
};
void nsDisplaySolidColor::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
{
aCtx->SetColor(mColor);
aCtx->FillRect(aDirtyRect);
}
nsresult
nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
const nsRegion& aDirtyRegion)
const nsRegion& aDirtyRegion, nscolor aBackground)
{
nsDisplayListBuilder builder(aFrame, PR_FALSE);
nsDisplayList list;
@ -622,6 +655,16 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list);
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, aBackground));
NS_ENSURE_SUCCESS(rv, rv);
}
#ifdef DEBUG
if (gDumpPaintList) {
fprintf(stderr, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",

View File

@ -329,9 +329,11 @@ public:
* is the origin of aFrame
* @param aDirtyRegion the region that must be painted, in the coordinates
* of aFrame
* @param aBackground 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);
const nsRegion& aDirtyRegion, nscolor aBackground);
/**
* @param aRootFrame the root frame of the tree to be displayed

View File

@ -5498,28 +5498,45 @@ PresShell::Paint(nsIView* aView,
NS_ASSERTION(!(nsnull == aView), "null view");
frame = NS_STATIC_CAST(nsIFrame*, aView->GetClientData());
if (nsnull != frame)
{
if (mCaret)
mCaret->EraseCaret();
nscolor backgroundColor;
mViewManager->GetDefaultBackgroundColor(&backgroundColor);
nsIView* rootView;
mViewManager->GetRootView(rootView);
if (!rootView->GetParent() && rootView->HasWidget()) {
PRBool widgetIsTranslucent;
rootView->GetWidget()->GetWindowTranslucency(widgetIsTranslucent);
if (widgetIsTranslucent) {
backgroundColor = NS_RGBA(0,0,0,0);
}
}
if (!frame) {
if (NS_GET_A(backgroundColor) > 0) {
aRenderingContext->SetColor(backgroundColor);
aRenderingContext->FillRect(aDirtyRegion.GetBounds());
}
return NS_OK;
}
if (mCaret)
mCaret->EraseCaret();
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion);
nsLayoutUtils::PaintFrame(aRenderingContext, frame, aDirtyRegion,
backgroundColor);
#ifdef NS_DEBUG
// Draw a border around the frame
if (nsIFrameDebug::GetShowFrameBorders()) {
nsRect r = frame->GetRect();
aRenderingContext->SetColor(NS_RGB(0,0,255));
aRenderingContext->DrawRect(0, 0, r.width, r.height);
}
// Draw a border around the current event target
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (aView == mCurrentTargetView)) {
aRenderingContext->SetColor(NS_RGB(128,0,128));
aRenderingContext->DrawRect(mCurrentTargetRect.x, mCurrentTargetRect.y, mCurrentTargetRect.width, mCurrentTargetRect.height);
}
#endif
// Draw a border around the frame
if (nsIFrameDebug::GetShowFrameBorders()) {
nsRect r = frame->GetRect();
aRenderingContext->SetColor(NS_RGB(0,0,255));
aRenderingContext->DrawRect(0, 0, r.width, r.height);
}
// Draw a border around the current event target
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (aView == mCurrentTargetView)) {
aRenderingContext->SetColor(NS_RGB(128,0,128));
aRenderingContext->DrawRect(mCurrentTargetRect.x, mCurrentTargetRect.y, mCurrentTargetRect.width, mCurrentTargetRect.height);
}
#endif
return rv;
}