зеркало из https://github.com/mozilla/pjs.git
backing out roc+%cs.cmu.edu check-in for bug 113232
This commit is contained in:
Родитель
0a6261ce8b
Коммит
fbab8a3edd
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче