Fixes for 18029 and 16723 -- fix image drawing on Mac to use GWorlds, and put in api to lock and unlock pixels. r=pnunn, a=chofmann.

This commit is contained in:
sfraser@netscape.com
1999-11-04 22:26:57 +00:00
parent c6e7d18b85
commit a9f23f9978
21 changed files with 729 additions and 273 deletions

View File

@@ -105,10 +105,18 @@ public:
/**
* Get the number of bytes needed to get to the next scanline for the pixelmap
* @update - dwc 2/1/99
@return The number of bytes in each scanline
* @return The number of bytes in each scanline
*/
virtual PRInt32 GetLineStride() = 0;
/**
* Get whether this image has an alpha mask. Preferable to testing
* if GetAlphaBits() is non-null.
* @update - sfraser 10/19/99
* @return PR_TRUE if the image has an alpha mask, PR_FALSE otherwise
*/
virtual PRBool GetHasAlphaMask() = 0;
/**
* Get a pointer to the bits for the alpha mask
* @update - dwc 2/1/99
@@ -217,6 +225,34 @@ public:
*/
virtual void* GetBitInfo() = 0;
/**
* LockImagePixels
* Lock the image pixels so that we can access them directly,
* with safely. May be a noop on some platforms.
*
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
*
* Must be balanced by a call to UnlockImagePixels().
*
* @update - sfraser 10/18/99
* @return error result
*/
NS_IMETHOD LockImagePixels(PRBool aMaskPixels) = 0;
/**
* UnlockImagePixels
* Unlock the image pixels. May be a noop on some platforms.
*
* Should balance an earlier call to LockImagePixels().
*
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
*
* @update - sfraser 10/18/99
* @return error result
*/
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels) = 0;
//get the color space metrics for this image
//virtual NI_ColorSpec * GetColorSpec() = 0; fix

View File

@@ -463,3 +463,19 @@ nsresult nsImageBeOS::Optimize(nsIDeviceContext* aContext)
mStaticImage = PR_TRUE;
return NS_OK;
}
//------------------------------------------------------------
// lock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageBeOS::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageBeOS::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -43,6 +43,8 @@ public:
virtual void* GetBitInfo();
virtual PRInt32 GetLineStride();
virtual nsColorMap* GetColorMap();
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
NS_IMETHOD Draw(nsIRenderingContext &aContext,
nsDrawingSurface aSurface,
PRInt32 aX, PRInt32 aY,
@@ -76,6 +78,9 @@ public:
virtual PRInt32 GetAlphaLevel();
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY);
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Calculate the amount of memory needed for the initialization of the image

View File

@@ -599,3 +599,19 @@ nsresult nsImageGTK::Optimize(nsIDeviceContext* aContext)
{
return NS_OK;
}
//------------------------------------------------------------
// lock the image pixels. nothing to do on gtk
NS_IMETHODIMP
nsImageGTK::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. nothing to do on gtk
NS_IMETHODIMP
nsImageGTK::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -62,6 +62,8 @@ public:
virtual PRBool IsOptimized();
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaWidth();
virtual PRInt32 GetAlphaHeight();
@@ -78,6 +80,9 @@ public:
virtual PRInt32 GetAlphaLevel();
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY);
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Calculate the amount of memory needed for the initialization of the image

View File

@@ -25,18 +25,55 @@
static NS_DEFINE_IID(kIImageIID, NS_IIMAGE_IID);
/** ------------------------------------------------------------
* Utility class for saving, locking, and restoring pixel state
*/
class StPixelLocker
{
public:
StPixelLocker(PixMapHandle thePixMap)
: mPixMap(thePixMap)
{
mPixelState = ::GetPixelsState(mPixMap);
::LockPixels(mPixMap);
}
~StPixelLocker()
{
::SetPixelsState(mPixMap, mPixelState);
}
protected:
PixMapHandle mPixMap;
GWorldFlags mPixelState;
};
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
nsImageMac::nsImageMac()
: mImageGWorld(nsnull)
, mWidth(0)
, mHeight(0)
, mRowBytes(0)
, mBytesPerPixel(0)
, mAlphaGWorld(nsnull)
, mAlphaDepth(0)
, mAlphaWidth(0)
, mAlphaHeight(0)
, mARowBytes(0)
, mIsTopToBottom(PR_TRUE)
, mPixelDataSize(0)
{
NS_INIT_REFCNT();
mThePixelmap.baseAddr = nsnull;
mImageBits = nsnull;
mWidth = 0;
mHeight = 0;
}
/** ---------------------------------------------------
@@ -45,13 +82,12 @@ nsImageMac :: nsImageMac()
*/
nsImageMac::~nsImageMac()
{
if(mImageBits)
delete[] mImageBits;
if (mImageGWorld)
::DisposeGWorld(mImageGWorld);
if (mAlphaGWorld)
::DisposeGWorld(mAlphaGWorld);
if(mAlphaBits){
delete mAlphaPix;
delete [] mAlphaBits;
}
}
NS_IMPL_ISUPPORTS(nsImageMac, kIImageIID);
@@ -63,9 +99,53 @@ NS_IMPL_ISUPPORTS(nsImageMac, kIImageIID);
PRUint8*
nsImageMac::GetBits()
{
return mImageBits;
if (!mImageGWorld)
{
NS_ASSERTION(0, "Getting bits for non-existent image");
return nsnull;
}
PixMapHandle thePixMap = ::GetGWorldPixMap(mImageGWorld);
// pixels should be locked here!
#if DEBUG
GWorldFlags pixelFlags = GetPixelsState(thePixMap);
NS_ASSERTION(pixelFlags & pixelsLocked, "Pixels must be locked here");
#endif
Ptr pixels = ::GetPixBaseAddr(thePixMap);
NS_ASSERTION(pixels, "Getting bits for image failed");
return (PRUint8 *)pixels;
}
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
PRUint8*
nsImageMac::GetAlphaBits()
{
if (!mAlphaGWorld)
{
NS_ASSERTION(0, "Getting alpha bits for non-existent mask");
return nsnull;
}
PixMapHandle thePixMap = GetGWorldPixMap(mAlphaGWorld);
// pixels should be locked here!
#if DEBUG
GWorldFlags pixelFlags = GetPixelsState(thePixMap);
NS_ASSERTION(pixelFlags & pixelsLocked, "Pixels must be locked here");
#endif
Ptr pixels = GetPixBaseAddr(thePixMap);
NS_ASSERTION(pixels, "Getting alpha bits failed");
return (PRUint8 *)pixels;
}
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update 08/03/99 -- cleared out the image pointer - dwc
@@ -73,137 +153,121 @@ nsImageMac::GetBits()
nsresult
nsImageMac::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
{
PRInt32 bufferdepth;
if(nsnull==mImageBits){
delete [] mImageBits;
// have we already been initted?
if (mImageGWorld)
{
NS_ASSERTION(0, "Initting image twice");
::DisposeGWorld(mImageGWorld);
mImageGWorld = nsnull;
}
switch(aDepth){
case 8:
mThePixelmap.pixelType = 0;
mThePixelmap.cmpCount = 1;
mThePixelmap.cmpSize = 8;
mThePixelmap.pmTable = GetCTable(8);
bufferdepth = 8;
break;
case 16:
mThePixelmap.pixelType = 16;
mThePixelmap.cmpCount = 3;
mThePixelmap.cmpSize = 5;
mThePixelmap.pmTable = 0;
bufferdepth = 16;
break;
case 24: // 24 and 32 bit are basically the same
case 32:
mThePixelmap.pixelType = 16;
mThePixelmap.cmpCount = 3;
mThePixelmap.cmpSize = 8;
mThePixelmap.pmTable = 0;
bufferdepth = 32;
break;
default:
mThePixelmap.cmpCount = 0;
break;
}
if(mThePixelmap.cmpCount){
mRowBytes = CalcBytesSpan(aWidth,bufferdepth);
mSizeImage = mRowBytes*aHeight;
mImageBits = new unsigned char[mSizeImage];
}
if(mImageBits){
memset(mImageBits,0,mSizeImage); // clear out any garbage
mThePixelmap.baseAddr = (char*) mImageBits;
mThePixelmap.rowBytes = mRowBytes | 0x8000;
mThePixelmap.bounds.top = 0;
mThePixelmap.bounds.left = 0;
mThePixelmap.bounds.bottom = aHeight;
mThePixelmap.bounds.right = aWidth;
mThePixelmap.pixelSize = bufferdepth;
mThePixelmap.packType = 0;
mThePixelmap.packSize = 0;
mThePixelmap.hRes = nsDeviceContextMac::GetScreenResolution()<<16;
mThePixelmap.vRes = nsDeviceContextMac::GetScreenResolution()<<16;
#if TARGET_CARBON
mThePixelmap.pixelFormat = 0; /*fourCharCode representation*/
mThePixelmap.pmTable = 0; /*color map for this pixMap*/
mThePixelmap.pmExt = 0;
#else
mThePixelmap.planeBytes = 0;
mThePixelmap.pmReserved = 0;
#endif
mThePixelmap.pmVersion = 0;
mWidth = aWidth;
mHeight = aHeight;
PRInt16 bufferdepth;
switch(aDepth)
{
case 8:
//mThePixelmap.pmTable = ::GetCTable(8);
bufferdepth = 8;
break;
case 16:
bufferdepth = 16;
break;
case 24: // 24 and 32 bit are basically the same
case 32:
bufferdepth = 32;
break;
default:
NS_NOTREACHED("Unexpected buffer depth");
bufferdepth = 32;
break;
}
// Allocate mask image bits if requested
if (aMaskRequirements != nsMaskRequirements_kNoMask){
mAlphaPix = new BitMap();
if (nsMaskRequirements_kNeeds1Bit == aMaskRequirements){
mARowBytes = (aWidth + 7) / 8; // 1 bit rowbytes
mARowBytes = (mARowBytes + 3) & ~0x3; // 32 bit align
mAlphaBits = new unsigned char[mARowBytes * aHeight];
// allocate the GWorld
Rect bounds = {0, 0, 0, 0};
bounds.right = aWidth;
bounds.bottom = aHeight;
OSErr err = AllocateGWorld(bufferdepth, nsnull, bounds, &mImageGWorld);
if (err != noErr)
{
NS_WARNING("GWorld allocation failed");
return NS_ERROR_OUT_OF_MEMORY;
}
ClearGWorld(mImageGWorld);
// calculate the pixel data size
PixMapHandle thePixMap = ::GetGWorldPixMap(mImageGWorld);
mRowBytes = (**thePixMap).rowBytes & 0x3FFF;
mPixelDataSize = mRowBytes * aHeight;
mBytesPerPixel = (**thePixMap).cmpCount;
if (aMaskRequirements != nsMaskRequirements_kNoMask)
{
PRInt16 mAlphaDepth = 0;
switch (aMaskRequirements)
{
case nsMaskRequirements_kNeeds1Bit:
mAlphaDepth = 1;
bufferdepth = 1;
mAlphaPix->baseAddr = (char*) mAlphaBits;
mAlphaPix->rowBytes = mARowBytes;
mAlphaPix->bounds.top = 0;
mAlphaPix->bounds.left = 0;
mAlphaPix->bounds.bottom = aHeight;
mAlphaPix->bounds.right = aWidth;
err = AllocateGWorld(mAlphaDepth, nsnull, bounds, &mAlphaGWorld);
if (err != noErr)
return NS_ERROR_OUT_OF_MEMORY;
break;
case nsMaskRequirements_kNeeds8Bit:
mAlphaDepth = 8;
// make 8-bit grayscale color table
CTabHandle grayRamp = nsnull;
err = MakeGrayscaleColorTable(256, &grayRamp);
if (err != noErr)
return NS_ERROR_OUT_OF_MEMORY;
err = AllocateGWorld(mAlphaDepth, grayRamp, bounds, &mAlphaGWorld);
if (err != noErr)
return NS_ERROR_OUT_OF_MEMORY;
::DisposeHandle((Handle)grayRamp);
break;
default:
NS_NOTREACHED("Uknown mask depth");
break;
}
if (mAlphaGWorld)
{
ClearGWorld(mAlphaGWorld);
// calculate the pixel data size
PixMapHandle maskPixMap = GetGWorldPixMap(mAlphaGWorld);
mARowBytes = (**maskPixMap).rowBytes & 0x3FFF;
mAlphaWidth = aWidth;
mAlphaHeight = aHeight;
}else{
NS_ASSERTION(nsMaskRequirements_kNeeds8Bit == aMaskRequirements, "unexpected mask depth");
mAlphaBits = nsnull;
mAlphaWidth = 0;
mAlphaHeight = 0;
}
}
} else{
mAlphaBits = nsnull;
mAlphaWidth = 0;
mAlphaHeight = 0;
}
mIsTopToBottom = PR_TRUE;
return NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
PRInt32 nsImageMac :: CalcBytesSpan(PRUint32 aWidth,PRUint32 aDepth)
{
PRInt32 spanbytes;
spanbytes = (aWidth * aDepth) >> 5;
if (((PRUint32)aWidth * aDepth) & 0x1F)
spanbytes++;
spanbytes <<= 2;
return(spanbytes);
return 0;
}
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
void nsImageMac::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
{
/*if (nsnull == mImage)
return;
if (IsFlagSet(nsImageUpdateFlags_kBitsChanged, aFlags)){
}
*/
// NS_NOTYETIMPLEMENTED("nsImageMac::ImageUpdated not implemented");
}
@@ -211,33 +275,49 @@ void nsImageMac :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRe
* See documentation in nsImageMac.h
* @update
*/
NS_IMETHODIMP nsImageMac :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY,
PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
{
PixMapPtr destpix;
RGBColor rgbblack = {0x0000,0x0000,0x0000};
RGBColor rgbwhite = {0xFFFF,0xFFFF,0xFFFF};
Rect srcrect,dstrect,maskrect;;
PixMapHandle imagePixMap;
Rect srcRect, dstRect, maskRect;
if (nsnull == mThePixelmap.baseAddr)
if (!mImageGWorld)
return NS_ERROR_FAILURE;
::SetRect(&srcrect,aSX,aSY,aSX+aSWidth,aSY+aSHeight);
::SetRect(&maskrect,aSX,aSY,aSX+aSWidth,aSY+aSHeight);
::SetRect(&dstrect,aDX,aDY,aDX+aDWidth,aDY+aDHeight);
::SetRect(&srcRect, aSX, aSY, aSX + aSWidth, aSY + aSHeight);
maskRect = srcRect;
::SetRect(&dstRect, aDX, aDY, aDX + aDWidth, aDY + aDHeight);
#if TARGET_CARBON
destpix = *::GetPortPixMap((CGrafPtr)aSurface);
#else
destpix = *((CGrafPtr)aSurface)->portPixMap;
#endif
::ForeColor(blackColor);
::BackColor(whiteColor);
::RGBForeColor(&rgbblack);
::RGBBackColor(&rgbwhite);
if(mAlphaBits){
::CopyDeepMask((BitMap*)&mThePixelmap,(BitMap*)mAlphaPix,(BitMap*)destpix,&srcrect,&maskrect,&dstrect,srcCopy,0L);
} else {
::CopyBits((BitMap*)&mThePixelmap, (BitMap*)destpix, &srcrect, &dstrect, ditherCopy, 0L);
imagePixMap = GetGWorldPixMap(mImageGWorld);
StPixelLocker pixelLocker(imagePixMap); // locks the pixels
// get the destination pix map
nsDrawingSurfaceMac* surface = static_cast<nsDrawingSurfaceMac*>(aSurface);
CGrafPtr destPort;
nsresult rv = surface->GetGrafPtr((GrafPtr *)&destPort);
if (NS_FAILED(rv)) return rv;
PixMapHandle destPixels = GetGWorldPixMap(destPort);
NS_ASSERTION(destPixels, "No dest pixels!");
// XXX printing???
if(mAlphaGWorld)
{
PixMapHandle maskPixMap = GetGWorldPixMap(mAlphaGWorld);
StPixelLocker pixelLocker(maskPixMap);
// 1-bit masks?
::CopyDeepMask((BitMap*)*imagePixMap, (BitMap*)*maskPixMap, (BitMap*)*destPixels, &srcRect, &maskRect, &dstRect, srcCopy, nsnull);
}
else
{
::CopyBits((BitMap*)*imagePixMap, (BitMap*)*destPixels, &srcRect, &dstRect, ditherCopy, 0L);
}
return NS_OK;
@@ -265,4 +345,157 @@ nsresult nsImageMac::Optimize(nsIDeviceContext* aContext)
return NS_OK;
}
//------------------------------------------------------------
#pragma mark -
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
void nsImageMac::SetAlphaLevel(PRInt32 aAlphaLevel)
{
NS_NOTYETIMPLEMENTED("nsImageMac::SetAlphaLevel not implemented");
}
/** ---------------------------------------------------
* See documentation in nsImageMac.h
* @update
*/
PRInt32 nsImageMac::GetAlphaLevel()
{
NS_NOTYETIMPLEMENTED("nsImageMac::GetAlphaLevel not implemented");
return 0;
}
#pragma mark -
/** ---------------------------------------------------
* Lock down the image pixels
*/
NS_IMETHODIMP
nsImageMac::LockImagePixels(PRBool aMaskPixels)
{
if (!mImageGWorld)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphaGWorld)
return NS_ERROR_NOT_INITIALIZED;
PixMapHandle thePixMap = ::GetGWorldPixMap(aMaskPixels ? mAlphaGWorld : mImageGWorld);
::LockPixels(thePixMap);
return NS_OK;
}
/** ---------------------------------------------------
* Unlock the pixels
*/
NS_IMETHODIMP
nsImageMac::UnlockImagePixels(PRBool aMaskPixels)
{
if (!mImageGWorld)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphaGWorld)
return NS_ERROR_NOT_INITIALIZED;
PixMapHandle thePixMap = ::GetGWorldPixMap(aMaskPixels ? mAlphaGWorld : mImageGWorld);
::UnlockPixels(thePixMap);
return NS_OK;
}
#pragma mark -
/** ---------------------------------------------------
* Erase the GWorld contents
*/
void nsImageMac::ClearGWorld(GWorldPtr theGWorld)
{
PixMapHandle thePixels;
GWorldPtr curPort;
GDHandle curDev;
OSErr err = noErr;
thePixels = ::GetGWorldPixMap(theGWorld);
::GetGWorld(&curPort, &curDev);
// Black the offscreen
if (LockPixels(thePixels))
{
::SetGWorld(theGWorld, nil);
::BackColor(whiteColor);
::EraseRect(&theGWorld->portRect);
::UnlockPixels(thePixels);
}
::SetGWorld(curPort, curDev);
}
/** -----------------------------------------------------------------
* Allocate a GWorld, trying first in the heap, and then in temp mem.
*/
#define kReserveHeapFreeSpace (256 * 1024)
#define kReserverHeapContigSpace (64 * 1024)
OSErr nsImageMac::AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld)
{
*outGWorld = nsnull;
// Quick and dirty check to make sure there is some memory available.
// GWorld allocations in temp mem can still fail if the heap is totally
// full, because some stuff is allocated in the heap
long totalSpace, contiguousSpace;
::PurgeSpace(&totalSpace, &contiguousSpace); // this does not purge memory!
QDErr err = noErr;
if (totalSpace > kReserveHeapFreeSpace && contiguousSpace > kReserverHeapContigSpace)
{
err = ::NewGWorld(outGWorld, depth, &bounds, colorTable, nsnull, 0);
if (err == noErr || err != memFullErr) return err;
}
err = ::NewGWorld(outGWorld, depth, &bounds, colorTable, nsnull, useTempMem);
return err;
}
/** ----------------------------------------------------------
* Make a 256-level grayscale color table, for alpha blending.
* Caller must free the color table with ::DisposeHandle((Handle)colorTable)
* when done.
*/
OSErr nsImageMac::MakeGrayscaleColorTable(PRInt16 numColors, CTabHandle *outColorTable)
{
CTabHandle colorTable = nil;
colorTable = (CTabHandle)::NewHandleClear (8 * numColors + 8); /* Allocate memory for the table */
if (!colorTable) return memFullErr;
(**colorTable).ctSeed = ::GetCTSeed(); // not sure about this one
(**colorTable).ctFlags = 0; // not sure about this one
(**colorTable).ctSize = numColors - 1;
RGBColor tempColor = { 0xFFFF, 0xFFFF, 0xFFFF}; // starts at white
PRUint16 colorInc = 0xFFFF / numColors;
for (PRInt16 i = 0; i < numColors; i++)
{
(**colorTable).ctTable[i].value = i;
(**colorTable).ctTable[i].rgb = tempColor;
tempColor.red -= colorInc;
tempColor.green -= colorInc;
tempColor.blue -= colorInc;
}
*outColorTable = colorTable;
return noErr;
}

View File

@@ -26,80 +26,80 @@ class nsImageMac : public nsIImage
{
public:
nsImageMac();
~nsImageMac();
virtual ~nsImageMac();
NS_DECL_ISUPPORTS
/**
@see nsIImage.h
*/
virtual PRInt32 GetBytesPix() { return mThePixelmap.cmpCount; }
virtual PRInt32 GetHeight() { return mHeight;}
virtual PRInt32 GetWidth() { return mWidth; }
virtual PRUint8* GetBits() ; //{ return mImageBits; }
virtual void* GetBitInfo() { return nsnull; }
virtual PRBool GetIsRowOrderTopToBottom() { return mIsTopToBottom; }
virtual PRInt32 GetLineStride() {return mRowBytes; }
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
virtual nsColorMap* GetColorMap() {return nsnull;}
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual PRBool IsOptimized() { return false; }
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
virtual PRInt32 GetBytesPix() { return mBytesPerPixel; }
virtual PRBool GetIsRowOrderTopToBottom() { return mIsTopToBottom; }
virtual PRInt32 GetWidth() { return mWidth; }
virtual PRInt32 GetHeight() { return mHeight;}
virtual PRUint8* GetBits();
virtual PRInt32 GetLineStride() { return mRowBytes; }
virtual PRBool GetHasAlphaMask() { return mAlphaGWorld != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaWidth() { return mAlphaWidth; }
virtual PRInt32 GetAlphaHeight() { return mAlphaHeight; }
virtual PRInt32 GetAlphaLineStride() { return mARowBytes; }
virtual nsIImage* DuplicateImage() {return(nsnull);}
void AllocConvertedBits(PRUint32 aSize);
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool IsOptimized() { return PR_FALSE; }
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual nsColorMap* GetColorMap() { return nsnull;}
/**
* Return the image size of the Device Independent Bitmap(DIB).
* @return size of image in bytes
*/
PRIntn GetSizeImage(){ return mSizeImage; }
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
/**
* Make a palette for the DIB.
* @return true or false if the palette was created
*/
PRBool MakePalette();
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
/**
* Calculate the number of bytes spaned for this image for a given width
* @param aWidth is the width to calculate the number of bytes for
* @return the number of bytes in this span
*/
PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aDepth);
virtual void SetAlphaLevel(PRInt32 aAlphaLevel) {}
virtual PRInt32 GetAlphaLevel() {return(0);}
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY) {}
virtual void SetAlphaLevel(PRInt32 aAlphaLevel);
virtual PRInt32 GetAlphaLevel();
virtual void* GetBitInfo() { return nsnull; }
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
protected:
void ClearGWorld(GWorldPtr);
OSErr MakeGrayscaleColorTable(PRInt16 numColors, CTabHandle *outColorTable);
OSErr AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld);
private:
PixMap mThePixelmap;
GWorldPtr mImageGWorld;
PRInt32 mWidth;
PRInt32 mHeight;
PRInt32 mSizeImage;
PRInt32 mRowBytes; // number of bytes per row
PRUint8* mImageBits; // starting address of the bits
nsColorMap* mColorMap; // Redundant with mColorTable, but necessary
PRInt32 mRowBytes;
PRInt32 mBytesPerPixel;
// alpha layer members
BitMap *mAlphaPix; // the alpha level pixel map
PRBool mIsTopToBottom;
PRUint8 *mAlphaBits; // the bits to set for the mask
PRInt32 mARowBytes; // rowbytes for the alpha layer
PRInt8 mAlphaDepth; // alpha layer depth
GWorldPtr mAlphaGWorld;
PRInt16 mAlphaDepth; // alpha layer depth
PRInt16 mAlphaWidth; // alpha layer width
PRInt16 mAlphaHeight; // alpha layer height
nsPoint mLocation; // alpha mask location
PRInt8 mImageCache; // place to save off the old image for fast animation
PRInt16 mAlphaLevel; // an alpha level every pixel uses
PRInt32 mARowBytes; // alpha row bytes
//nsPoint mLocation; // alpha mask location
//PRInt8 mImageCache; // place to save off the old image for fast animation
//PRInt16 mAlphaLevel; // an alpha level every pixel uses
PRIntn mPixelDataSize;
PRBool mIsTopToBottom;
};
#endif

View File

@@ -399,3 +399,19 @@ printf("Format XYPixmap\n");
}
return ;
}
//------------------------------------------------------------
// lock the image pixels. nothing to do on gtk
NS_IMETHODIMP
nsImageMotif::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. nothing to do on gtk
NS_IMETHODIMP
nsImageMotif::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -62,6 +62,7 @@ public:
virtual nsresult BuildImage(nsDrawingSurface aDrawingSurface);
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
virtual PRInt32 GetAlphaWidth() { return 0;}
virtual PRInt32 GetAlphaHeight() {return 0;}
@@ -95,6 +96,9 @@ public:
virtual PRInt32 GetAlphaLevel() {return(0);}
virtual void MoveAlphaMask(PRInt32 /* aX */, PRInt32 /* aY */) {}
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
void CreateImage(nsDrawingSurface aSurface);
void ConvertImage(nsDrawingSurface aSurface);

View File

@@ -354,3 +354,19 @@ void nsImageOS2::DrawBitmap( HPS hps, LONG lCount, PPOINTL pPoints,
delete pMaskInfo;
}
}
//------------------------------------------------------------
// lock the image pixels. implement this if you need it
NS_IMETHODIMP
nsImageOS2::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. implement this if you need it
NS_IMETHODIMP
nsImageOS2::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -50,6 +50,7 @@ class nsImageOS2 : public nsIImage
PRInt32 GetAlphaWidth() { return mInfo ? mInfo->cx : 0; }
PRInt32 GetAlphaHeight() { return mInfo ? mInfo->cy : 0; }
PRInt32 GetAlphaLineStride() { return mAStride; }
PRBool GetHasAlphaMask() { return mAImageBits != nsnull; }
PRUint8 *GetAlphaBits() { return mAImageBits; }
void SetAlphaLevel(PRInt32 aAlphaLevel) {}
@@ -67,6 +68,9 @@ class nsImageOS2 : public nsIImage
void ImageUpdated( nsIDeviceContext *aContext,
PRUint8 aFlags, nsRect *aUpdateRect);
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
BITMAPINFO2 *mInfo;
PRInt32 mStride;

View File

@@ -606,3 +606,19 @@ void* nsImagePh::GetBitInfo()
return nsnull;
}
//------------------------------------------------------------
// lock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImagePh::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImagePh::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -46,6 +46,7 @@ public:
virtual PRBool IsOptimized();
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRUint8* GetAlphaBits();
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRInt32 GetAlphaWidth();
virtual PRInt32 GetAlphaHeight();
virtual PRInt32 GetAlphaLineStride();
@@ -87,6 +88,13 @@ public:
void* GetBitInfo();
/**
* Lock and unlock the image pixels (for platforms on which this is necessary)
* @param aMaskPixels true to lock the mask, false to lock the image
*/
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Clean up the memory used nsImagePh.

View File

@@ -499,3 +499,19 @@ PRBool nsImageQT::GetIsRowOrderTopToBottom()
PR_LOG(QtGfxLM, PR_LOG_DEBUG, ("nsImageQT::GetIsRowOrderTopToBottom()\n"));
return PR_TRUE;
}
//------------------------------------------------------------
// lock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageQT::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageQT::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -66,6 +66,7 @@ public:
virtual PRBool IsOptimized();
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaWidth();
virtual PRInt32 GetAlphaHeight();
@@ -82,6 +83,9 @@ public:
virtual PRInt32 GetAlphaLevel();
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY);
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
/**
* Calculate the amount of memory needed for the initialization of the

View File

@@ -795,3 +795,38 @@ PRInt16 numPaletteColors;
return NS_OK;
}
/** ---------------------------------------------------
* Lock down the image pixels
*/
NS_IMETHODIMP
nsImageWin::LockImagePixels(PRBool aMaskPixels)
{
/*
if (!mHBitmap)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphaHBitmap)
return NS_ERROR_NOT_INITIALIZED;
... and do Windows locking of image pixels here, if necessary
*/
return NS_OK;
}
/** ---------------------------------------------------
* Unlock the pixels
*/
NS_IMETHODIMP
nsImageWin::UnlockImagePixels(PRBool aMaskPixels)
{
/*
if (!mHBitmap)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphamHBitmap)
return NS_ERROR_NOT_INITIALIZED;
... and do Windows unlocking of image pixels here, if necessary
*/
return NS_OK;
}

View File

@@ -38,6 +38,8 @@ public:
virtual PRInt32 GetWidth() { return mBHead->biWidth; }
virtual PRUint8* GetBits() { return mImageBits; }
virtual PRInt32 GetLineStride() { return mRowBytes; }
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
@@ -87,6 +89,10 @@ public:
*/
void* GetBitInfo() {return mBHead;}
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
static PRBool gIsWinNT;
private:

View File

@@ -414,3 +414,20 @@ nsImageXlib::ComputeMetrics()
mRowBytes = CalcBytesSpan(mWidth);
mSizeImage = mRowBytes * mHeight;
}
//------------------------------------------------------------
// lock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageXlib::LockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}
//------------------------------------------------------------
// unlock the image pixels. Implement this if you need it.
NS_IMETHODIMP
nsImageXlib::UnlockImagePixels(PRBool aMaskPixels)
{
return NS_OK;
}

View File

@@ -53,6 +53,7 @@ public:
PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
virtual PRBool IsOptimized();
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull; }
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaWidth();
virtual PRInt32 GetAlphaHeight();
@@ -68,6 +69,10 @@ public:
void* GetBitInfo();
virtual PRBool GetIsRowOrderTopToBottom() { return PR_TRUE; }
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
private:
PRInt32 mWidth;
PRInt32 mHeight;

View File

@@ -1929,8 +1929,7 @@ nsCSSRendering::PaintBackground(nsIPresContext& aPresContext,
xDistance = dirtyRect.width;
yDistance = dirtyRect.height;
// We need to render the background color if the image is transparent
PRUint8* alphaBits = image->GetAlphaBits();
needBackgroundColor = alphaBits != nsnull;
needBackgroundColor = image->GetHasAlphaMask();
break;
}

View File

@@ -1929,8 +1929,7 @@ nsCSSRendering::PaintBackground(nsIPresContext& aPresContext,
xDistance = dirtyRect.width;
yDistance = dirtyRect.height;
// We need to render the background color if the image is transparent
PRUint8* alphaBits = image->GetAlphaBits();
needBackgroundColor = alphaBits != nsnull;
needBackgroundColor = image->GetHasAlphaMask();
break;
}