Fix for bug 66814. r=pink, sr=smfr
git-svn-id: svn://10.0.0.236/trunk@111786 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
b3949a7795
commit
e9dd704861
@ -19,6 +19,8 @@
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Andrew Thompson (lordpixel@mac.com)
|
||||
* Andrew Thompson (lordpixel@mac.com)
|
||||
* Contributor(s):
|
||||
* Mike Pinkerton (pinkerton@netscape.com)
|
||||
*
|
||||
@ -42,7 +44,9 @@
|
||||
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include <quickdraw.h>
|
||||
#include "nsRect.h"
|
||||
#include <QuickDraw.h>
|
||||
|
||||
|
||||
// IID for the nsIImage interface
|
||||
// {80b2f600-f140-11d4-bb6f-d472847e8dbc}
|
||||
@ -53,6 +57,7 @@
|
||||
//
|
||||
// nsIImageMac
|
||||
//
|
||||
|
||||
// MacOS-specific Interface to Images
|
||||
//
|
||||
class nsIImageMac : public nsISupports
|
||||
@ -72,6 +77,22 @@ public:
|
||||
|
||||
// Get the PixMap for this image
|
||||
NS_IMETHOD GetPixMap ( PixMap** aPixMap ) = 0;
|
||||
|
||||
//Convert to the os-native icon format. Most used to put icons
|
||||
//onto windows and menus. The outIcon will be allocated, the caller
|
||||
//is responsible for disposing the memory
|
||||
NS_IMETHOD ConvertToIcon( const nsRect& aSrcRegion,
|
||||
const PRInt16 aIconDepth,
|
||||
const PRInt16 aIconSize,
|
||||
Handle* aOutIcon,
|
||||
OSType* aOutIconType) = 0;
|
||||
//Companion method for ConvertToIcon, makes icon masks
|
||||
//see nsImageMac.cpp for full details
|
||||
NS_IMETHOD ConvertAlphaToIconMask( const nsRect& aSrcRegion,
|
||||
const PRInt16 aMaskDepth,
|
||||
const PRInt16 aMaskSize,
|
||||
Handle* aOutMask,
|
||||
OSType* aOutIconType) = 0;
|
||||
|
||||
}; // nsIImageMac
|
||||
|
||||
|
||||
@ -182,6 +182,8 @@ nsImageMac::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirem
|
||||
nsMemory::HeapMinimize(PR_FALSE);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mBytesPerPixel = (aDepth < 8) ? 1 : aDepth / 8;
|
||||
|
||||
mRowBytes = mImagePixmap.rowBytes & 0x3FFF; // we only set the top bit, but QuickDraw can use the top 2 bits
|
||||
|
||||
@ -477,7 +479,9 @@ nsImageMac::UnlockImagePixels(PRBool aMaskPixels)
|
||||
/** -----------------------------------------------------------------
|
||||
* Create a PixMap, filling in ioPixMap
|
||||
*/
|
||||
OSErr nsImageMac::CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, CTabHandle aColorTable, PixMap& ioPixMap, Handle& ioBitsHandle)
|
||||
OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRInt32 aDepth, CTabHandle aColorTable,
|
||||
PixMap& ioPixMap, Handle& ioBitsHandle)
|
||||
{
|
||||
PRInt16 bufferdepth;
|
||||
OSErr err = noErr;
|
||||
@ -491,15 +495,35 @@ OSErr nsImageMac::CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
|
||||
ioPixMap.pixelType = 0;
|
||||
ioPixMap.cmpCount = 1;
|
||||
ioPixMap.cmpSize = 1;
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 1); // default to black & white colortable
|
||||
// default to black & white colortable
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 1);
|
||||
bufferdepth = 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ioPixMap.pixelType = 0;
|
||||
ioPixMap.cmpCount = 1;
|
||||
ioPixMap.cmpSize = 2;
|
||||
// Black, 33% gray, 66% gray, white
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 2);
|
||||
bufferdepth = 2;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ioPixMap.pixelType = 0;
|
||||
ioPixMap.cmpCount = 1;
|
||||
ioPixMap.cmpSize = 4;
|
||||
// Black, 14 shades of gray, white
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 4);
|
||||
bufferdepth = 4;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
ioPixMap.pixelType = 0;
|
||||
ioPixMap.cmpCount = 1;
|
||||
ioPixMap.cmpSize = 8;
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 8); // default to gray ramp colortable
|
||||
// default to gray ramp colortable
|
||||
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 8);
|
||||
bufferdepth = 8;
|
||||
break;
|
||||
|
||||
@ -541,9 +565,11 @@ OSErr nsImageMac::CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
|
||||
err = AllocateBitsHandle(imageSize, &ioBitsHandle);
|
||||
if (err != noErr)
|
||||
return err;
|
||||
|
||||
ioPixMap.baseAddr = nsnull; // We can only set this after locking the pixels handle
|
||||
ioPixMap.rowBytes = rowBytes | 0x8000; // set the high bit to tell CopyBits that this is a PixMap
|
||||
|
||||
// We can only set this after locking the pixels handle
|
||||
ioPixMap.baseAddr = nsnull;
|
||||
// set the high bit to tell CopyBits that this is a PixMap
|
||||
ioPixMap.rowBytes = rowBytes | 0x8000;
|
||||
ioPixMap.bounds.top = 0;
|
||||
ioPixMap.bounds.left = 0;
|
||||
ioPixMap.bounds.bottom = aHeight;
|
||||
@ -551,7 +577,8 @@ OSErr nsImageMac::CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,
|
||||
ioPixMap.pixelSize = bufferdepth;
|
||||
ioPixMap.packType = 0;
|
||||
ioPixMap.packSize = 0;
|
||||
ioPixMap.hRes = nsDeviceContextMac::GetScreenResolution() << 16; // is this correct? printing?
|
||||
// is this correct? printing?
|
||||
ioPixMap.hRes = nsDeviceContextMac::GetScreenResolution() << 16;
|
||||
ioPixMap.vRes = nsDeviceContextMac::GetScreenResolution() << 16;
|
||||
#if TARGET_CARBON
|
||||
ioPixMap.pixelFormat = 0; /*fourCharCode representation*/
|
||||
@ -628,7 +655,14 @@ nsImageMac::SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2 )
|
||||
*/
|
||||
PRInt32 nsImageMac::CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth)
|
||||
{
|
||||
PRInt32 rowBytes = ((aWidth * aDepth + 31) / 32) * 4;
|
||||
PRInt32 rowBits = aWidth * aDepth;
|
||||
PRInt32 rowBytes;
|
||||
// if bits per row is 24 or less, needs 3 bytes or less
|
||||
if (rowBits > 24)
|
||||
rowBytes = ((aWidth * aDepth + 31) / 32) * 4;
|
||||
else
|
||||
rowBytes = ((aWidth * aDepth + 15) / 16) * 2;
|
||||
|
||||
return rowBytes;
|
||||
}
|
||||
|
||||
@ -781,7 +815,7 @@ nsImageMac :: ConvertToPICT ( PicHandle* outPicture )
|
||||
GWorldPtr currPort;
|
||||
GDHandle currDev;
|
||||
::GetGWorld(&currPort, &currDev);
|
||||
::SetGWorld(tempGWorld, nil);
|
||||
::SetGWorld(tempGWorld, nsnull);
|
||||
PicHandle thePicture = ::OpenPicture(&picFrame);
|
||||
OSErr err = noErr;
|
||||
if ( thePicture ) {
|
||||
@ -825,6 +859,531 @@ nsImageMac::GetPixMap ( PixMap** aPixMap )
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** Create a Macintosh native icon from a region of this image.
|
||||
After creating an Icon, you probably want to add it to either
|
||||
an IconSuite, an IconFamily or perhaps just write it as a resource.
|
||||
See <Icons.h>
|
||||
The caller of the function owns the memory allocated for the resulting icon.
|
||||
|
||||
The "type" of the icon is implicit in the size and depth and mask
|
||||
parameters,
|
||||
e.g.
|
||||
size 32, depth 1 -> 'ICON' resource
|
||||
size 16, depth 4 -> 'ics4' resource
|
||||
size 48, depth 32 -> 'ih32' valid only inside an 'icns' resource (IconFamily)
|
||||
|
||||
n.b. you cannout create any of the 'XXX#' (icm#, ics#, ICN# or ich#) resources
|
||||
using this method. Use ConvertAlphaToIconMask for this task.
|
||||
|
||||
CopyBits is used to scale and dither, so the bit depth and size of the requested
|
||||
icon do not have to match those of this image.
|
||||
|
||||
@param the region of this image to make into an icon.
|
||||
@param aIconDepth the depth of the icon, must be one of 1, 4, 8 or 32
|
||||
@param aIconSize the size of the icon. Traditionally 12, 16, 32 or 48
|
||||
@param aOutIcon a handle the icon, caller owns the memory
|
||||
@param aOutIconType the type code for the icon requested (see MakeIconType)
|
||||
@return error an error code -
|
||||
NS_OK if the data was produced,
|
||||
NS_ERROR_INVALID_ARG if the depth is wrong,
|
||||
NS_ERROR_FAILURE if a general error occurs.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageMac::ConvertToIcon( const nsRect& aSrcRegion,
|
||||
const PRInt16 aIconDepth,
|
||||
const PRInt16 aIconSize,
|
||||
Handle* aOutIcon,
|
||||
OSType* aOutIconType)
|
||||
{
|
||||
|
||||
Rect srcRect;
|
||||
Rect iconRect = { 0, 0, aIconSize, aIconSize};
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aOutIcon);
|
||||
NS_ENSURE_ARG_POINTER(aOutIconType);
|
||||
*aOutIcon = nsnull;
|
||||
*aOutIconType = nsnull;
|
||||
|
||||
if ( aIconDepth != 1 && aIconDepth != 2 && aIconDepth != 4 &&
|
||||
aIconDepth != 8 && aIconDepth != 24 && aIconDepth != 32) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//returns null if there size specified isn't a valid size for an icon
|
||||
OSType iconType = MakeIconType(aIconSize, aIconDepth, false);
|
||||
if (iconType == nil) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*aOutIconType = iconType;
|
||||
|
||||
srcRect.top = aSrcRegion.y;
|
||||
srcRect.left = aSrcRegion.x;
|
||||
srcRect.bottom = aSrcRegion.y + aSrcRegion.height;
|
||||
srcRect.right = aSrcRegion.x + aSrcRegion.width;
|
||||
|
||||
return CopyPixMap( srcRect, iconRect, aIconDepth,
|
||||
PR_FALSE, aOutIcon);
|
||||
} // ConvertToIcon
|
||||
|
||||
/** Create an Icon mask from a specified region of the the alpha channel
|
||||
in this image.
|
||||
The caller owns the memory allocated for the mask.
|
||||
|
||||
If the image has no alpha channel, a fully opaque mask of the
|
||||
requested size and depth is generated and returned.
|
||||
If the image has an alpha channel which is at a different depth
|
||||
from the requested mask, the channel is converted.
|
||||
|
||||
If an 8 bit masks is requested, one is simply returned.
|
||||
As with icons, the size and determines the exact type, however
|
||||
8 bit masks are ONLY valid inside an IconFamily ('icns' resource)
|
||||
|
||||
size 16 -> s8mk, size 32 -> l8mk, size 48 -> h8mk.
|
||||
(no mini 8 bit masks exist)
|
||||
|
||||
1 bit masks are trickier. These are older and work for both IconFamilies and
|
||||
IconSuites. Actually, a 1 bit masks is required for every size that you set
|
||||
in an IconFamily or Icon Suite.
|
||||
|
||||
'XXX#' resources (icm#, ics#, ICN# or ich#) contain a 1 bit icon of the
|
||||
indicated
|
||||
size, followed immediate by a 1 bit mask of the same size.
|
||||
That's how it works, you can't have the mask seperately.
|
||||
This mask is used for all icons of that size in a suite or family.
|
||||
|
||||
So if you want to use a 256 colour 32x32 icon you will typically call
|
||||
CreateToIcon to make an icl8 resource then this function to make an ICN#
|
||||
resource. Then you store the result in an suite or a family.
|
||||
Repeat for other sizes and depths as desired.
|
||||
For more details, see Inside Macintosh: Icon Utilities, Icon Services and
|
||||
<Icons.h>
|
||||
|
||||
size 12 -> icm#, size 16 -> ics#, size 32-> ICN#, size 48-> ich#
|
||||
(constrast ICON above with ICN#, the later has both the icon and the mask)
|
||||
|
||||
@param the region of this image's alpha channel to make into an icon.
|
||||
@param aIconDepth the depth of the icon, must be 1 or 8
|
||||
@param aIconSize the size of the icon. Traditionally 12, 16, 32 or 48
|
||||
See above for restictions.
|
||||
@param aOutIcon a handle the mask, caller owns the memory
|
||||
@param aOutIconType the type code for the icon mask requested (see MakeIconType)
|
||||
@return error an error code -
|
||||
NS_OK if the data was produced,
|
||||
NS_ERROR_INVALID_ARG if the depth is wrong,
|
||||
NS_ERROR_FAILURE if a general error occurs.
|
||||
|
||||
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsImageMac::ConvertAlphaToIconMask( const nsRect& aSrcRegion,
|
||||
const PRInt16 aMaskDepth,
|
||||
const PRInt16 aMaskSize,
|
||||
Handle* aOutMask,
|
||||
OSType* aOutIconType)
|
||||
{
|
||||
Handle dstHandle = nsnull;
|
||||
Rect srcRect;
|
||||
nsresult result;
|
||||
Rect maskRect = { 0, 0, aMaskSize, aMaskSize};
|
||||
|
||||
srcRect.top = aSrcRegion.y;
|
||||
srcRect.left = aSrcRegion.x;
|
||||
srcRect.bottom = aSrcRegion.y + aSrcRegion.height;
|
||||
srcRect.right = aSrcRegion.x + aSrcRegion.width;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aOutMask);
|
||||
NS_ENSURE_ARG_POINTER(aOutIconType);
|
||||
*aOutMask = nsnull;
|
||||
*aOutIconType = nsnull;
|
||||
|
||||
//returns null if there size specified isn't a valid size for an icon
|
||||
OSType iconType = MakeIconType(aMaskSize, aMaskDepth, true);
|
||||
if (iconType == nil) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*aOutIconType = iconType;
|
||||
|
||||
if (mMaskBitsHandle) {
|
||||
//image has an alpha channel, copy into icon mask
|
||||
|
||||
//if the image has an 8 bit mask, but the caller asks for a 1 bit
|
||||
//mask, or vice versa, it'll simply be converted by CopyPixMap
|
||||
if (aMaskDepth == 8) {
|
||||
//for 8 bit masks, this is sufficient
|
||||
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
|
||||
PR_TRUE, &dstHandle);
|
||||
} else if (aMaskDepth == 1) {
|
||||
//1 bit masks are tricker, we must create an '#' resource
|
||||
//which inclues both the 1-bit icon and a mask for it (icm#, ics#, ICN# or ich#)
|
||||
Handle iconHandle = nsnull, maskHandle = nsnull;
|
||||
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
|
||||
PR_FALSE, &iconHandle);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
|
||||
PR_TRUE, &maskHandle);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
//a '#' resource's data is simply the mask appended to the icon
|
||||
//these icons and masks are small - 128 bytes each
|
||||
result = ConcatBitsHandles(iconHandle, maskHandle, &dstHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (iconHandle) ::DisposeHandle(iconHandle);
|
||||
if (maskHandle) ::DisposeHandle(maskHandle);
|
||||
} else {
|
||||
NS_ASSERTION(aMaskDepth, "Unregonised icon mask depth");
|
||||
result = NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
} else {
|
||||
//image has no alpha channel, make an entirely black mask with the appropriate depth
|
||||
if (aMaskDepth == 8) {
|
||||
//simply make the mask
|
||||
result = MakeOpaqueMask(aMaskSize, aMaskSize, aMaskDepth, &dstHandle);
|
||||
} else if (aMaskDepth == 1) {
|
||||
//make 1 bit icon and mask as above
|
||||
Handle iconHandle = nsnull, maskHandle = nsnull;
|
||||
result = CopyPixMap( srcRect, maskRect, aMaskDepth, PR_FALSE, &iconHandle);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = MakeOpaqueMask(aMaskSize, aMaskSize, aMaskDepth, &maskHandle);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
//a '#' resource's data is simply the mask appended to the icon
|
||||
//these icons and masks are small - 128 bytes each
|
||||
result = ConcatBitsHandles(iconHandle, maskHandle, &dstHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (iconHandle) ::DisposeHandle(iconHandle);
|
||||
if (maskHandle) ::DisposeHandle(maskHandle);
|
||||
|
||||
} else {
|
||||
NS_ASSERTION(aMaskDepth, "Unregonised icon mask depth");
|
||||
result = NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(NS_SUCCEEDED(result)) *aOutMask = dstHandle;
|
||||
return result;
|
||||
} // ConvertAlphaToIconMask
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/** Create a new PixMap with the specified size and depth,
|
||||
then copy either the image bits or the mask bits from this
|
||||
image into a handle. CopyBits is used to dither and scale
|
||||
the indicated source region from this image into the resulting
|
||||
handle. For indexed colour image depths, a standard Mac colour table
|
||||
is used. For masks, a standard Mac greyscale table is used.
|
||||
|
||||
@param aSrcregion the part of the image to copy
|
||||
@param aDestRegion the size of the destination image bits to create
|
||||
@param aDestDepth the depth of the destination image bits
|
||||
@param aCopyMaskBits if true, the alpha bits are copied, otherwise the
|
||||
image bits are copied. You must check that the
|
||||
image has an alpha channel before calling with this
|
||||
parameter set to true.
|
||||
@param aDestData the result bits are copied into this handle, the caller
|
||||
is responsible for disposing of them
|
||||
*/
|
||||
nsresult
|
||||
nsImageMac::CopyPixMap ( Rect& aSrcRegion,
|
||||
Rect& aDestRegion,
|
||||
const PRInt32 aDestDepth,
|
||||
const PRBool aCopyMaskBits,
|
||||
Handle *aDestData
|
||||
)
|
||||
{
|
||||
OSStatus err;
|
||||
PRBool pixelsNeedLocking = PR_FALSE;
|
||||
PixMap destPixmap;
|
||||
PixMapPtr srcPixmap;
|
||||
Handle *srcData;
|
||||
Handle resultData = nsnull;
|
||||
PRInt32 copyMode;
|
||||
CTabHandle destColorTable = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aDestData);
|
||||
*aDestData = nsnull;
|
||||
|
||||
//are we copying the image data or the mask
|
||||
if (aCopyMaskBits) {
|
||||
if (!mMaskBitsHandle) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
} else {
|
||||
srcPixmap = &mMaskPixmap;
|
||||
srcData = &mMaskBitsHandle;
|
||||
copyMode = srcCopy;
|
||||
if (aDestDepth <= 8)
|
||||
destColorTable = GetCTable(32 + aDestDepth);
|
||||
}
|
||||
} else {
|
||||
if (!mImageBitsHandle) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
} else {
|
||||
srcPixmap = &mImagePixmap;
|
||||
srcData = &mImageBitsHandle;
|
||||
copyMode = srcCopy | ditherCopy;
|
||||
if (aDestDepth <= 8)
|
||||
destColorTable = GetCTable(64 + aDestDepth);
|
||||
}
|
||||
}
|
||||
|
||||
// allocate the PixMap structure, then fill it out
|
||||
err = CreatePixMap( aDestRegion.right - aDestRegion.left,
|
||||
aDestRegion.bottom - aDestRegion.top,
|
||||
aDestDepth,
|
||||
destColorTable,
|
||||
destPixmap,
|
||||
resultData);
|
||||
if(err) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// otherwise lock and set up bits handles
|
||||
StHandleLocker srcBitsLocker(*srcData);
|
||||
StHandleLocker destBitsLocker(resultData);
|
||||
|
||||
srcPixmap->baseAddr = **srcData;
|
||||
|
||||
//CreatePixMap does not set the baseAdr as the bits handle must
|
||||
//be locked first, but it does initialise dstHandle for us so we
|
||||
//set up baseAddr to use aDestHandle
|
||||
destPixmap.baseAddr = *resultData;
|
||||
|
||||
//no need to lock either set of pixels as they're not in offscreen GWorlds.
|
||||
|
||||
::CopyBits( (BitMapPtr) srcPixmap,
|
||||
(BitMapPtr) &destPixmap,
|
||||
&aSrcRegion, &aDestRegion,
|
||||
copyMode, nsnull);
|
||||
err = QDError();
|
||||
NS_ASSERTION(err == noErr, "Error from QuickDraw copying PixMap Data");
|
||||
|
||||
//Clean up PixMap
|
||||
if (destPixmap.pmTable) ::DisposeCTable(destPixmap.pmTable);
|
||||
|
||||
if (err == noErr) {
|
||||
*aDestData = resultData;
|
||||
return NS_OK;
|
||||
} else {
|
||||
//deallocate handle data
|
||||
if (resultData) ::DisposeHandle(resultData);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} //CopyPixMap
|
||||
|
||||
/** Concantenate the data supplied in the given handles,
|
||||
the caller is responsible for disposing the result.
|
||||
This uses AllocateBitsHandle to allocate the new handle, to take
|
||||
advantage of spillover allocation into TempMemory
|
||||
@param aSrcData1 first piece of source data
|
||||
@param aSrcData2 second piece of src data
|
||||
@param astData on exit, contains a copy of aSrcData1 followed by
|
||||
a copy of aSrcData2
|
||||
@return nsresult an error code
|
||||
*/
|
||||
nsresult
|
||||
nsImageMac::ConcatBitsHandles( Handle aSrcData1,
|
||||
Handle aSrcData2,
|
||||
Handle *aDstData)
|
||||
{
|
||||
PRInt32 src1Size = ::GetHandleSize(aSrcData1);
|
||||
PRInt32 src2Size = ::GetHandleSize(aSrcData2);
|
||||
Handle result = nsnull;
|
||||
OSStatus err;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aDstData);
|
||||
*aDstData = nsnull;
|
||||
|
||||
err = AllocateBitsHandle(src1Size + src2Size, &result);
|
||||
if (err) {
|
||||
NS_ASSERTION(err == noErr, "Problem allocating handle for bits");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
} else {
|
||||
StHandleLocker dstLocker(*aDstData);
|
||||
::BlockMoveData(*aSrcData1, *result, src1Size);
|
||||
::BlockMoveData(*aSrcData2, *result + src1Size, src2Size);
|
||||
err = MemError();
|
||||
NS_ASSERTION(err == noErr, "Mem error copying icon mask data");
|
||||
if (err==noErr) {
|
||||
*aDstData = result;
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
} // ConcatBitsHandles
|
||||
|
||||
/** Make a completely opaque mask for an Icon of the specified size and depth.
|
||||
@param aWidth the width of the desired mask
|
||||
@param aHeight the height of the desired mask
|
||||
@param aDepth the bit depth of the desired mask
|
||||
@param aMask the mask
|
||||
@return nsresult an error code
|
||||
*/
|
||||
nsresult
|
||||
nsImageMac::MakeOpaqueMask( const PRInt32 aWidth,
|
||||
const PRInt32 aHeight,
|
||||
const PRInt32 aDepth,
|
||||
Handle *aMask)
|
||||
{
|
||||
//mask size = (width * height * depth)
|
||||
PRInt32 size = aHeight * CalculateRowBytes(aWidth, aDepth);
|
||||
OSStatus err;
|
||||
Handle resultData = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aMask);
|
||||
aMask = nsnull;
|
||||
|
||||
err = AllocateBitsHandle(size, &resultData);
|
||||
if (err != noErr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
StHandleLocker dstLocker(resultData);
|
||||
::memset(*resultData, 0xFF, size);
|
||||
*aMask = resultData;
|
||||
return NS_OK;
|
||||
} // MakeOpaqueMask
|
||||
|
||||
|
||||
/** Make icon types (OSTypes) from depth and size arguments
|
||||
Valid depths for icons: 1, 4, 8 and then 16, 24 or 32 are treat as 32.
|
||||
Valid masks for icons: 1 and 8.
|
||||
Valid sizes for icons:
|
||||
16x12 - mini (pretty obsolete)
|
||||
16x16 - small
|
||||
32x32 - large
|
||||
48x48 - huge
|
||||
128x128 - thumbnail
|
||||
|
||||
Exact mapping table (see note above about 1 bit masks being generally inseperable from 1 bit icons)
|
||||
|
||||
Icon
|
||||
depth height width type
|
||||
1 32 32 ICON (one bit icon without mask)
|
||||
4 12 16 icm4
|
||||
4 16 16 ics4
|
||||
4 32 32 icl4
|
||||
4 48 48 ich4
|
||||
8 12 16 icm8
|
||||
8 16 16 ics8
|
||||
8 32 32 icl8
|
||||
8 48 48 ich8
|
||||
32 16 16 is32
|
||||
32 32 32 il32
|
||||
32 48 48 ih32
|
||||
32 128 128 it32
|
||||
Mask
|
||||
1 16 12 icm#
|
||||
1 16 16 ics#
|
||||
1 32 32 ICN# (one bit icon and mask - you probably want one of these, not an 'ICON')
|
||||
1 48 48 ich#
|
||||
8 16 16 s8mk
|
||||
8 32 32 l8mk
|
||||
8 48 48 h8mk
|
||||
8 16 12 t8mk
|
||||
|
||||
16 and 24 bit depths will be promoted to 32 bit.
|
||||
Any other combination not in the above table gives nil
|
||||
|
||||
@param aHeight the height of the icon or mask
|
||||
@param aDepth the depth of the icon or mask
|
||||
@param aMask pass true for masks, false for icons
|
||||
@return the correct OSType as defined above
|
||||
*/
|
||||
OSType
|
||||
nsImageMac::MakeIconType(PRInt32 aHeight, PRInt32 aDepth, PRBool aMask)
|
||||
{
|
||||
switch(aHeight) {
|
||||
case 12:
|
||||
switch(aDepth) {
|
||||
case 1:
|
||||
return 'icm#';
|
||||
case 4:
|
||||
return 'icm4';
|
||||
case 8:
|
||||
return 'icm8';
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
case 16:
|
||||
switch(aDepth) {
|
||||
case 1:
|
||||
return 'ics#';
|
||||
case 4:
|
||||
return 'ics4';
|
||||
case 8:
|
||||
if(aMask)
|
||||
return 's8mk';
|
||||
else
|
||||
return 'ics8';
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
return 'is32';
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
case 32:
|
||||
switch(aDepth) {
|
||||
case 1:
|
||||
if(aMask)
|
||||
return 'ICN#';
|
||||
else
|
||||
return 'ICON';
|
||||
case 4:
|
||||
return 'icl4';
|
||||
case 8:
|
||||
if(aMask)
|
||||
return 'l8mk';
|
||||
else
|
||||
return 'icl8';
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
return 'il32';
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
case 48:
|
||||
switch(aDepth) {
|
||||
case 1:
|
||||
return 'ich#';
|
||||
case 4:
|
||||
return 'ich4';
|
||||
case 8:
|
||||
if(aMask)
|
||||
return 'h8mk';
|
||||
else
|
||||
return 'ich8';
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
return 'ih32';
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
case 128:
|
||||
if(aMask)
|
||||
return 't8mk';
|
||||
else
|
||||
switch (aDepth) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
return 'it32';
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
default:
|
||||
return nil;
|
||||
} //switch(aHeight)
|
||||
}
|
||||
|
||||
nsresult nsImageMac::SlowTile(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
@ -1153,5 +1712,3 @@ NS_IMETHODIMP nsImageMac::DrawTile(nsIRenderingContext &aContext,
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -43,7 +43,6 @@
|
||||
#include "nsIImageMac.h"
|
||||
#include <QDOffscreen.h>
|
||||
|
||||
|
||||
class nsImageMac : public nsIImage, public nsIImageMac
|
||||
{
|
||||
public:
|
||||
@ -100,6 +99,7 @@ public:
|
||||
PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
const nsRect &aTileRect);
|
||||
#ifdef USE_IMG2
|
||||
|
||||
|
||||
/**
|
||||
* Get the alpha depth for the image mask
|
||||
@ -117,11 +117,29 @@ public:
|
||||
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
|
||||
|
||||
|
||||
|
||||
// Convert to and from the os-native PICT format. Most likely
|
||||
// used for clipboard.
|
||||
NS_IMETHOD ConvertToPICT ( PicHandle* outPicture ) ;
|
||||
NS_IMETHOD ConvertFromPICT ( PicHandle inPicture ) ;
|
||||
NS_IMETHOD ConvertToPICT ( PicHandle* outPicture ) ;
|
||||
NS_IMETHOD ConvertFromPICT ( PicHandle inPicture ) ;
|
||||
//Convert to os-native icon format(s)
|
||||
//exact format depends on the bit depth
|
||||
NS_IMETHOD ConvertToIcon( const nsRect& aSrcRegion,
|
||||
const PRInt16 aIconDepth,
|
||||
const PRInt16 aIconSize,
|
||||
Handle* aOutIcon,
|
||||
OSType* aOutIconType);
|
||||
|
||||
NS_IMETHOD ConvertAlphaToIconMask( const nsRect& aSrcRegion,
|
||||
const PRInt16 aMaskDepth,
|
||||
const PRInt16 aMaskSize,
|
||||
Handle* aOutMask,
|
||||
OSType* aOutIconType);
|
||||
|
||||
static OSType MakeIconType(PRInt32 aHeight, PRInt32 aDepth, PRBool aMask);
|
||||
|
||||
|
||||
NS_IMETHOD GetPixMap ( PixMap** outPixMap ) ;
|
||||
|
||||
@ -145,6 +163,22 @@ protected:
|
||||
|
||||
static void ClearGWorld(GWorldPtr);
|
||||
static OSErr AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld);
|
||||
|
||||
nsresult CopyPixMap( Rect& aSrcRegion,
|
||||
Rect& aDestRegion,
|
||||
const PRInt32 aDestDepth,
|
||||
const PRBool aCopyMaskBits,
|
||||
Handle *aDestData
|
||||
);
|
||||
static nsresult ConcatBitsHandles( Handle srcData1,
|
||||
Handle srcData2,
|
||||
Handle *dstData);
|
||||
|
||||
|
||||
static nsresult MakeOpaqueMask( const PRInt32 aWidth,
|
||||
const PRInt32 aHeight,
|
||||
const PRInt32 aDepth,
|
||||
Handle *aMask);
|
||||
|
||||
static void CopyBitsWithMask(BitMap* srcBits, BitMap* maskBits, PRInt16 maskDepth, BitMap* destBits,
|
||||
const Rect& srcRect, const Rect& maskRect, const Rect& destRect);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user