diff --git a/gfx/src/gtk/nsImageGTK.cpp b/gfx/src/gtk/nsImageGTK.cpp index f08a5b654567..5191aaff2feb 100644 --- a/gfx/src/gtk/nsImageGTK.cpp +++ b/gfx/src/gtk/nsImageGTK.cpp @@ -33,6 +33,9 @@ #define IsFlagSet(a,b) ((a) & (b)) +#define NS_GET_BIT(rowptr, x) (rowptr[(x)>>3] & (1<<(7-(x)&0x7))) +#define NS_SET_BIT(rowptr, x) (rowptr[(x)>>3] |= (1<<(7-(x)&0x7))) + // Defining this will trace the allocation of images. This includes // ctor, dtor and update. //#define TRACE_IMAGE_ALLOCATION @@ -61,17 +64,16 @@ nsImageGTK::nsImageGTK() mWidth = 0; mHeight = 0; mDepth = 0; - mAlphaBits = nsnull; + mAlphaBits = mTrueAlphaBits = nsnull; mAlphaPixmap = nsnull; mImagePixmap = nsnull; - mAlphaDepth = 0; + mAlphaDepth = mTrueAlphaDepth = 0; mRowBytes = 0; mSizeImage = 0; mAlphaHeight = 0; mAlphaWidth = 0; mNaturalWidth = 0; mNaturalHeight = 0; - mAlphaValid = PR_FALSE; mIsSpacer = PR_TRUE; mPendingUpdate = PR_FALSE; @@ -86,15 +88,20 @@ nsImageGTK::nsImageGTK() nsImageGTK::~nsImageGTK() { if(nsnull != mImageBits) { - delete[] (PRUint8*)mImageBits; + delete[] mImageBits; mImageBits = nsnull; } if (nsnull != mAlphaBits) { - delete[] (PRUint8*)mAlphaBits; + delete[] mAlphaBits; mAlphaBits = nsnull; } + if (nsnull != mTrueAlphaBits) { + delete[] mTrueAlphaBits; + mTrueAlphaBits = nsnull; + } + if (mAlphaPixmap) { gdk_pixmap_unref(mAlphaPixmap); } @@ -117,15 +124,20 @@ nsresult nsImageGTK::Init(PRInt32 aWidth, PRInt32 aHeight, g_return_val_if_fail ((aWidth != 0) || (aHeight != 0), NS_ERROR_FAILURE); if (nsnull != mImageBits) { - delete[] (PRUint8*)mImageBits; + delete[] mImageBits; mImageBits = nsnull; } if (nsnull != mAlphaBits) { - delete[] (PRUint8*)mAlphaBits; + delete[] mAlphaBits; mAlphaBits = nsnull; } + if (nsnull != mTrueAlphaBits) { + delete[] mTrueAlphaBits; + mTrueAlphaBits = nsnull; + } + if (nsnull != mAlphaPixmap) { gdk_pixmap_unref(mAlphaPixmap); mAlphaPixmap = nsnull; @@ -177,6 +189,16 @@ nsresult nsImageGTK::Init(PRInt32 aWidth, PRInt32 aHeight, mAlphaHeight = 0; break; + case nsMaskRequirements_kNeeds8Bit: + mTrueAlphaRowBytes = aWidth; + mTrueAlphaDepth = 8; + + // 32-bit align each row + mTrueAlphaRowBytes = (mTrueAlphaRowBytes + 3) & ~0x3; + mTrueAlphaBits = new PRUint8[mTrueAlphaRowBytes * aHeight]; + + // FALL THROUGH + case nsMaskRequirements_kNeeds1Bit: mAlphaRowBytes = (aWidth + 7) / 8; mAlphaDepth = 1; @@ -185,22 +207,15 @@ nsresult nsImageGTK::Init(PRInt32 aWidth, PRInt32 aHeight, mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3; mAlphaBits = new PRUint8[mAlphaRowBytes * aHeight]; - mAlphaWidth = aWidth; - mAlphaHeight = aHeight; - break; - - case nsMaskRequirements_kNeeds8Bit: - mAlphaRowBytes = aWidth; - mAlphaDepth = 8; - - // 32-bit align each row - mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3; - mAlphaBits = new PRUint8[mAlphaRowBytes * aHeight]; + memset(mAlphaBits, 0, mAlphaRowBytes*aHeight); mAlphaWidth = aWidth; mAlphaHeight = aHeight; break; } + if (aMaskRequirements == nsMaskRequirements_kNeeds8Bit) + mAlphaDepth = 0; + return NS_OK; } @@ -243,7 +258,10 @@ PRBool nsImageGTK::IsOptimized() PRUint8 *nsImageGTK::GetAlphaBits() { - return mAlphaBits; + if (mTrueAlphaBits) + return mTrueAlphaBits; + else + return mAlphaBits; } PRInt32 nsImageGTK::GetAlphaWidth() @@ -259,7 +277,10 @@ PRInt32 nsImageGTK::GetAlphaHeight() PRInt32 nsImageGTK::GetAlphaLineStride() { - return mAlphaRowBytes; + if (mTrueAlphaBits) + return mTrueAlphaRowBytes; + else + return mAlphaRowBytes; } nsIImage *nsImageGTK::DuplicateImage() @@ -310,16 +331,44 @@ void nsImageGTK::UpdateCachedImage() right = left + rect->width; // check if the image has an all-opaque 8-bit alpha mask - if ((mAlphaDepth==8) && !mAlphaValid) { - for (unsigned y=rect->y; (yy; + (yx, rect->y); } } - + mUpdateRegion.Empty(); mPendingUpdate = PR_FALSE; mFlags = nsImageUpdateFlags_kBitsChanged; // this should be 0'd out by Draw() @@ -455,7 +499,7 @@ nsImageGTK::DrawScaled(nsIRenderingContext &aContext, CreateAlphaBitmap(mWidth, mHeight); } - if ((mAlphaDepth==8) && mAlphaValid) { + if (mAlphaDepth==8) { DrawComposited(aContext, aSurface, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight); @@ -605,7 +649,7 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0) return NS_OK; - if ((mAlphaDepth==8) && mAlphaValid) { + if (mAlphaDepth==8) { DrawComposited(aContext, aSurface, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aSWidth, aSHeight); @@ -1261,7 +1305,7 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, if ((mAlphaDepth==1) && mIsSpacer) return NS_OK; - if ((mAlphaDepth==8) && mAlphaValid) { + if (mAlphaDepth==8) { DrawComposited(aContext, aSurface, 0, 0, aWidth, aHeight, aX, aY, aWidth, aHeight); return NS_OK; } @@ -1472,7 +1516,7 @@ NS_IMETHODIMP nsImageGTK::DrawTile(nsIRenderingContext &aContext, return NS_OK; } - if (partial || ((mAlphaDepth == 8) && mAlphaValid)) { + if (partial || (mAlphaDepth == 8)) { #ifdef DEBUG_TILING printf("Warning: using slow tiling\n"); #endif @@ -1695,9 +1739,6 @@ NS_IMETHODIMP nsImageGTK::DrawToImage(nsIImage* aDstImage, PRUint8 *src = rgbPtr + y*rgbStride; PRUint8 *alpha = alphaPtr + y*alphaStride; for (int x=0; x>3] & (1<<(7-(x)&0x7))) -#define NS_SET_BIT(rowptr, x) (rowptr[(x)>>3] |= (1<<(7-(x)&0x7))) - // if this pixel is opaque then copy into the destination image if (NS_GET_BIT(alpha, x)) { dst[0] = src[0]; @@ -1705,9 +1746,6 @@ NS_IMETHODIMP nsImageGTK::DrawToImage(nsIImage* aDstImage, dst[2] = src[2]; NS_SET_BIT(dstAlpha, aDX+x); } - -#undef NS_GET_BIT -#undef NS_SET_BIT } } break; diff --git a/gfx/src/gtk/nsImageGTK.h b/gfx/src/gtk/nsImageGTK.h index 039aa027c385..38ced543c455 100644 --- a/gfx/src/gtk/nsImageGTK.h +++ b/gfx/src/gtk/nsImageGTK.h @@ -123,7 +123,12 @@ public: * @update - lordpixel 2001/05/16 * @return the alpha mask depth for the image, ie, 0, 1 or 8 */ - virtual PRInt8 GetAlphaDepth() {return(mAlphaDepth);} + virtual PRInt8 GetAlphaDepth() { + if (mTrueAlphaBits) + return mTrueAlphaDepth; + else + return mAlphaDepth; + } virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY); NS_IMETHOD LockImagePixels(PRBool aMaskPixels); @@ -189,6 +194,7 @@ private: PRUint8 *mImageBits; GdkPixmap *mImagePixmap; + PRUint8 *mTrueAlphaBits; PRUint8 *mAlphaBits; GdkPixmap *mAlphaPixmap; @@ -209,10 +215,11 @@ private: // alpha layer members PRInt16 mAlphaRowBytes; // alpha bytes per row + PRInt16 mTrueAlphaRowBytes; // alpha bytes per row PRInt16 mAlphaWidth; // alpha layer width PRInt16 mAlphaHeight; // alpha layer height PRInt8 mAlphaDepth; // alpha layer depth - PRPackedBool mAlphaValid; + PRInt8 mTrueAlphaDepth; // alpha layer depth PRPackedBool mIsSpacer; PRPackedBool mPendingUpdate;