From 418b92e9d58b3fa0727b07be2bec81e0b2d9ac21 Mon Sep 17 00:00:00 2001 From: "darin%netscape.com" Date: Tue, 25 Mar 2003 00:07:00 +0000 Subject: [PATCH] backing out roc+%cs.cmu.edu check-in for bug 113232 git-svn-id: svn://10.0.0.236/trunk@140172 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/public/nsIBlender.h | 9 - mozilla/gfx/src/nsBlender.cpp | 171 +------- mozilla/gfx/src/nsBlender.h | 3 - mozilla/layout/base/nsCSSRendering.cpp | 58 +-- mozilla/layout/generic/nsContainerFrame.cpp | 31 +- .../layout/html/base/src/nsContainerFrame.cpp | 31 +- .../layout/html/style/src/nsCSSRendering.cpp | 58 +-- mozilla/view/src/nsViewManager.cpp | 367 +++++++----------- mozilla/view/src/nsViewManager.h | 22 +- mozilla/widget/public/nsIWidget.h | 38 -- mozilla/widget/src/gtk/nsWindow.cpp | 253 ++---------- mozilla/widget/src/gtk/nsWindow.h | 50 +-- mozilla/widget/src/xpwidgets/nsBaseWidget.cpp | 20 - mozilla/widget/src/xpwidgets/nsBaseWidget.h | 3 - mozilla/xpfe/appshell/src/nsXULWindow.cpp | 20 - mozilla/xpfe/appshell/src/nsXULWindow.h | 1 - 16 files changed, 254 insertions(+), 881 deletions(-) diff --git a/mozilla/gfx/public/nsIBlender.h b/mozilla/gfx/public/nsIBlender.h index ea5e4076c2d..2ee3fe77db1 100644 --- a/mozilla/gfx/public/nsIBlender.h +++ b/mozilla/gfx/public/nsIBlender.h @@ -95,15 +95,6 @@ public: nsIRenderingContext *aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity, nsIRenderingContext *aSecondSrc = nsnull, nscolor aSrcBackColor = NS_RGB(0, 0, 0), nscolor aSecondSrcBackColor = NS_RGB(0, 0, 0)) = 0; - - /** - GetAlphas computes an array of alpha values for a rectangle of pixels, using - the drawn-onto-black and the drawn-onto-white images. The pixels are - returned in a new'ed array of aRect.width*aRect.height elements, in row-major - order. This array must be freed by the caller with delete[]. - */ - NS_IMETHOD GetAlphas(const nsRect& aRect, nsDrawingSurface aBlack, - nsDrawingSurface aWhite, PRUint8** aAlphas) = 0; }; #endif diff --git a/mozilla/gfx/src/nsBlender.cpp b/mozilla/gfx/src/nsBlender.cpp index 915680885dd..3f3c112306d 100644 --- a/mozilla/gfx/src/nsBlender.cpp +++ b/mozilla/gfx/src/nsBlender.cpp @@ -75,7 +75,6 @@ NS_IMPL_ISUPPORTS1(nsBlender, nsIBlender); #define BLEND_RED_SHIFT 7 #define BLEND_GREEN_SHIFT 2 #define BLEND_BLUE_SHIFT 3 -#define BLEND_GREEN_BITS 5 #else // XP_WIN, XP_UNIX, ??? @@ -88,7 +87,6 @@ NS_IMPL_ISUPPORTS1(nsBlender, nsIBlender); #define BLEND_RED_SHIFT 8 #define BLEND_GREEN_SHIFT 3 #define BLEND_BLUE_SHIFT 3 -#define BLEND_GREEN_BITS 6 #endif @@ -104,10 +102,6 @@ nsBlender::Init(nsIDeviceContext *aContext) return NS_OK; } -#define RED16(x) (((x) & BLEND_RED_MASK) >> BLEND_RED_SHIFT) -#define GREEN16(x) (((x) & BLEND_GREEN_MASK) >> BLEND_GREEN_SHIFT) -#define BLUE16(x) (((x) & BLEND_BLUE_MASK) << BLEND_BLUE_SHIFT) - static void rangeCheck(nsIDrawingSurface* surface, PRInt32& aX, PRInt32& aY, PRInt32& aWidth, PRInt32& aHeight) { PRUint32 width, height; @@ -234,166 +228,6 @@ NS_IMETHODIMP nsBlender::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aSecondSrcBackColor); } -#ifndef MOZ_XUL -NS_IMETHODIMP nsBlender::GetAlphas(const nsRect& aRect, nsDrawingSurface aBlack, - nsDrawingSurface aWhite, PRUint8** aAlphas) { - NS_ERROR("GetAlphas not implemented because XUL support not built"); - return NS_ERROR_NOT_IMPLEMENTED; -} -#else -/** - * Let A be the unknown source pixel's alpha value and let C be its (unknown) color. - * Let S be the value painted onto black and T be the value painted onto white. - * Then S = C*(A/255) and T = 255*(1 - A/255) + C*(A/255). - * Therefore A = 255 - (T - S) - * This is true no matter what color component we look at. - */ -static void ComputeAlphasByByte(PRInt32 aNumLines, PRInt32 aBytesPerLine, - PRInt32 aBytesPerPixel, - PRUint8 *aOnBlackImage, PRUint8 *aOnWhiteImage, - PRInt32 aBytesLineSpan, PRUint8 *aAlphas) -{ - NS_ASSERTION(aBytesPerPixel == 3 || aBytesPerPixel == 4, - "Only 24 or 32 bits per pixel supported here"); - - PRIntn y; - for (y = 0; y < aNumLines; y++) { - // Look at component #1. It must be a real color no matter what - // RGBA ordering is used. - PRUint8 *s1 = aOnBlackImage + 1; - PRUint8 *s2 = aOnWhiteImage + 1; - - PRIntn i; - for (i = 1; i < aBytesPerLine; i += aBytesPerPixel) { - *aAlphas++ = (PRUint8)(255 - (*s2 - *s1)); - s1 += aBytesPerPixel; - s2 += aBytesPerPixel; - } - - aOnBlackImage += aBytesLineSpan; - aOnWhiteImage += aBytesLineSpan; - } -} - -/** Use the green channel to work out the alpha value, - since green has the most bits in most divisions of 16-bit color. - - The green values range from 0 to (1 << BLEND_GREEN_BITS) - 1. - Therefore we multiply a green value by 255/((1 << BLEND_GREEN_BITS) - 1) - to get a real alpha value. -*/ -static void ComputeAlphas16(PRInt32 aNumLines, PRInt32 aBytesPerLine, - PRUint8 *aOnBlackImage, PRUint8 *aOnWhiteImage, - PRInt32 aBytesLineSpan, PRUint8 *aAlphas) -{ - PRIntn y; - for (y = 0; y < aNumLines; y++) { - PRUint16 *s1 = (PRUint16*)aOnBlackImage; - PRUint16 *s2 = (PRUint16*)aOnWhiteImage; - - // GREEN16 returns a value between 0 and 255 representing the - // green value of the pixel. It only has BLEND_GREEN_BITS of - // precision (so the values are typically 0, 8, 16, ..., 248). - // If we just used the GREEN16 values - // directly in the same equations that we use for the 24-bit case, - // we'd lose because (e.g.) a completely transparent pixel would - // have GREEN16(pix1) = 0, GREEN16(pix2) = 248, and the resulting - // alpha value would just be 248, but we need 255. So we need to - // do some rescaling. - const PRUint32 SCALE_DENOMINATOR = // usually 248 - ((1 << BLEND_GREEN_BITS) - 1) << (8 - BLEND_GREEN_BITS); - - PRIntn i; - for (i = 0; i < aBytesPerLine; i += 2) { - PRUint32 pix1 = GREEN16(*s1); - PRUint32 pix2 = GREEN16(*s2); - *aAlphas++ = (PRUint8)(255 - ((pix2 - pix1)*255)/SCALE_DENOMINATOR); - s1++; - s2++; - } - - aOnBlackImage += aBytesLineSpan; - aOnWhiteImage += aBytesLineSpan; - } -} - -static void ComputeAlphas(PRInt32 aNumLines, PRInt32 aBytesPerLine, - PRInt32 aDepth, - PRUint8 *aOnBlackImage, PRUint8 *aOnWhiteImage, - PRInt32 aBytesLineSpan, PRUint8 *aAlphas, - PRUint32 aAlphasSize) -{ - switch (aDepth) { - case 32: - case 24: - ComputeAlphasByByte(aNumLines, aBytesPerLine, aDepth/8, - aOnBlackImage, aOnWhiteImage, - aBytesLineSpan, aAlphas); - break; - - case 16: - ComputeAlphas16(aNumLines, aBytesPerLine, aOnBlackImage, aOnWhiteImage, - aBytesLineSpan, aAlphas); - break; - - default: - NS_ERROR("Unknown depth for alpha calculation"); - // make them all opaque - memset(aAlphas, 255, aAlphasSize); - } -} - -NS_IMETHODIMP nsBlender::GetAlphas(const nsRect& aRect, nsDrawingSurface aBlack, - nsDrawingSurface aWhite, PRUint8** aAlphas) { - nsresult result; - - nsIDrawingSurface* blackSurface = (nsIDrawingSurface *)aBlack; - nsIDrawingSurface* whiteSurface = (nsIDrawingSurface *)aWhite; - - nsRect r = aRect; - - rangeCheck(blackSurface, r.x, r.y, r.width, r.height); - rangeCheck(whiteSurface, r.x, r.y, r.width, r.height); - - PRUint8* blackBytes = nsnull; - PRUint8* whiteBytes = nsnull; - PRInt32 blackSpan, whiteSpan; - PRInt32 blackBytesPerLine, whiteBytesPerLine; - - result = blackSurface->Lock(r.x, r.y, r.width, r.height, - (void**)&blackBytes, &blackSpan, - &blackBytesPerLine, NS_LOCK_SURFACE_READ_ONLY); - if (NS_SUCCEEDED(result)) { - result = whiteSurface->Lock(r.x, r.y, r.width, r.height, - (void**)&whiteBytes, &whiteSpan, - &whiteBytesPerLine, NS_LOCK_SURFACE_READ_ONLY); - if (NS_SUCCEEDED(result)) { - NS_ASSERTION(blackSpan == whiteSpan && - blackBytesPerLine == whiteBytesPerLine, - "Mismatched bitmap formats (black/white) in Blender"); - if (blackSpan == whiteSpan && blackBytesPerLine == whiteBytesPerLine) { - *aAlphas = new PRUint8[r.width*r.height]; - if (*aAlphas) { - PRUint32 depth; - mContext->GetDepth(depth); - ComputeAlphas(r.height, blackBytesPerLine, depth, - blackBytes, whiteBytes, blackSpan, - *aAlphas, r.width*r.height); - } else { - result = NS_ERROR_FAILURE; - } - } - - whiteSurface->Unlock(); - } - - blackSurface->Unlock(); - } - - return result; -} -#endif // MOZ_XUL - /** --------------------------------------------------- * See documentation in nsBlender.h * @update 2/25/00 dwc @@ -692,6 +526,10 @@ nsBlender::Do24Blend(float aOpacity, PRInt32 aNumLines, PRInt32 aNumBytes, +#define RED16(x) (((x) & BLEND_RED_MASK) >> BLEND_RED_SHIFT) +#define GREEN16(x) (((x) & BLEND_GREEN_MASK) >> BLEND_GREEN_SHIFT) +#define BLUE16(x) (((x) & BLEND_BLUE_MASK) << BLEND_BLUE_SHIFT) + #define MAKE16(r, g, b) \ (PRUint16)(((r) & BLEND_RED_SET_MASK) << BLEND_RED_SHIFT) \ | (((g) & BLEND_GREEN_SET_MASK) << BLEND_GREEN_SHIFT) \ @@ -735,6 +573,7 @@ nsBlender::Do16Blend(float aOpacity, PRInt32 aNumLines, PRInt32 aNumBytes, *d2 = MAKE16(destPixR + (((RED16(srcPix) - destPixR)*opacity256) >> 8), destPixG + (((GREEN16(srcPix) - destPixG)*opacity256) >> 8), destPixB + (((BLUE16(srcPix) - destPixB)*opacity256) >> 8)); + d2++; s2++; } diff --git a/mozilla/gfx/src/nsBlender.h b/mozilla/gfx/src/nsBlender.h index 6c3b9df215e..23a012d9af9 100644 --- a/mozilla/gfx/src/nsBlender.h +++ b/mozilla/gfx/src/nsBlender.h @@ -60,9 +60,6 @@ public: nsIRenderingContext *aSecondSrc = nsnull, nscolor aSrcBackColor = NS_RGB(0, 0, 0), nscolor aSecondSrcBackColor = NS_RGB(0, 0, 0)); - NS_IMETHOD GetAlphas(const nsRect& aRect, nsDrawingSurface aBlack, - nsDrawingSurface aWhite, PRUint8** aAlphas); - protected: /** -------------------------------------------------------------------------- diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 9db1d63e0a7..d9a0dae7bd9 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -2615,32 +2615,14 @@ nsCSSRendering::FindNonTransparentBackground(nsStyleContext* aContext, * canvas. */ -// Returns nsnull if aFrame is not a canvas frame. -// Otherwise, it returns the frame we should look for the background on. -// This is normally aFrame but if aFrame is the viewport, we need to -// look for the background starting at the scroll root (which shares -// style context with the document root) or the document root itself. -// We need to treat the viewport as canvas because, even though -// it does not actually paint a background, we need to get the right -// background style so we correctly detect transparent documents. -inline nsIFrame* -IsCanvasFrame(nsIPresContext* aPresContext, nsIFrame *aFrame) +inline PRBool +IsCanvasFrame(nsIFrame *aFrame) { nsCOMPtr frameType; aFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType == nsLayoutAtoms::canvasFrame || - frameType == nsLayoutAtoms::rootFrame || - frameType == nsLayoutAtoms::pageFrame) { - return aFrame; - } else if (frameType == nsLayoutAtoms::viewportFrame) { - nsIFrame* firstChild; - aFrame->FirstChild(aPresContext, nsnull, &firstChild); - if (firstChild) { - return firstChild; - } - } - - return nsnull; + return (frameType == nsLayoutAtoms::canvasFrame || + frameType == nsLayoutAtoms::rootFrame || + frameType == nsLayoutAtoms::pageFrame); } inline PRBool @@ -2737,7 +2719,7 @@ FindElementBackground(nsIPresContext* aPresContext, nsIFrame *parentFrame; aForFrame->GetParent(&parentFrame); // XXXldb We shouldn't have to null-check |parentFrame| here. - if (parentFrame && IsCanvasFrame(aPresContext, parentFrame) == parentFrame) { + if (parentFrame && IsCanvasFrame(parentFrame)) { // Check that we're really the root (rather than in another child list). nsIFrame *childFrame; parentFrame->FirstChild(aPresContext, nsnull, &childFrame); @@ -2779,10 +2761,10 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext, const nsStyleBackground** aBackground, PRBool* aIsCanvas) { - nsIFrame* canvasFrame = IsCanvasFrame(aPresContext, aForFrame); - *aIsCanvas = canvasFrame != nsnull; - return canvasFrame - ? FindCanvasBackground(aPresContext, canvasFrame, aBackground) + PRBool isCanvas = IsCanvasFrame(aForFrame); + *aIsCanvas = isCanvas; + return isCanvas + ? FindCanvasBackground(aPresContext, aForFrame, aBackground) : FindElementBackground(aPresContext, aForFrame, aBackground); } @@ -2854,21 +2836,11 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, vm->GetRootView(rootView); nsIView* rootParent; rootView->GetParent(rootParent); - if (!rootParent) { - PRBool widgetIsTranslucent = PR_FALSE; - - nsCOMPtr rootWidget; - rootView->GetWidget(*getter_AddRefs(rootWidget)); - if (rootWidget) { - rootWidget->GetWindowTranslucency(widgetIsTranslucent); - } - - if (!widgetIsTranslucent) { - // Ensure that we always paint a color for the root (in case there's - // no background at all or a partly transparent image). - canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; - aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); - } + if (nsnull == rootParent) { + // Ensure that we always paint a color for the root (in case there's + // no background at all or a partly transparent image). + canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; + aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); } } diff --git a/mozilla/layout/generic/nsContainerFrame.cpp b/mozilla/layout/generic/nsContainerFrame.cpp index 0a493306dd3..f4006fb69d3 100644 --- a/mozilla/layout/generic/nsContainerFrame.cpp +++ b/mozilla/layout/generic/nsContainerFrame.cpp @@ -37,7 +37,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsContainerFrame.h" #include "nsIContent.h" -#include "nsIDocument.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" #include "nsStyleContext.h" @@ -559,41 +558,15 @@ SyncFrameViewGeometryDependentProperties(nsIPresContext* aPresContext, (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) || !aFrame->CanPaintBackground() || HasNonZeroBorderRadius(aStyleContext); - if (isCanvas) { + if (isCanvas && viewHasTransparentContent) { nsIView* rootView; vm->GetRootView(rootView); nsIView* rootParent; rootView->GetParent(rootParent); - if (!rootParent) { + if (nsnull == rootParent) { viewHasTransparentContent = PR_FALSE; - - // We need to set window translucency for top-level windows - // which have transparent backgrounds - if (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (doc) { - nsCOMPtr parentDoc; - doc->GetParentDocument(getter_AddRefs(parentDoc)); - if (!parentDoc) { - // our document is the root of the doc tree, so we must - // either be a top-level XUL window or something embedded. - // The SetWindowTranslucency call will fail if we're embedded. - nsCOMPtr widget; - aView->GetWidget(*getter_AddRefs(widget)); - if (widget) { - // Enable translucency in the widget - widget->SetWindowTranslucency(PR_TRUE); - viewHasTransparentContent = PR_TRUE; - } - } - } - } } } - // XXX we should also set widget transparency for XUL popups that ask for it const nsStyleDisplay* display; ::GetStyleData(aStyleContext, &display); diff --git a/mozilla/layout/html/base/src/nsContainerFrame.cpp b/mozilla/layout/html/base/src/nsContainerFrame.cpp index 0a493306dd3..f4006fb69d3 100644 --- a/mozilla/layout/html/base/src/nsContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsContainerFrame.cpp @@ -37,7 +37,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsContainerFrame.h" #include "nsIContent.h" -#include "nsIDocument.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" #include "nsStyleContext.h" @@ -559,41 +558,15 @@ SyncFrameViewGeometryDependentProperties(nsIPresContext* aPresContext, (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) || !aFrame->CanPaintBackground() || HasNonZeroBorderRadius(aStyleContext); - if (isCanvas) { + if (isCanvas && viewHasTransparentContent) { nsIView* rootView; vm->GetRootView(rootView); nsIView* rootParent; rootView->GetParent(rootParent); - if (!rootParent) { + if (nsnull == rootParent) { viewHasTransparentContent = PR_FALSE; - - // We need to set window translucency for top-level windows - // which have transparent backgrounds - if (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (doc) { - nsCOMPtr parentDoc; - doc->GetParentDocument(getter_AddRefs(parentDoc)); - if (!parentDoc) { - // our document is the root of the doc tree, so we must - // either be a top-level XUL window or something embedded. - // The SetWindowTranslucency call will fail if we're embedded. - nsCOMPtr widget; - aView->GetWidget(*getter_AddRefs(widget)); - if (widget) { - // Enable translucency in the widget - widget->SetWindowTranslucency(PR_TRUE); - viewHasTransparentContent = PR_TRUE; - } - } - } - } } } - // XXX we should also set widget transparency for XUL popups that ask for it const nsStyleDisplay* display; ::GetStyleData(aStyleContext, &display); diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index 9db1d63e0a7..d9a0dae7bd9 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -2615,32 +2615,14 @@ nsCSSRendering::FindNonTransparentBackground(nsStyleContext* aContext, * canvas. */ -// Returns nsnull if aFrame is not a canvas frame. -// Otherwise, it returns the frame we should look for the background on. -// This is normally aFrame but if aFrame is the viewport, we need to -// look for the background starting at the scroll root (which shares -// style context with the document root) or the document root itself. -// We need to treat the viewport as canvas because, even though -// it does not actually paint a background, we need to get the right -// background style so we correctly detect transparent documents. -inline nsIFrame* -IsCanvasFrame(nsIPresContext* aPresContext, nsIFrame *aFrame) +inline PRBool +IsCanvasFrame(nsIFrame *aFrame) { nsCOMPtr frameType; aFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType == nsLayoutAtoms::canvasFrame || - frameType == nsLayoutAtoms::rootFrame || - frameType == nsLayoutAtoms::pageFrame) { - return aFrame; - } else if (frameType == nsLayoutAtoms::viewportFrame) { - nsIFrame* firstChild; - aFrame->FirstChild(aPresContext, nsnull, &firstChild); - if (firstChild) { - return firstChild; - } - } - - return nsnull; + return (frameType == nsLayoutAtoms::canvasFrame || + frameType == nsLayoutAtoms::rootFrame || + frameType == nsLayoutAtoms::pageFrame); } inline PRBool @@ -2737,7 +2719,7 @@ FindElementBackground(nsIPresContext* aPresContext, nsIFrame *parentFrame; aForFrame->GetParent(&parentFrame); // XXXldb We shouldn't have to null-check |parentFrame| here. - if (parentFrame && IsCanvasFrame(aPresContext, parentFrame) == parentFrame) { + if (parentFrame && IsCanvasFrame(parentFrame)) { // Check that we're really the root (rather than in another child list). nsIFrame *childFrame; parentFrame->FirstChild(aPresContext, nsnull, &childFrame); @@ -2779,10 +2761,10 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext, const nsStyleBackground** aBackground, PRBool* aIsCanvas) { - nsIFrame* canvasFrame = IsCanvasFrame(aPresContext, aForFrame); - *aIsCanvas = canvasFrame != nsnull; - return canvasFrame - ? FindCanvasBackground(aPresContext, canvasFrame, aBackground) + PRBool isCanvas = IsCanvasFrame(aForFrame); + *aIsCanvas = isCanvas; + return isCanvas + ? FindCanvasBackground(aPresContext, aForFrame, aBackground) : FindElementBackground(aPresContext, aForFrame, aBackground); } @@ -2854,21 +2836,11 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, vm->GetRootView(rootView); nsIView* rootParent; rootView->GetParent(rootParent); - if (!rootParent) { - PRBool widgetIsTranslucent = PR_FALSE; - - nsCOMPtr rootWidget; - rootView->GetWidget(*getter_AddRefs(rootWidget)); - if (rootWidget) { - rootWidget->GetWindowTranslucency(widgetIsTranslucent); - } - - if (!widgetIsTranslucent) { - // Ensure that we always paint a color for the root (in case there's - // no background at all or a partly transparent image). - canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; - aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); - } + if (nsnull == rootParent) { + // Ensure that we always paint a color for the root (in case there's + // no background at all or a partly transparent image). + canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; + aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); } } diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 2da78476395..2dac205ac40 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -99,33 +99,6 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); #define SUPPORT_TRANSLUCENT_VIEWS -/* - This class encapsulates all the offscreen buffers we might want to - render into. mOffscreen is the basic buffer for doing - double-buffering. mBlack and mWhite are buffers for collecting an - individual view drawn onto black and drawn onto white, from which we - can recover the alpha values of the view's pixels. mOffscreenWhite - is only for when the widget being rendered is transparent; it's an - alternative double-buffer buffer that starts off white instead of - black, and allows us to recover alpha values for the widget. -*/ -class BlendingBuffers { -public: - BlendingBuffers(nsIRenderingContext* aCleanupContext); - ~BlendingBuffers(); - - nsCOMPtr mCleanupContext; - nsCOMPtr mOffScreenCX; - nsCOMPtr mOffScreenWhiteCX; - nsCOMPtr mBlackCX; - nsCOMPtr mWhiteCX; - - nsDrawingSurface mOffScreen; - nsDrawingSurface mOffScreenWhite; - nsDrawingSurface mBlack; - nsDrawingSurface mWhite; -}; - // A DisplayListElement2 records the information needed to paint one view. // Note that child views get their own DisplayListElement2s; painting a view // paints that view's frame and all its child frames EXCEPT for the child frames @@ -318,6 +291,10 @@ nsViewManager::PostInvalidateEvent() PRInt32 nsViewManager::mVMCount = 0; nsIRenderingContext* nsViewManager::gCleanupContext = nsnull; +nsDrawingSurface nsViewManager::gOffScreen = nsnull; +nsDrawingSurface nsViewManager::gBlack = nsnull; +nsDrawingSurface nsViewManager::gWhite = nsnull; +nsSize nsViewManager::gOffScreenSize = nsSize(0, 0); // Weakly held references to all of the view managers nsVoidArray* nsViewManager::gViewManagers = nsnull; @@ -389,16 +366,37 @@ nsViewManager::~nsViewManager() if (gCleanupContext) { gCleanupContext->DestroyCachedBackbuffer(); + + if (nsnull != gOffScreen) + gCleanupContext->DestroyDrawingSurface(gOffScreen); + + if (nsnull != gWhite) + gCleanupContext->DestroyDrawingSurface(gWhite); + + if (nsnull != gBlack) + gCleanupContext->DestroyDrawingSurface(gBlack); + } else { NS_ASSERTION(PR_FALSE, "Cleanup of drawing surfaces + offscreen buffer failed"); } + gOffScreen = nsnull; + gWhite = nsnull; + gBlack = nsnull; + gOffScreenSize.SizeTo(0, 0); + NS_IF_RELEASE(gCleanupContext); } mObserver = nsnull; mContext = nsnull; + NS_IF_RELEASE(mBlender); + + NS_IF_RELEASE(mOffScreenCX); + NS_IF_RELEASE(mBlackCX); + NS_IF_RELEASE(mWhiteCX); + if (nsnull != mCompositeListeners) { mCompositeListeners->Clear(); NS_RELEASE(mCompositeListeners); @@ -1007,11 +1005,13 @@ static void PushStateAndClip(nsIRenderingContext **aRCs, PRInt32 aRCCount, nsRec PRInt32 aDX, PRInt32 aDY) { PRBool clipEmpty; nsRect rect = aRect; - rect.x -= aDX; - rect.y -= aDY; for (PRInt32 i = 0; i < aRCCount; i++) { aRCs[i]->PushState(); - aRCs[i]->SetClipRect(i == 0 ? aRect : rect, nsClipCombine_kIntersect, clipEmpty); + if (i == 1) { + rect.x -= aDX; + rect.y -= aDY; + } + aRCs[i]->SetClipRect(rect, nsClipCombine_kIntersect, clipEmpty); } } @@ -1126,29 +1126,15 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, con // We keep a list of all the rendering contexts whose clip rects // need to be updated. - nsIRenderingContext* RCList[5]; + nsIRenderingContext* RCList[4]; PRInt32 RCCount = 1; RCList[0] = &aRC; - - nsCOMPtr widget; - aRootView->GetWidget(*getter_AddRefs(widget)); - PRBool translucentWindow = PR_FALSE; - if (widget) { - widget->GetWindowTranslucency(translucentWindow); - if (translucentWindow) { - // for a translucent window, we'll pretend the whole area is - // translucent. - mTranslucentArea = aRect; - } - } - BlendingBuffers* buffers = nsnull; - // create blending buffers, if necessary. - if (mTranslucentViewCount > 0 || translucentWindow) { - buffers = CreateBlendingBuffers(&aRC, translucentWindow); - NS_ASSERTION(buffers, "not enough memory to blend"); - if (!buffers) { + if (mTranslucentViewCount > 0) { + nsresult rv = CreateBlendingBuffers(aRC); + NS_ASSERTION((rv == NS_OK), "not enough memory to blend"); + if (NS_FAILED(rv)) { // fall back by just rendering with transparency. mTranslucentViewCount = 0; for (PRInt32 i = mDisplayListCount - 1; i>= 0; --i) { @@ -1156,21 +1142,17 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, con element->mFlags &= ~VIEW_TRANSLUCENT; } } else { - RCList[RCCount++] = buffers->mOffScreenCX; - if (translucentWindow) { - RCList[RCCount++] = buffers->mOffScreenWhiteCX; - } - if (mTranslucentViewCount > 0) { - RCList[RCCount++] = buffers->mBlackCX; - RCList[RCCount++] = buffers->mWhiteCX; - } + RCCount = 4; + RCList[1] = mBlackCX; + RCList[2] = mWhiteCX; + RCList[3] = mOffScreenCX; + } - if (!translucentWindow && !finalTransparentRect.IsEmpty()) { - // There are some bits that aren't going to be completely painted, so - // make sure we don't leave garbage in the offscreen context - buffers->mOffScreenCX->SetColor(NS_RGB(128, 128, 128)); - buffers->mOffScreenCX->FillRect(nsRect(0, 0, mTranslucentArea.width, mTranslucentArea.height)); - } + if (!finalTransparentRect.IsEmpty()) { + // There are some bits that aren't going to be completely painted, so + // make sure we don't leave garbage in the offscreen context + mOffScreenCX->SetColor(NS_RGB(128, 128, 128)); + mOffScreenCX->FillRect(nsRect(0, 0, gOffScreenSize.width, gOffScreenSize.height)); } // DEBUGGING: fill in complete offscreen image in green, to see if we've got a blending bug. //mOffScreenCX->SetColor(NS_RGB(0, 255, 0)); @@ -1186,10 +1168,10 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, con if (element->mFlags & VIEW_CLIPPED) { //Render the view using the clip rect set by it's ancestors PushStateAndClip(RCList, RCCount, element->mBounds, mTranslucentArea.x, mTranslucentArea.y); - RenderDisplayListElement(element, aRC, buffers); + RenderDisplayListElement(element, aRC); PopState(RCList, RCCount); } else { - RenderDisplayListElement(element, aRC, buffers); + RenderDisplayListElement(element, aRC); } } else { @@ -1208,51 +1190,31 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, con // flush bits back to screen. // Must flush back when no clipping is in effect. - if (buffers) { - if (translucentWindow) { - // Set window alphas - nsRect r = mTranslucentArea; - r *= mTwipsToPixels; - nsRect bufferRect(0, 0, r.width, r.height); - PRUint8* alphas = nsnull; - nsresult rv = mBlender->GetAlphas(bufferRect, buffers->mOffScreen, - buffers->mOffScreenWhite, &alphas); - if (NS_SUCCEEDED(rv)) { - widget->UpdateTranslucentWindowAlpha(r, alphas); - } - delete[] alphas; - } - + if (mTranslucentViewCount > 0) { // DEBUG: is this getting through? // mOffScreenCX->SetColor(NS_RGB(0, 0, 0)); // mOffScreenCX->DrawRect(nsRect(0, 0, mTranslucentArea.width, mTranslucentArea.height)); - aRC.CopyOffScreenBits(buffers->mOffScreen, 0, 0, mTranslucentArea, + aRC.CopyOffScreenBits(gOffScreen, 0, 0, mTranslucentArea, NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER); // DEBUG: what rectangle are we blitting? // aRC.SetColor(NS_RGB(0, 0, 0)); // aRC.DrawRect(mTranslucentArea); - - delete buffers; } mDisplayList.Clear(); } -void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, - nsIRenderingContext &aRC, - BlendingBuffers* aBuffers) +void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, nsIRenderingContext &aRC) { + PRBool isTranslucent = (element->mFlags & VIEW_TRANSLUCENT) != 0; PRBool clipEmpty; nsRect r; nsView* view = element->mView; view->GetDimensions(r); - // if this element is contained by the translucent area, then - // there's no point in drawing it here because it will be - // overwritten by the final copy of the composited offscreen area - if (!aBuffers || !mTranslucentArea.Contains(element->mBounds)) { + if (!isTranslucent) { aRC.PushState(); nscoord x = element->mAbsX - r.x, y = element->mAbsY - r.y; @@ -1267,7 +1229,11 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, } #if defined(SUPPORT_TRANSLUCENT_VIEWS) - if (aBuffers && mTranslucentArea.Intersects(element->mBounds)) { + if (mTranslucentViewCount > 0 && (isTranslucent || mTranslucentArea.Intersects(element->mBounds))) { + // transluscency case. if this view is transluscent, have to use the nsIBlender, otherwise, just + // render in the offscreen. when we reach the last transluscent view, then we flush the bits + // to the onscreen rendering context. + // compute the origin of the view, relative to the offscreen buffer, which has the // same dimensions as mTranslucentArea. nscoord x = element->mAbsX - r.x, y = element->mAbsY - r.y; @@ -1277,21 +1243,16 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, damageRect.IntersectRect(damageRect, mTranslucentArea); // -> coordinates relative to element->mView origin damageRect.x -= x, damageRect.y -= y; - - // the element must be rendered into mOffscreenCX and also - // mOffScreenWhiteCX if the window is transparent/translucent. - nsIRenderingContext* targets[2] = - { aBuffers->mOffScreenCX, aBuffers->mOffScreenWhiteCX }; if (element->mFlags & VIEW_TRANSLUCENT) { // paint the view twice, first in the black buffer, then the white; // the blender will pick up the touched pixels only. - PaintView(view, *aBuffers->mBlackCX, viewX, viewY, damageRect); + PaintView(view, *mBlackCX, viewX, viewY, damageRect); // DEBUGGING ONLY //aRC.CopyOffScreenBits(gBlack, 0, 0, element->mBounds, // NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER); - PaintView(view, *aBuffers->mWhiteCX, viewX, viewY, damageRect); + PaintView(view, *mWhiteCX, viewX, viewY, damageRect); // DEBUGGING ONLY //aRC.CopyOffScreenBits(gWhite, 0, 0, element->mBounds, // NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER); @@ -1308,21 +1269,16 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, nsRect damageRectInPixels = damageRect; damageRectInPixels *= mTwipsToPixels; if (damageRectInPixels.width > 0 && damageRectInPixels.height > 0) { - PRIntn i; - for (i = 0; i < 2; i++) { - if (targets[i]) { - nsresult rv = mBlender->Blend(damageRectInPixels.x, damageRectInPixels.y, - damageRectInPixels.width, damageRectInPixels.height, - aBuffers->mBlackCX, targets[i], - damageRectInPixels.x, damageRectInPixels.y, - opacity, aBuffers->mWhiteCX, - NS_RGB(0, 0, 0), NS_RGB(255, 255, 255)); - if (NS_FAILED(rv)) { - NS_WARNING("Blend failed!"); - // let's paint SOMETHING. Paint opaquely - PaintView(view, *targets[i], viewX, viewY, damageRect); - } - } + nsresult rv = mBlender->Blend(damageRectInPixels.x, damageRectInPixels.y, + damageRectInPixels.width, damageRectInPixels.height, + mBlackCX, mOffScreenCX, + damageRectInPixels.x, damageRectInPixels.y, + opacity, mWhiteCX, + NS_RGB(0, 0, 0), NS_RGB(255, 255, 255)); + if (NS_FAILED(rv)) { + NS_WARNING("Blend failed!"); + // let's paint SOMETHING. Paint opaquely + PaintView(view, *mOffScreenCX, viewX, viewY, damageRect); } } @@ -1330,17 +1286,12 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element, // We do that here because we know that whatever the clip region is, // everything we just painted is within the clip region so we are // sure to be able to overwrite it now. - aBuffers->mBlackCX->SetColor(NS_RGB(0, 0, 0)); - aBuffers->mBlackCX->FillRect(damageRect); - aBuffers->mWhiteCX->SetColor(NS_RGB(255, 255, 255)); - aBuffers->mWhiteCX->FillRect(damageRect); + mBlackCX->SetColor(NS_RGB(0, 0, 0)); + mBlackCX->FillRect(damageRect); + mWhiteCX->SetColor(NS_RGB(255, 255, 255)); + mWhiteCX->FillRect(damageRect); } else { - PRIntn i; - for (i = 0; i < 2; i++) { - if (targets[i]) { - PaintView(view, *targets[i], viewX, viewY, damageRect); - } - } + PaintView(view, *mOffScreenCX, viewX, viewY, damageRect); } } #endif @@ -1356,6 +1307,14 @@ void nsViewManager::PaintView(nsView *aView, nsIRenderingContext &aRC, nscoord x aRC.PopState(unused); } +inline PRInt32 nextPowerOf2(PRInt32 value) +{ + PRInt32 result = 1; + while (value > result) + result <<= 1; + return result; +} + static nsresult NewOffscreenContext(nsIDeviceContext* deviceContext, nsDrawingSurface surface, const nsSize& size, nsIRenderingContext* *aResult) { @@ -1375,119 +1334,87 @@ static nsresult NewOffscreenContext(nsIDeviceContext* deviceContext, nsDrawingSu return NS_OK; } -BlendingBuffers::BlendingBuffers(nsIRenderingContext* aCleanupContext) { - mCleanupContext = aCleanupContext; - - mOffScreen = nsnull; - mOffScreenWhite = nsnull; - mWhite = nsnull; - mBlack = nsnull; -} - -BlendingBuffers::~BlendingBuffers() { - if (mOffScreen) - mCleanupContext->DestroyDrawingSurface(mOffScreen); - - if (mOffScreenWhite) - mCleanupContext->DestroyDrawingSurface(mOffScreenWhite); - - if (mWhite) - mCleanupContext->DestroyDrawingSurface(mWhite); - - if (mBlack) - mCleanupContext->DestroyDrawingSurface(mBlack); -} - -BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC, - PRBool aTranslucentWindow) +nsresult nsViewManager::CreateBlendingBuffers(nsIRenderingContext &aRC) { - nsresult rv; + nsresult rv = NS_OK; // create a blender, if none exists already. - if (!mBlender) { - mBlender = do_CreateInstance(kBlenderCID, &rv); + if (nsnull == mBlender) { + rv = nsComponentManager::CreateInstance(kBlenderCID, nsnull, NS_GET_IID(nsIBlender), (void **)&mBlender); if (NS_FAILED(rv)) - return nsnull; + return rv; rv = mBlender->Init(mContext); if (NS_FAILED(rv)) - return nsnull; + return rv; } - BlendingBuffers* buffers = new BlendingBuffers(aRC); - if (!buffers) - return nsnull; + // ensure that the global drawing surfaces are large enough. + if (mTranslucentArea.width > gOffScreenSize.width || mTranslucentArea.height > gOffScreenSize.height) { + nsRect offscreenBounds(0, 0, mTranslucentArea.width, mTranslucentArea.height); + offscreenBounds.ScaleRoundOut(mTwipsToPixels); + offscreenBounds.width = nextPowerOf2(offscreenBounds.width); + offscreenBounds.height = nextPowerOf2(offscreenBounds.height); - nsRect offscreenBounds(0, 0, mTranslucentArea.width, mTranslucentArea.height); - offscreenBounds.ScaleRoundOut(mTwipsToPixels); - nsSize offscreenSize(mTranslucentArea.width, mTranslucentArea.height); + NS_IF_RELEASE(mOffScreenCX); + NS_IF_RELEASE(mBlackCX); + NS_IF_RELEASE(mWhiteCX); - rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mOffScreen); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; + if (nsnull != gOffScreen) { + aRC.DestroyDrawingSurface(gOffScreen); + gOffScreen = nsnull; + } + rv = aRC.CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gOffScreen); + if (NS_FAILED(rv)) + return rv; + + if (nsnull != gBlack) { + aRC.DestroyDrawingSurface(gBlack); + gBlack = nsnull; + } + rv = aRC.CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gBlack); + if (NS_FAILED(rv)) + return rv; + + if (nsnull != gWhite) { + aRC.DestroyDrawingSurface(gWhite); + gWhite = nsnull; + } + rv = aRC.CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gWhite); + if (NS_FAILED(rv)) + return rv; + + offscreenBounds.ScaleRoundIn(mPixelsToTwips); + gOffScreenSize.width = offscreenBounds.width; + gOffScreenSize.height = offscreenBounds.height; } - rv = NewOffscreenContext(mContext, buffers->mOffScreen, offscreenSize, getter_AddRefs(buffers->mOffScreenCX)); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; + // recreate local offscreen & blending contexts, if necessary. + if (mOffScreenCX == nsnull) { + rv = NewOffscreenContext(mContext, gOffScreen, gOffScreenSize, &mOffScreenCX); + if (NS_FAILED(rv)) + return rv; + } + if (mBlackCX == nsnull) { + rv = NewOffscreenContext(mContext, gBlack, gOffScreenSize, &mBlackCX); + if (NS_FAILED(rv)) + return rv; + } + if (mWhiteCX == nsnull) { + rv = NewOffscreenContext(mContext, gWhite, gOffScreenSize, &mWhiteCX); + if (NS_FAILED(rv)) + return rv; } - if (mTranslucentViewCount > 0) { - rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mBlack); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } + nsRect fillArea = mTranslucentArea; + fillArea.x = 0; + fillArea.y = 0; - rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mWhite); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } - - rv = NewOffscreenContext(mContext, buffers->mBlack, offscreenSize, getter_AddRefs(buffers->mBlackCX)); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } + mBlackCX->SetColor(NS_RGB(0, 0, 0)); + mBlackCX->FillRect(fillArea); + mWhiteCX->SetColor(NS_RGB(255, 255, 255)); + mWhiteCX->FillRect(fillArea); - rv = NewOffscreenContext(mContext, buffers->mWhite, offscreenSize, getter_AddRefs(buffers->mWhiteCX)); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } - - nsRect fillArea(0, 0, mTranslucentArea.width, mTranslucentArea.height); - - buffers->mBlackCX->SetColor(NS_RGB(0, 0, 0)); - buffers->mBlackCX->FillRect(fillArea); - buffers->mWhiteCX->SetColor(NS_RGB(255, 255, 255)); - buffers->mWhiteCX->FillRect(fillArea); - } - - if (aTranslucentWindow) { - rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mOffScreenWhite); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } - - rv = NewOffscreenContext(mContext, buffers->mOffScreenWhite, offscreenSize, getter_AddRefs(buffers->mOffScreenWhiteCX)); - if (NS_FAILED(rv)) { - delete buffers; - return nsnull; - } - - nsRect fillArea(0, 0, mTranslucentArea.width, mTranslucentArea.height); - - buffers->mOffScreenCX->SetColor(NS_RGB(0, 0, 0)); - buffers->mOffScreenCX->FillRect(fillArea); - buffers->mOffScreenWhiteCX->SetColor(NS_RGB(255, 255, 255)); - buffers->mOffScreenWhiteCX->FillRect(fillArea); - } - - return buffers; + return NS_OK; } void nsViewManager::ProcessPendingUpdates(nsView* aView) diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index 2be4974d3c7..5f290b3aabb 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -60,7 +60,6 @@ class nsIPresContext; class nsISupportsArray; struct DisplayListElement2; struct DisplayZTreeNode; -class BlendingBuffers; //Uncomment the following line to enable generation of viewmanager performance data. #ifdef MOZ_PERF_METRICS @@ -256,19 +255,16 @@ private: void RenderViews(nsView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult); - void RenderDisplayListElement(DisplayListElement2* element, - nsIRenderingContext &aRC, - BlendingBuffers* aBuffers); + void RenderDisplayListElement(DisplayListElement2* element, nsIRenderingContext &aRC); void PaintView(nsView *aView, nsIRenderingContext &aRC, nscoord x, nscoord y, - const nsRect &aDamageRect); + const nsRect &aDamageRect); void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut, PRUint32 aUpdateFlags); void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut, PRUint32 aUpdateFlags, nscoord aY1, nscoord aY2, PRBool aInCutOut); - BlendingBuffers* CreateBlendingBuffers(nsIRenderingContext *aRC, - PRBool aTranslucentWindow); + nsresult CreateBlendingBuffers(nsIRenderingContext &aRC); void ReparentViews(DisplayZTreeNode* aNode); void BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing, PRBool aCaptured); @@ -395,13 +391,23 @@ private: //from here to public should be static and locked... MMP static PRInt32 mVMCount; //number of viewmanagers + //blending buffers + static nsDrawingSurface gOffScreen; + static nsDrawingSurface gBlack; + static nsDrawingSurface gWhite; + static nsSize gOffScreenSize; + //Rendering context used to cleanup the blending buffers static nsIRenderingContext* gCleanupContext; //list of view managers static nsVoidArray *gViewManagers; - nsCOMPtr mBlender; + nsIBlender *mBlender; + + nsIRenderingContext *mOffScreenCX; + nsIRenderingContext *mBlackCX; + nsIRenderingContext *mWhiteCX; nsISupportsArray *mCompositeListeners; void DestroyZTreeNode(DisplayZTreeNode* aNode); diff --git a/mozilla/widget/public/nsIWidget.h b/mozilla/widget/public/nsIWidget.h index 43c148c4b24..bc78e28b101 100644 --- a/mozilla/widget/public/nsIWidget.h +++ b/mozilla/widget/public/nsIWidget.h @@ -593,44 +593,6 @@ class nsIWidget : public nsISupports { */ NS_IMETHOD GetWindowType(nsWindowType& aWindowType) = 0; - /** - * Set the translucency of the top-level window containing this widget. - * So, e.g., if you call this on the widget for an IFRAME, the top level - * browser window containing the IFRAME actually gets set. Be careful. - * - * This can fail if the platform doesn't support - * transparency/translucency. By default widgets are not - * transparent. This will also fail if the toplevel window is not - * a Mozilla window, e.g., if the widget is in an embedded - * context. - * - * After translucency has been enabled, the initial alpha channel - * value for all pixels is 1, i.e., opaque. - * If the window is resized then the alpha channel values for - * all pixels are reset to 1. - * @param aTranslucent true if the window may have translucent - * or transparent pixels - */ - NS_IMETHOD SetWindowTranslucency(PRBool aTranslucent) = 0; - - /** - * Get the translucency of the top-level window that contains this - * widget. - * @param aTranslucent true if the window may have translucent or - * transparent pixels - */ - NS_IMETHOD GetWindowTranslucency(PRBool& aTranslucent) = 0; - - /** - * Update the alpha channel for some pixels of the top-level window - * that contains this widget. - * The window must have been made translucent using SetWindowTranslucency. - * @param aRect the rect to update - * @param aAlphas the alpha values, in w x h array, row-major order, - * in units of 1/255. nsBlender::GetAlphas is a good way to compute this array. - */ - NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas) = 0; - /** * Hide window chrome (borders, buttons) for this widget. * diff --git a/mozilla/widget/src/gtk/nsWindow.cpp b/mozilla/widget/src/gtk/nsWindow.cpp index baa3ce4c801..278ae5b8fef 100644 --- a/mozilla/widget/src/gtk/nsWindow.cpp +++ b/mozilla/widget/src/gtk/nsWindow.cpp @@ -266,9 +266,6 @@ nsWindow::nsWindow() mIMECompositionUniString = nsnull; mIMECompositionUniStringSize = 0; - mIsTranslucent = PR_FALSE; - mTransparencyBitmap = nsnull; - #ifdef USE_XIM mIMEEnable = PR_TRUE; //currently will not be used mIMEShellWindow = 0; @@ -357,9 +354,6 @@ nsWindow::~nsWindow() Destroy(); - delete[] mTransparencyBitmap; - mTransparencyBitmap = nsnull; - if (mIsUpdating) UnqueueDraw(); } @@ -2769,10 +2763,6 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint) aWidth, aHeight); #endif - // ResizeTransparencyBitmap uses the old bounds, so pass it the new bounds - // before we change the old bounds. - ResizeTransparencyBitmap(aWidth, aHeight); - mBounds.width = aWidth; mBounds.height = aHeight; @@ -4265,208 +4255,15 @@ NS_IMETHODIMP nsWindow::ResetInputState() return NS_OK; } -nsWindow* nsWindow::FindTopLevelWindow() { - if (!mShell) { - GtkWidget *top_mozarea = GetOwningWidget(); - void *data = gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"); - return NS_STATIC_CAST(nsWindow *, data); - } else { - return nsnull; - } -} - -static void -gdk_wmspec_change_state (gboolean add, - GdkWindow *window, - GdkAtom state1, - GdkAtom state2) -{ - XEvent xev; - -#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ -#define _NET_WM_STATE_ADD 1 /* add/set property */ -#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = GDK_WINDOW_XWINDOW(window); - xev.xclient.message_type = gdk_atom_intern("_NET_WM_STATE", FALSE); - xev.xclient.format = 32; - xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - xev.xclient.data.l[1] = state1; - xev.xclient.data.l[2] = state2; - - XSendEvent(gdk_display, GDK_ROOT_WINDOW(), False, - SubstructureRedirectMask | SubstructureNotifyMask, &xev); -} - -#ifndef MOZ_XUL -void nsWindow::ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight) { -} -#else -NS_IMETHODIMP nsWindow::SetWindowTranslucency(PRBool aTranslucent) { - nsWindow* top = FindTopLevelWindow(); - if (top) { - return top->SetWindowTranslucency(aTranslucent); - } - - if (!mShell) { - // we must be embedded - NS_WARNING("Trying to use transparent chrome in an embedded context"); - return NS_ERROR_FAILURE; - } - - if (mIsTranslucent == aTranslucent) - return NS_OK; - - if (!aTranslucent) { - delete[] mTransparencyBitmap; - mTransparencyBitmap = nsnull; - gtk_widget_reset_shapes(mShell); - } // else the new default alpha values are "all 1", so we don't - // need to change anything yet - - mIsTranslucent = aTranslucent; - return NS_OK; -} - -NS_IMETHODIMP nsWindow::GetWindowTranslucency(PRBool& aTranslucent) { - nsWindow* top = FindTopLevelWindow(); - if (top) { - return top->GetWindowTranslucency(aTranslucent); - } - - aTranslucent = mIsTranslucent; - return NS_OK; -} - -void nsWindow::ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight) { - if (!mTransparencyBitmap) - return; - - PRInt32 newSize = ((aNewWidth+7)/8)*aNewHeight; - gchar* newBits = new gchar[newSize]; - if (!newBits) { - delete[] mTransparencyBitmap; - mTransparencyBitmap = nsnull; - return; - } - // fill new mask with "opaque", first - memset(newBits, 255, newSize); - - // Now copy the intersection of the old and new areas into the new mask - PRInt32 copyWidth = PR_MIN(aNewWidth, mBounds.width); - PRInt32 copyHeight = PR_MIN(aNewHeight, mBounds.height); - PRInt32 oldRowBytes = (mBounds.width+7)/8; - PRInt32 newRowBytes = (aNewWidth+7)/8; - PRInt32 copyBytes = (copyWidth+7)/8; - - PRInt32 i; - gchar* fromPtr = mTransparencyBitmap; - gchar* toPtr = newBits; - for (i = 0; i < copyHeight; i++) { - memcpy(toPtr, fromPtr, copyBytes); - fromPtr += oldRowBytes; - toPtr += newRowBytes; - } - - delete[] mTransparencyBitmap; - mTransparencyBitmap = newBits; -} - -static PRBool ChangedMaskBits(gchar* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight, - const nsRect& aRect, PRUint8* aAlphas) { - PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8; - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y*maskBytesPerRow; - for (x = aRect.x; x < xMax; x++) { - PRBool newBit = *aAlphas > 0; - aAlphas++; - - gchar maskByte = maskBytes[x >> 3]; - PRBool maskBit = (maskByte & (1 << (x & 7))) != 0; - - if (maskBit != newBit) { - return PR_TRUE; - } - } - } - - return PR_FALSE; -} - -static void UpdateMaskBits(gchar* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight, - const nsRect& aRect, PRUint8* aAlphas) { - PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8; - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y*maskBytesPerRow; - for (x = aRect.x; x < xMax; x++) { - PRBool newBit = *aAlphas > 0; - aAlphas++; - - gchar mask = 1 << (x & 7); - gchar maskByte = maskBytes[x >> 3]; - // Note: '-newBit' turns 0 into 00...00 and 1 into 11...11 - maskBytes[x >> 3] = (maskByte & ~mask) | (-newBit & mask); - } - } -} - -NS_IMETHODIMP nsWindow::UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas) { - nsWindow* top = FindTopLevelWindow(); - if (top) { - return top->UpdateTranslucentWindowAlpha(aRect, aAlphas); - } - - NS_ASSERTION(mIsTranslucent, "Window is not transparent"); - - if (!mTransparencyBitmap) { - PRInt32 size = ((mBounds.width+7)/8)*mBounds.height; - mTransparencyBitmap = new gchar[size]; - if (!mTransparencyBitmap) - return NS_ERROR_FAILURE; - memset(mTransparencyBitmap, 255, size); - } - - NS_ASSERTION(aRect.x >= 0 && aRect.y >= 0 - && aRect.XMost() <= mBounds.width && aRect.YMost() <= mBounds.height, - "Rect is out of window bounds"); - - if (!ChangedMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height, aRect, aAlphas)) - // skip the expensive stuff if the mask bits haven't changed; hopefully - // this is the common case - return NS_OK; - - UpdateMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height, aRect, aAlphas); - - gtk_widget_reset_shapes(mShell); - GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(mShell->window, - mTransparencyBitmap, - mBounds.width, mBounds.height); - if (!maskBitmap) - return NS_ERROR_FAILURE; - - gtk_widget_shape_combine_mask(mShell, maskBitmap, 0, 0); - gdk_bitmap_unref(maskBitmap); - - return NS_OK; -} - NS_IMETHODIMP nsWindow::HideWindowChrome(PRBool aShouldHide) { - nsWindow* top = FindTopLevelWindow(); - if (top) { - return top->HideWindowChrome(aShouldHide); - } - if (!mShell) { - // we must be embedded - NS_WARNING("Trying to hide window decorations in an embedded context"); - return NS_ERROR_FAILURE; + // Pass the request to the toplevel window. + GtkWidget *top_mozarea = GetOwningWidget(); + void *data = gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"); + nsWindow *mozAreaWindow = NS_STATIC_CAST(nsWindow *, data); + return mozAreaWindow->HideWindowChrome(aShouldHide); } // Sawfish, metacity, and presumably other window managers get @@ -4497,18 +4294,41 @@ nsWindow::HideWindowChrome(PRBool aShouldHide) return NS_OK; } +static void +gdk_wmspec_change_state (gboolean add, + GdkWindow *window, + GdkAtom state1, + GdkAtom state2) +{ + XEvent xev; + +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = GDK_WINDOW_XWINDOW(window); + xev.xclient.message_type = gdk_atom_intern("_NET_WM_STATE", FALSE); + xev.xclient.format = 32; + xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = state1; + xev.xclient.data.l[2] = state2; + + XSendEvent(gdk_display, GDK_ROOT_WINDOW(), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + NS_IMETHODIMP nsWindow::MakeFullScreen(PRBool aFullScreen) { - nsWindow* top = FindTopLevelWindow(); - if (top) { - return top->MakeFullScreen(aFullScreen); - } - if (!mShell) { - // we must be embedded - NS_WARNING("Trying to go fullscreen in an embedded context"); - return NS_ERROR_FAILURE; + // Pass the request to the toplevel window. + GtkWidget *top_mozarea = GetOwningWidget(); + void *data = gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"); + nsWindow *mozAreaWindow = NS_STATIC_CAST(nsWindow *, data); + return mozAreaWindow->MakeFullScreen(aFullScreen); } gdk_wmspec_change_state(aFullScreen, mShell->window, @@ -4516,7 +4336,6 @@ nsWindow::MakeFullScreen(PRBool aFullScreen) GDK_NONE); return NS_OK; } -#endif PRBool PR_CALLBACK nsWindow::IconEntryMatches(PLDHashTable* aTable, diff --git a/mozilla/widget/src/gtk/nsWindow.h b/mozilla/widget/src/gtk/nsWindow.h index fe7e6a28552..4d0b22cae11 100644 --- a/mozilla/widget/src/gtk/nsWindow.h +++ b/mozilla/widget/src/gtk/nsWindow.h @@ -115,15 +115,8 @@ public: NS_IMETHOD SetFocus(PRBool aRaise); NS_IMETHOD GetAttention(void); NS_IMETHOD Destroy(); - nsWindow* FindTopLevelWindow(); // returns nsnull if WE are top level - void ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight); -#ifdef INCLUDE_XUL - NS_IMETHOD SetWindowTranslucency(PRBool aTransparent); - NS_IMETHOD GetWindowTranslucency(PRBool& aTransparent); - NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas); NS_IMETHOD HideWindowChrome(PRBool aShouldHide); NS_IMETHOD MakeFullScreen(PRBool aFullScreen); -#endif NS_IMETHOD SetIcon(const nsAString& aIcon); GdkCursor *GtkCreateCursor(nsCursor aCursorType); virtual void LoseFocus(void); @@ -345,14 +338,14 @@ protected: #ifdef USE_XIM protected: + PRBool mIMEEnable; static GdkFont *gPreeditFontset; static GdkFont *gStatusFontset; static GdkIMStyle gInputStyle; static PLDHashTable gXICLookupTable; - PRPackedBool mIMEEnable; - PRPackedBool mIMECallComposeStart; - PRPackedBool mIMECallComposeEnd; - PRPackedBool mIMEIsBeingActivate; + PRBool mIMECallComposeStart; + PRBool mIMECallComposeEnd; + PRBool mIMEIsBeingActivate; nsWindow* mIMEShellWindow; void SetXICSpotLocation(nsIMEGtkIC* aXIC, nsPoint aPoint); void SetXICBaseFontSize(nsIMEGtkIC* aXIC, int height); @@ -364,18 +357,18 @@ protected: int mXICFontSize; public: - nsIMEGtkIC* IMEGetInputContext(PRBool aCreate); + nsIMEGtkIC* IMEGetInputContext(PRBool aCreate); - void ime_preedit_start(); - void ime_preedit_draw(nsIMEGtkIC* aXIC); - void ime_preedit_done(); - void ime_status_draw(); + void ime_preedit_start(); + void ime_preedit_draw(nsIMEGtkIC* aXIC); + void ime_preedit_done(); + void ime_status_draw(); - void IMEUnsetFocusWindow(); - void IMESetFocusWindow(); - void IMEGetShellWindow(); - void IMEDestroyIC(); - void IMEBeingActivate(PRBool aActive); + void IMEUnsetFocusWindow(); + void IMESetFocusWindow(); + void IMEGetShellWindow(); + void IMEDestroyIC(); + void IMEBeingActivate(PRBool aActive); #endif // USE_XIM protected: @@ -397,24 +390,17 @@ private: GdkBitmap *window_mask); nsresult SetIcon(GdkPixmap *window_pixmap, GdkBitmap *window_mask); - + PRBool mLastGrabFailed; void NativeGrab(PRBool aGrab); - PRPackedBool mLastGrabFailed; - PRPackedBool mIsUpdating; - PRPackedBool mLeavePending; - PRPackedBool mRestoreFocus; - - PRPackedBool mIsTranslucent; - // This bitmap tracks which pixels are transparent. We don't support - // full translucency at this time; each pixel is either fully opaque - // or fully transparent. - gchar* mTransparencyBitmap; + PRBool mIsUpdating; void DestroyNativeChildren(void); GtkWindow *mTransientParent; + PRBool mLeavePending; + PRBool mRestoreFocus; }; // diff --git a/mozilla/widget/src/xpwidgets/nsBaseWidget.cpp b/mozilla/widget/src/xpwidgets/nsBaseWidget.cpp index 8268fd19d01..80d35f2edaf 100644 --- a/mozilla/widget/src/xpwidgets/nsBaseWidget.cpp +++ b/mozilla/widget/src/xpwidgets/nsBaseWidget.cpp @@ -482,26 +482,6 @@ NS_IMETHODIMP nsBaseWidget::SetWindowType(nsWindowType aWindowType) return NS_OK; } -//------------------------------------------------------------------------- -// -// Window transparency methods -// -//------------------------------------------------------------------------- - -NS_IMETHODIMP nsBaseWidget::SetWindowTranslucency(PRBool aTranslucent) { - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP nsBaseWidget::GetWindowTranslucency(PRBool& aTranslucent) { - aTranslucent = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP nsBaseWidget::UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas) { - NS_ASSERTION(PR_FALSE, "Window is not translucent"); - return NS_ERROR_NOT_IMPLEMENTED; -} - //------------------------------------------------------------------------- // // Hide window borders/decorations for this widget diff --git a/mozilla/widget/src/xpwidgets/nsBaseWidget.h b/mozilla/widget/src/xpwidgets/nsBaseWidget.h index 1b2da268b1a..2a6d5c87a33 100644 --- a/mozilla/widget/src/xpwidgets/nsBaseWidget.h +++ b/mozilla/widget/src/xpwidgets/nsBaseWidget.h @@ -99,9 +99,6 @@ public: NS_IMETHOD SetCursor(nsCursor aCursor); NS_IMETHOD GetWindowType(nsWindowType& aWindowType); NS_IMETHOD SetWindowType(nsWindowType aWindowType); - NS_IMETHOD SetWindowTranslucency(PRBool aTranslucent); - NS_IMETHOD GetWindowTranslucency(PRBool& aTranslucent); - NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas); NS_IMETHOD HideWindowChrome(PRBool aShouldHide); NS_IMETHOD MakeFullScreen(PRBool aFullScreen); virtual nsIRenderingContext* GetRenderingContext(); diff --git a/mozilla/xpfe/appshell/src/nsXULWindow.cpp b/mozilla/xpfe/appshell/src/nsXULWindow.cpp index dc20dab0674..0faee9d6460 100644 --- a/mozilla/xpfe/appshell/src/nsXULWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsXULWindow.cpp @@ -874,7 +874,6 @@ void nsXULWindow::OnChromeLoaded() LoadSizeStateFromXUL(); //LoadContentAreas(); - LoadChromeHidingFromXUL(); if (mCenterAfterLoad && !positionSet) Center(parentWindow, parentWindow ? PR_FALSE : PR_TRUE, PR_FALSE); @@ -884,25 +883,6 @@ void nsXULWindow::OnChromeLoaded() } } -nsresult nsXULWindow::LoadChromeHidingFromXUL() -{ - NS_ENSURE_STATE(mWindow); - - // Get element. - nsCOMPtr windowElement; - GetWindowDOMElement(getter_AddRefs(windowElement)); - NS_ENSURE_TRUE(windowElement, NS_ERROR_FAILURE); - - nsAutoString attr; - nsresult rv = windowElement->GetAttribute(NS_LITERAL_STRING("hidechrome"), attr); - - if (NS_SUCCEEDED(rv) && attr.EqualsIgnoreCase("true")) { - mWindow->HideWindowChrome(PR_TRUE); - } - - return NS_OK; -} - PRBool nsXULWindow::LoadPositionFromXUL() { nsresult rv; diff --git a/mozilla/xpfe/appshell/src/nsXULWindow.h b/mozilla/xpfe/appshell/src/nsXULWindow.h index 4c1c99c917d..293ea3384d3 100644 --- a/mozilla/xpfe/appshell/src/nsXULWindow.h +++ b/mozilla/xpfe/appshell/src/nsXULWindow.h @@ -80,7 +80,6 @@ protected: PRBool LoadPositionFromXUL(); PRBool LoadSizeFromXUL(); PRBool LoadSizeStateFromXUL(); - nsresult LoadChromeHidingFromXUL(); NS_IMETHOD LoadTitleFromXUL(); NS_IMETHOD LoadWindowClassFromXUL(); NS_IMETHOD LoadIconFromXUL();