backing out roc+%cs.cmu.edu check-in for bug 113232

This commit is contained in:
darin%netscape.com 2003-03-25 00:07:00 +00:00
Родитель 0a6261ce8b
Коммит fbab8a3edd
16 изменённых файлов: 254 добавлений и 881 удалений

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

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

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

@ -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++;
}

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

@ -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:
/** --------------------------------------------------------------------------

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

@ -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<nsIAtom> 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<nsIWidget> 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);
}
}

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

@ -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<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIDocument> 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<nsIWidget> 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);

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

@ -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<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIDocument> doc;
shell->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIDocument> 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<nsIWidget> 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);

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

@ -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<nsIAtom> 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<nsIWidget> 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);
}
}

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

@ -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<nsIRenderingContext> mCleanupContext;
nsCOMPtr<nsIRenderingContext> mOffScreenCX;
nsCOMPtr<nsIRenderingContext> mOffScreenWhiteCX;
nsCOMPtr<nsIRenderingContext> mBlackCX;
nsCOMPtr<nsIRenderingContext> 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<nsIWidget> 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)

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

@ -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<nsIBlender> mBlender;
nsIBlender *mBlender;
nsIRenderingContext *mOffScreenCX;
nsIRenderingContext *mBlackCX;
nsIRenderingContext *mWhiteCX;
nsISupportsArray *mCompositeListeners;
void DestroyZTreeNode(DisplayZTreeNode* aNode);

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

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

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

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

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

@ -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;
};
//

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

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

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

@ -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();

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

@ -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 <window> element.
nsCOMPtr<nsIDOMElement> 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;

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

@ -80,7 +80,6 @@ protected:
PRBool LoadPositionFromXUL();
PRBool LoadSizeFromXUL();
PRBool LoadSizeStateFromXUL();
nsresult LoadChromeHidingFromXUL();
NS_IMETHOD LoadTitleFromXUL();
NS_IMETHOD LoadWindowClassFromXUL();
NS_IMETHOD LoadIconFromXUL();