b=326738, move thebes doublebuffering/transparent window handling into widget, sr=roc
git-svn-id: svn://10.0.0.236/trunk@190158 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -67,6 +67,7 @@ struct nsBoundingMetrics;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
class gfxASurface;
|
||||
class gfxContext;
|
||||
#endif
|
||||
|
||||
/* gfx2 */
|
||||
@@ -137,6 +138,14 @@ public:
|
||||
* @result The result of the initialization, NS_Ok if no errors
|
||||
*/
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, gfxASurface* aThebesSurface) = 0;
|
||||
|
||||
/**
|
||||
* Initialize the RenderingContext
|
||||
* @param aContext the device context to use for the drawing.
|
||||
* @param aThebesContext an existing thebes context to use for the drawing
|
||||
* @result The result of the initialization, NS_Ok if no errors
|
||||
*/
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, gfxContext* aThebesContext) = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,6 +112,22 @@ nsThebesRenderingContext::Init(nsIDeviceContext* aContext, gfxASurface *aThebesS
|
||||
return (CommonInit());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::Init(nsIDeviceContext* aContext, gfxContext *aThebesContext)
|
||||
{
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::Init ctx %p thebesContext %p\n", this, aContext, aThebesContext));
|
||||
|
||||
mDeviceContext = aContext;
|
||||
mWidget = nsnull;
|
||||
|
||||
mLocalDrawingSurface = nsnull;
|
||||
mDrawingSurface = nsnull;
|
||||
|
||||
mThebes = aThebesContext;
|
||||
|
||||
return (CommonInit());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::Init(nsIDeviceContext* aContext, nsIWidget *aWidget)
|
||||
{
|
||||
@@ -160,11 +176,8 @@ nsThebesRenderingContext::CommonInit(void)
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::Reset(void)
|
||||
{
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::Reset\n", this));
|
||||
|
||||
mThebes = new gfxContext(mDrawingSurface->GetThebesSurface());
|
||||
|
||||
return (CommonInit());
|
||||
NS_ERROR("nsThebesRenderingContext::Reset called!\n");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -178,22 +191,15 @@ nsThebesRenderingContext::GetDeviceContext(nsIDeviceContext *& aDeviceContext)
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::SelectOffScreenDrawingSurface(nsIDrawingSurface *aSurface)
|
||||
{
|
||||
if (aSurface)
|
||||
mDrawingSurface = NS_STATIC_CAST(nsThebesDrawingSurface*, aSurface);
|
||||
else
|
||||
mDrawingSurface = mLocalDrawingSurface;
|
||||
|
||||
mThebes->SetTarget(mDrawingSurface->GetThebesSurface());
|
||||
|
||||
return NS_OK;
|
||||
NS_ERROR("nsThebesRenderingContext::SelectOffScreenDrawingSurface called!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::GetDrawingSurface(nsIDrawingSurface **aSurface)
|
||||
{
|
||||
*aSurface = mDrawingSurface;
|
||||
// don't addref! this isn't an xpcom call even though it sure looks like one
|
||||
return NS_OK;
|
||||
NS_ERROR("nsThebesRenderingContext::GetDrawingSurface called!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -773,7 +779,7 @@ nsThebesRenderingContext::GetNativeGraphicData(GraphicDataType aType)
|
||||
if (aType == NATIVE_WINDOWS_DC) {
|
||||
nsRefPtr<gfxASurface> surf = mThebes->CurrentGroupSurface();
|
||||
if (!surf)
|
||||
mThebes->CurrentSurface();
|
||||
surf = mThebes->CurrentSurface();
|
||||
|
||||
return cairo_win32_surface_get_dc(surf->CairoSurface());
|
||||
}
|
||||
@@ -1083,10 +1089,6 @@ nsThebesRenderingContext::DrawTile(imgIContainer *aImage,
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIDrawingSurface *surface = nsnull;
|
||||
GetDrawingSurface(&surface);
|
||||
if (!surface) return NS_ERROR_FAILURE;
|
||||
|
||||
/* bug 113561 - frame can be smaller than container */
|
||||
nsIntRect pxImgFrameRect;
|
||||
imgFrame->GetRect(pxImgFrameRect);
|
||||
@@ -1098,7 +1100,7 @@ nsThebesRenderingContext::DrawTile(imgIContainer *aImage,
|
||||
NSToIntRound(FROM_TWIPS(twDr.width)),
|
||||
NSToIntRound(FROM_TWIPS(twDr.height)));
|
||||
|
||||
return img->DrawTile(*this, surface,
|
||||
return img->DrawTile(*this, NULL,
|
||||
pxXOffset - pxImgFrameRect.x, pxYOffset - pxImgFrameRect.y,
|
||||
pxPadX, pxPadY,
|
||||
pxDr);
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, gfxASurface* aThebesSurface);
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, gfxContext* aThebesContext);
|
||||
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget);
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface *aSurface);
|
||||
|
||||
@@ -48,7 +48,9 @@ class NS_EXPORT gfxWindowsSurface : public gfxASurface {
|
||||
public:
|
||||
gfxWindowsSurface(HWND wnd);
|
||||
gfxWindowsSurface(HDC dc, PRBool deleteDC = PR_FALSE);
|
||||
gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height);
|
||||
gfxWindowsSurface(HDC dc,
|
||||
unsigned long width, unsigned long height,
|
||||
gfxImageFormat imageFormat = ImageFormatRGB24);
|
||||
virtual ~gfxWindowsSurface();
|
||||
|
||||
HDC GetDC() { return mDC; }
|
||||
|
||||
@@ -303,7 +303,13 @@ gfxWindowsTextRun::MeasureOrDrawUniscribe(gfxContext *aContext,
|
||||
const PRUnichar *aString, PRUint32 aLength,
|
||||
PRBool aDraw, PRInt32 aX, PRInt32 aY, const PRInt32 *aSpacing)
|
||||
{
|
||||
HDC aDC = static_cast<gfxWindowsSurface*>(aContext->CurrentSurface())->GetDC();
|
||||
nsRefPtr<gfxASurface> surf = aContext->CurrentGroupSurface();
|
||||
if (!surf)
|
||||
surf = aContext->CurrentSurface();
|
||||
|
||||
HDC aDC = cairo_win32_surface_get_dc(surf->CairoSurface());
|
||||
|
||||
int knownGoodDCState = SaveDC(aDC);
|
||||
|
||||
int loops = 0;
|
||||
|
||||
@@ -507,7 +513,17 @@ TRY_AGAIN_SAME_SCRIPT:
|
||||
RestoreDC(aDC, -1);
|
||||
#else
|
||||
/* Draw using cairo */
|
||||
|
||||
/* XXX cairo sets a world transform in order to get subpixel accuracy in some cases;
|
||||
* this breaks it there's a surface fallback that happens with clipping, because
|
||||
* the clip gets applied with the world transform and the world breaks. Doing this
|
||||
* RestoreDC fixes things until we can fix the win32 font stuff.
|
||||
*/
|
||||
RestoreDC(aDC, knownGoodDCState);
|
||||
|
||||
cairo_show_glyphs(cr, cglyphs, numGlyphs);
|
||||
|
||||
knownGoodDCState = SaveDC(aDC);
|
||||
#endif
|
||||
free(cglyphs);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ gfxWindowsPlatform::CreateOffscreenSurface(PRUint32 width,
|
||||
PRUint32 height,
|
||||
gfxASurface::gfxImageFormat imageFormat)
|
||||
{
|
||||
return new gfxWindowsSurface(nsnull, width, height);
|
||||
return new gfxWindowsSurface(nsnull, width, height, imageFormat);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@@ -53,51 +53,19 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, PRBool deleteDC) :
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height) :
|
||||
mOwnsDC(PR_TRUE), mWnd(nsnull)
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height, gfxImageFormat imageFormat) :
|
||||
mOwnsDC(PR_FALSE), mWnd(nsnull)
|
||||
{
|
||||
mDC = ::CreateCompatibleDC(dc);
|
||||
|
||||
// set the clip region on it so that cairo knows the surface
|
||||
// dimensions
|
||||
HRGN clipRegion = ::CreateRectRgn(0, 0, width, height);
|
||||
if (::SelectClipRgn(mDC, clipRegion) == ERROR) {
|
||||
NS_ERROR("gfxWindowsSurface: SelectClipRgn failed\n");
|
||||
}
|
||||
::DeleteObject(clipRegion);
|
||||
|
||||
HBITMAP bmp = nsnull;
|
||||
if (dc) {
|
||||
// Create a DDB if we can -- this is faster.
|
||||
|
||||
// Creating with width or height of 0 will create a
|
||||
// 1x1 monotone bitmap, which isn't what we want
|
||||
bmp = ::CreateCompatibleBitmap(dc, PR_MAX(2, width), PR_MAX(2, height));
|
||||
} else {
|
||||
// Otherwise, create a DIB -- this is slower.
|
||||
BITMAPINFO bmpInfo;
|
||||
unsigned char *bits = NULL;
|
||||
// At some point we might want to revisit creating a DDB
|
||||
// with CreateCompatibleDC, but from stuff that I've read
|
||||
// that's only useful for terminal services clients.
|
||||
|
||||
/* initialize the bitmapinfoheader */
|
||||
memset(&bmpInfo.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
|
||||
bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||
bmpInfo.bmiHeader.biWidth = width;
|
||||
bmpInfo.bmiHeader.biHeight = -(long)height;
|
||||
bmpInfo.bmiHeader.biPlanes = 1;
|
||||
bmpInfo.bmiHeader.biBitCount = 24;
|
||||
bmpInfo.bmiHeader.biCompression = BI_RGB;
|
||||
Init(cairo_win32_surface_create_dib((cairo_format_t)imageFormat,
|
||||
width, height));
|
||||
|
||||
/* create a DIBSection */
|
||||
bmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
|
||||
/* Flush GDI to make sure the DIBSection is actually created */
|
||||
GdiFlush();
|
||||
}
|
||||
|
||||
/* Select the bitmap in to the DC */
|
||||
mOrigBitmap = (HBITMAP)::SelectObject(mDC, bmp);
|
||||
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
mDC = cairo_win32_surface_get_dc(CairoSurface());
|
||||
}
|
||||
|
||||
gfxWindowsSurface::~gfxWindowsSurface()
|
||||
|
||||
@@ -610,34 +610,13 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
||||
float t2p = mContext->AppUnitsToDevUnits();
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
nsRefPtr<gfxContext> ctx = (gfxContext*) localcx->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||
PRBool usingDoubleBuffer = (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER);
|
||||
nsRefPtr<gfxContext> ctx =
|
||||
(gfxContext*) localcx->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||
|
||||
ctx->Save();
|
||||
|
||||
ctx->Translate(gfxPoint(NSToIntRound(viewRect.x * t2p), NSToIntRound(viewRect.y * t2p)));
|
||||
ctx->NewPath();
|
||||
|
||||
if (aRegion) {
|
||||
nsRegionRectSet *rs = nsnull;
|
||||
aRegion->GetRects(&rs);
|
||||
for (int i = 0; i < rs->mNumRects; i++) {
|
||||
ctx->Rectangle(gfxRect(rs->mRects[i].x,
|
||||
rs->mRects[i].y,
|
||||
rs->mRects[i].width,
|
||||
rs->mRects[i].height));
|
||||
}
|
||||
aRegion->FreeRects(rs);
|
||||
}
|
||||
|
||||
ctx->Rectangle(gfxRect(NSToIntRound(damageRect.x * t2p),
|
||||
NSToIntRound(damageRect.y * t2p),
|
||||
NSToIntRound(damageRect.width * t2p),
|
||||
NSToIntRound(damageRect.height * t2p)));
|
||||
ctx->Clip();
|
||||
|
||||
if (usingDoubleBuffer)
|
||||
ctx->PushGroup(gfxContext::CONTENT_COLOR);
|
||||
ctx->Translate(gfxPoint(NSToIntRound(viewRect.x * t2p),
|
||||
NSToIntRound(viewRect.y * t2p)));
|
||||
|
||||
nsRegion opaqueRegion;
|
||||
AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView);
|
||||
@@ -645,12 +624,6 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
||||
|
||||
RenderViews(aView, *localcx, damageRegion, ds);
|
||||
|
||||
if (usingDoubleBuffer) {
|
||||
ctx->PopGroupToSource();
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
ctx->Restore();
|
||||
#else
|
||||
// widgetDamageRectInPixels is the clipped damage area bounds,
|
||||
@@ -857,6 +830,7 @@ void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceCo
|
||||
void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
|
||||
const nsRegion& aRegion, nsIDrawingSurface* aRCSurface)
|
||||
{
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
nsIWidget* widget = aView->GetWidget();
|
||||
PRBool translucentWindow = PR_FALSE;
|
||||
if (widget) {
|
||||
@@ -873,6 +847,7 @@ void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
|
||||
NS_ASSERTION(buffers, "Failed to create rendering buffers");
|
||||
if (!buffers)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (mObserver) {
|
||||
nsView* displayRoot = GetDisplayRootFor(aView);
|
||||
@@ -886,6 +861,7 @@ void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
|
||||
aRC.PopState();
|
||||
}
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
if (translucentWindow) {
|
||||
// Get the alpha channel into an array so we can send it to the widget
|
||||
nsRect r = aRegion.GetBounds();
|
||||
@@ -902,6 +878,7 @@ void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
|
||||
}
|
||||
|
||||
delete buffers;
|
||||
#endif
|
||||
}
|
||||
|
||||
static nsresult NewOffscreenContext(nsIDeviceContext* deviceContext, nsIDrawingSurface* surface,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@@ -855,10 +855,6 @@ class nsIWidget : public nsISupports {
|
||||
virtual nsIRenderingContext* GetRenderingContext() = 0;
|
||||
virtual nsIDeviceContext* GetDeviceContext() = 0;
|
||||
virtual nsIAppShell *GetAppShell() = 0;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
virtual gfxASurface *GetThebesSurface() = 0;
|
||||
#endif
|
||||
//@}
|
||||
|
||||
/**
|
||||
@@ -1043,6 +1039,12 @@ class nsIWidget : public nsISupports {
|
||||
*/
|
||||
NS_IMETHOD GetLastInputEventTime(PRUint32& aTime) = 0;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
/**
|
||||
* Get the Thebes surface associated with this widget.
|
||||
*/
|
||||
virtual gfxASurface *GetThebesSurface() = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// keep the list of children. We also keep track of our siblings.
|
||||
|
||||
@@ -87,8 +87,10 @@
|
||||
#include "resource.h"
|
||||
#include <commctrl.h>
|
||||
#include "prtime.h"
|
||||
#ifdef MOZ_THEBES
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
#include "nsIThebesRenderingContext.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#else
|
||||
#include "nsIRenderingContextWin.h"
|
||||
#endif
|
||||
@@ -5637,21 +5639,54 @@ PRBool nsWindow::OnPaint(HDC aDC)
|
||||
#endif // NS_DEBUG
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
|
||||
nsRefPtr<gfxASurface> targetSurface = new gfxWindowsSurface(hDC);
|
||||
nsRefPtr<gfxContext> thebesContext = new gfxContext(targetSurface);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (mIsTranslucent && IsAlphaTranslucencySupported()) {
|
||||
// If we're rendering with translucency, we're going to be
|
||||
// rendering the whole window; make sure we clear it first
|
||||
thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
thebesContext->Paint();
|
||||
thebesContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
} else {
|
||||
// If we're not doing translucency, then double buffer
|
||||
thebesContext->PushGroup(gfxContext::CONTENT_COLOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CreateRenderingContextInstance failed");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
rv = rc->Init(mContext, thebesContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("RC::Init failed");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
event.renderingContext = rc;
|
||||
result = DispatchWindowEvent(&event, eventStatus);
|
||||
event.renderingContext = nsnull;
|
||||
|
||||
if (mIsTranslucent && IsAlphaTranslucencySupported())
|
||||
{
|
||||
#ifdef MOZ_XUL
|
||||
if (mIsTranslucent && IsAlphaTranslucencySupported()) {
|
||||
// Data from offscreen drawing surface was copied to memory bitmap of transparent
|
||||
// bitmap. Now it can be read from memory bitmap to apply alpha channel and after
|
||||
// that displayed on the screen.
|
||||
UpdateTranslucentWindow();
|
||||
} else {
|
||||
thebesContext->PopGroupToSource();
|
||||
thebesContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
thebesContext->Paint();
|
||||
}
|
||||
rc = nsnull;
|
||||
#else
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Non-cairo GFX */
|
||||
if (NS_SUCCEEDED(CallCreateInstance(kRenderingContextCID, &event.renderingContext)))
|
||||
{
|
||||
nsIRenderingContextWin *winrc;
|
||||
@@ -8002,8 +8037,6 @@ nsWindow* nsWindow::GetTopLevelWindow()
|
||||
}
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
#include "gfxWindowsSurface.h"
|
||||
|
||||
gfxASurface *nsWindow::GetThebesSurface()
|
||||
{
|
||||
if (mPaintDC)
|
||||
@@ -8013,11 +8046,12 @@ gfxASurface *nsWindow::GetThebesSurface()
|
||||
}
|
||||
#endif
|
||||
|
||||
void nsWindow::ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight)
|
||||
void nsWindow::ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight, PRBool force)
|
||||
{
|
||||
if (aNewWidth == mBounds.width && aNewHeight == mBounds.height)
|
||||
if (!force && aNewWidth == mBounds.width && aNewHeight == mBounds.height)
|
||||
return;
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// resize the alpha mask
|
||||
PRUint8* pBits;
|
||||
|
||||
@@ -8025,7 +8059,7 @@ void nsWindow::ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight)
|
||||
{
|
||||
pBits = new PRUint8 [aNewWidth * aNewHeight];
|
||||
|
||||
if (pBits)
|
||||
if (pBits && mAlphaMask)
|
||||
{
|
||||
PRInt32 copyWidth, copyHeight;
|
||||
PRInt32 growWidth, growHeight;
|
||||
@@ -8072,15 +8106,23 @@ void nsWindow::ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight)
|
||||
|
||||
delete [] mAlphaMask;
|
||||
mAlphaMask = pBits;
|
||||
|
||||
#endif
|
||||
|
||||
if (IsAlphaTranslucencySupported())
|
||||
{
|
||||
// Always use at least 24-bit bitmaps regardless of the device context.
|
||||
if (!w2k.mMemoryDC)
|
||||
w2k.mMemoryDC = ::CreateCompatibleDC(NULL);
|
||||
|
||||
// Always use at least 24-bit (32 with cairo) bitmaps regardless of the device context.
|
||||
int depth = ::GetDeviceCaps(w2k.mMemoryDC, BITSPIXEL);
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
if (depth < 32)
|
||||
depth = 32;
|
||||
#else
|
||||
if (depth < 24)
|
||||
depth = 24;
|
||||
|
||||
#endif
|
||||
|
||||
// resize the memory bitmap
|
||||
BITMAPINFO bi = { 0 };
|
||||
bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||
@@ -8192,52 +8234,26 @@ nsresult nsWindow::SetWindowTranslucencyInner(PRBool aTranslucent)
|
||||
|
||||
nsresult nsWindow::SetupTranslucentWindowMemoryBitmap(PRBool aTranslucent)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (aTranslucent)
|
||||
{
|
||||
w2k.mMemoryDC = ::CreateCompatibleDC(NULL);
|
||||
|
||||
if (aTranslucent) {
|
||||
ResizeTranslucentWindow(mBounds.width, mBounds.height, PR_TRUE);
|
||||
} else {
|
||||
if (w2k.mMemoryDC)
|
||||
{
|
||||
// Always use at least 24-bit bitmaps regardless of the device context.
|
||||
int depth = ::GetDeviceCaps(w2k.mMemoryDC, BITSPIXEL);
|
||||
if (depth < 24)
|
||||
depth = 24;
|
||||
|
||||
BITMAPINFO bi = { 0 };
|
||||
bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = mBounds.width;
|
||||
bi.bmiHeader.biHeight = -mBounds.height;
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = depth;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
w2k.mMemoryBitmap = ::CreateDIBSection(w2k.mMemoryDC, &bi, DIB_RGB_COLORS, (void**)&w2k.mMemoryBits, NULL, 0);
|
||||
|
||||
if (w2k.mMemoryBitmap)
|
||||
{
|
||||
::SelectObject(w2k.mMemoryDC, w2k.mMemoryBitmap);
|
||||
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
::DeleteDC(w2k.mMemoryDC);
|
||||
::DeleteObject(w2k.mMemoryBitmap);
|
||||
::DeleteDC(w2k.mMemoryDC);
|
||||
if (w2k.mMemoryBitmap)
|
||||
::DeleteObject(w2k.mMemoryBitmap);
|
||||
|
||||
w2k.mMemoryDC = NULL;
|
||||
w2k.mMemoryBitmap = NULL;
|
||||
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsWindow::UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* aAlphas)
|
||||
{
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
NS_ERROR("nsWindow::UpdateTranslucentWindowAlphaInner called, when it sholdn't be!");
|
||||
#else
|
||||
NS_ASSERTION(mIsTranslucent, "Window is not transparent");
|
||||
NS_ASSERTION(aRect.x >= 0 && aRect.y >= 0 &&
|
||||
aRect.XMost() <= mBounds.width && aRect.YMost() <= mBounds.height,
|
||||
@@ -8292,6 +8308,7 @@ void nsWindow::UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* a
|
||||
if (transparencyMaskChanged)
|
||||
SetWindowRegionToAlphaMask();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult nsWindow::UpdateTranslucentWindow()
|
||||
@@ -8303,13 +8320,24 @@ nsresult nsWindow::UpdateTranslucentWindow()
|
||||
|
||||
::GdiFlush();
|
||||
|
||||
HDC hMemoryDC;
|
||||
HBITMAP hAlphaBitmap;
|
||||
PRBool needConversion;
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
|
||||
hMemoryDC = w2k.mMemoryDC;
|
||||
needConversion = PR_FALSE;
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
#else
|
||||
|
||||
int depth = ::GetDeviceCaps(w2k.mMemoryDC, BITSPIXEL);
|
||||
if (depth < 24)
|
||||
depth = 24;
|
||||
|
||||
HDC hMemoryDC;
|
||||
HBITMAP hAlphaBitmap;
|
||||
PRBool needConversion = (depth == 24);
|
||||
needConversion = (depth == 24);
|
||||
|
||||
if (needConversion)
|
||||
{
|
||||
@@ -8372,7 +8400,7 @@ nsresult nsWindow::UpdateTranslucentWindow()
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZ_CAIRO_GFX */
|
||||
|
||||
if (rv == NS_OK)
|
||||
{
|
||||
|
||||
@@ -212,7 +212,7 @@ private:
|
||||
nsresult SetWindowTranslucencyInner(PRBool aTransparent);
|
||||
PRBool GetWindowTranslucencyInner() { return mIsTranslucent; }
|
||||
void UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* aAlphas);
|
||||
void ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight);
|
||||
void ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight, PRBool force = PR_FALSE);
|
||||
nsresult UpdateTranslucentWindow();
|
||||
nsresult SetupTranslucentWindowMemoryBitmap(PRBool aTranslucent);
|
||||
void SetWindowRegionToAlphaMask();
|
||||
|
||||
Reference in New Issue
Block a user