#include "wx/image.h"
#include "wx/xpmdecod.h"
+#include "wx/rawbmp.h"
+
IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject )
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject )
#ifdef __DARWIN__
#include <ApplicationServices/ApplicationServices.h>
CTabHandle wxMacCreateColorTable( int numColors )
{
CTabHandle newColors; /* Handle to the new color table */
-
+
/* Allocate memory for the color table */
newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) +
sizeof (ColorSpec) * (numColors - 1) );
return newColors ;
}
-void wxMacDestroyColorTable( CTabHandle colors )
+void wxMacDestroyColorTable( CTabHandle colors )
{
DisposeHandle( (Handle) colors ) ;
}
OSErr err = noErr ;
GWorldPtr port ;
Rect rect = { 0 , 0 , height , width } ;
-
+
if ( depth < 0 )
{
- depth = wxDisplayDepth() ;
+ depth = wxDisplayDepth() ;
}
-
+
err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
if ( err == noErr )
{
(**icon).iconPMap.baseAddr = *(**icon).iconData ;
LockPixels(GetGWorldPixMap(image));
-
+
CopyBits(GetPortBitMapForCopyBits(image),
(BitMapPtr)&((**icon).iconPMap),
&imageBounds,
&imageBounds,
srcCopy | ditherCopy, nil);
-
-
+
+
UnlockPixels(GetGWorldPixMap(image));
HUnlock( (**icon).iconData ) ;
-
+
(**icon).iconMask.rowBytes = iconSize / 8 ;
(**icon).iconMask.bounds = frame ;
&(**icon).iconMask , &r , &r, srcCopy , nil ) ;
UnlockPixels(GetGWorldPixMap(image));
}
-
+
(**icon).iconMask.baseAddr = NULL ;
(**icon).iconBMap.baseAddr = NULL ;
(**icon).iconPMap.baseAddr = NULL ;
HUnlock((Handle)icon) ;
SetGWorld(saveWorld,saveHandle);
-
+
return icon;
}
CGrafPtr origPort ;
GDHandle origDev ;
- PicHandle pict;
+ PicHandle pict;
RGBColor white = { 0xffff ,0xffff , 0xffff } ;
RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ;
BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( mask ) ) ;
UnlockPixels( GetGWorldPixMap( mask ) ) ;
}
-
+
SetGWorld( wp , NULL ) ;
Rect portRect ;
if ( clipRgn )
- GetRegionBounds( clipRgn , &portRect ) ;
+ GetRegionBounds( clipRgn , &portRect ) ;
else
GetPortBounds( wp , &portRect ) ;
- pict = OpenPicture(&portRect);
- if(pict)
+ pict = OpenPicture(&portRect);
+ if(pict)
{
RGBForeColor( &black ) ;
RGBBackColor( &white ) ;
-
+
if ( clipRgn )
SetClip( clipRgn ) ;
-
+
LockPixels( GetGWorldPixMap( wp ) ) ;
- CopyBits(GetPortBitMapForCopyBits(wp),
- GetPortBitMapForCopyBits(wp),
- &portRect,
- &portRect,
- srcCopy,clipRgn);
+ CopyBits(GetPortBitMapForCopyBits(wp),
+ GetPortBitMapForCopyBits(wp),
+ &portRect,
+ &portRect,
+ srcCopy,clipRgn);
UnlockPixels( GetGWorldPixMap( wp ) ) ;
- ClosePicture();
+ ClosePicture();
}
SetGWorld( origPort , origDev ) ;
if ( clipRgn )
DisposeRgn( clipRgn ) ;
- return pict;
+ return pict;
}
-void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
+void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
{
memset( info , 0 , sizeof(ControlButtonContentInfo) ) ;
if ( bitmap.Ok() )
wxBitmapRefData * bmap = (wxBitmapRefData*) ( bitmap.GetRefData()) ;
if ( bmap == NULL )
return ;
-
+
if ( bmap->m_bitmapType == kMacBitmapTypePict )
{
info->contentType = kControlContentPictHandle ;
{
info->contentType = kControlContentCIconHandle ;
if ( bitmap.GetMask() )
- {
+ {
info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap()) ,
8 , bmap->m_width ) ;
}
m_hPict = NULL ;
m_hIcon = NULL ;
m_bitmapType = kMacBitmapTypeUnknownType ;
+ m_hasAlpha = false;
}
// TODO move this to a public function of Bitmap Ref
{
if ( !data )
return ;
-
+
switch (data->m_bitmapType)
{
case kMacBitmapTypePict :
DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ;
data->m_hIcon = NULL ;
}
-
+
default :
// unkown type ?
break ;
}
-
+
if (data->m_bitmapMask)
{
delete data->m_bitmapMask;
if ( no_bits == 1 )
{
M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
- MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
+ M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
M_BITMAPDATA->m_ok = (MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) != NULL ) ;
-
+
CGrafPtr origPort ;
GDHandle origDevice ;
-
+
GetGWorld( &origPort , &origDevice ) ;
SetGWorld( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ;
LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ;
-
+
// bits is a char array
-
+
unsigned char* linestart = (unsigned char*) bits ;
int linesize = ( the_width / (sizeof(unsigned char) * 8)) ;
if ( the_width % (sizeof(unsigned char) * 8) ) {
linesize += sizeof(unsigned char);
}
-
- RGBColor colors[2] = {
+
+ RGBColor colors[2] = {
{ 0xFFFF , 0xFFFF , 0xFFFF } ,
- { 0, 0 , 0 }
+ { 0, 0 , 0 }
} ;
-
+
for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
{
for ( int x = 0 ; x < the_width ; ++x )
}
}
UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ;
-
+
SetGWorld( origPort , origDevice ) ;
}
else
wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
wxXPMDecoder decoder;
wxImage img = decoder.ReadData(bits);
- wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") )
- *this = wxBitmap(img);
+ wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") )
+ *this = wxBitmap(img);
return TRUE;
}
(rect.y+rect.height <= GetHeight()),
wxNullBitmap, wxT("invalid bitmap or bitmap region") );
-
+
wxBitmap ret( rect.width, rect.height, GetDepth() );
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
wxBitmapRefData *ref = (wxBitmapRefData *)ret.GetRefData();
ref->m_numColors = M_BITMAPDATA->m_numColors;
- ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette;
+#if wxUSE_PALETTE
+ ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette;
+#endif // wxUSE_PALETTE
ref->m_bitmapType = M_BITMAPDATA->m_bitmapType;
// Copy sub region of this bitmap
RGBColor color;
mask = (GWorldPtr) GetMask()->GetMaskBitmap();
- submask = wxMacCreateGWorld(rect.width, rect.height, 1);
+ submask = wxMacCreateGWorld(rect.width, rect.height, GetMask()->GetDepth() );
LockPixels(GetGWorldPixMap(mask));
LockPixels(GetGWorldPixMap(submask));
m_refData = new wxBitmapRefData;
else
DisposeBitmapRefData( M_BITMAPDATA ) ;
-
+
M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
M_BITMAPDATA->m_hBitmap = bmp ;
M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ;
m_refData = new wxBitmapRefData;
else
DisposeBitmapRefData( M_BITMAPDATA ) ;
-
+
M_BITMAPDATA->m_bitmapType = kMacBitmapTypeIcon ;
M_BITMAPDATA->m_hIcon = ico ;
M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hIcon != NULL ) ;
m_refData = new wxBitmapRefData;
else
DisposeBitmapRefData( M_BITMAPDATA ) ;
-
+
M_BITMAPDATA->m_bitmapType = kMacBitmapTypePict ;
M_BITMAPDATA->m_hPict = pict ;
M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hPict != NULL ) ;
return true;
}
}
- wxLogWarning("no bitmap handler for type %d defined.", type);
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
return false;
}
wxBitmapHandler *handler = FindHandler(type);
if ( handler == NULL ) {
- wxLogWarning("no bitmap handler for type %d defined.", type);
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
return FALSE;
}
wxBitmap::wxBitmap(const wxImage& image, int depth)
{
wxCHECK_RET( image.Ok(), wxT("invalid image") )
- wxCHECK_RET( depth == -1, wxT("invalid bitmap depth") )
m_refData = new wxBitmapRefData();
-
+
// width and height of the device-dependent bitmap
int width = image.GetWidth();
int height = image.GetHeight();
// Create picture
Create( width , height , 32 ) ;
-
+
CGrafPtr origPort ;
GDHandle origDevice ;
GetGWorld( &origPort , &origDevice ) ;
SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ;
-
+
// Render image
register unsigned char* data = image.GetData();
char* destinationBase = GetPixBaseAddr( pixMap );
for (int x = 0; x < width; x++)
{
*destination++ = 0 ;
- *destination++ = *data++ ;
- *destination++ = *data++ ;
- *destination++ = *data++ ;
+ *destination++ = *data++ ;
+ *destination++ = *data++ ;
+ *destination++ = *data++ ;
}
- destinationBase += ((**pixMap).rowBytes & 0x7fff);
- destination = (unsigned char*) destinationBase ;
- }
- if ( image.HasMask() )
+ destinationBase += ((**pixMap).rowBytes & 0x7fff);
+ destination = (unsigned char*) destinationBase ;
+ }
+ if ( image.HasAlpha() )
+ {
+ unsigned char *alpha = image.GetAlpha();
+
+ wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
+ RGBColor color ;
+ wxBitmap maskBitmap ;
+
+ maskBitmap.Create( width, height, 24);
+ LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ memset( &color , 255 - *alpha , sizeof( color ) );
+ SetCPixel(x,y, &color);
+
+ alpha += 1 ;
+ }
+ } // for height
+ SetGWorld( (GWorldPtr) GetHBITMAP(), NULL);
+ SetMask(new wxMask( maskBitmap ));
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ }
+ else if ( image.HasMask() )
{
- data = image.GetData();
-
+ data = image.GetData();
+
wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
RGBColor white = { 0xffff, 0xffff, 0xffff };
RGBColor black = { 0 , 0 , 0 };
SetCPixel(x,y, &white);
}
else {
- SetCPixel(x,y, &black);
+ SetCPixel(x,y, &black);
}
data += 3 ;
}
SetMask(new wxMask( maskBitmap ));
UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
}
-
+
UnlockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP()) );
SetGWorld( origPort, origDevice );
}
wxImage wxBitmap::ConvertToImage() const
{
wxImage image;
-
+
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
// create an wxImage object
{
::PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(GetHICON()) ) ;
maskRgn = NewRgn() ;
- BitMapToRegion( maskRgn , &(**(MAC_WXHICON(GetHICON()))).iconMask ) ;
+ BitMapToRegion( maskRgn , &(**(MAC_WXHICON(GetHICON()))).iconMask ) ;
}
else
::DrawPicture( (PicHandle) GetPict(), &bitmaprect ) ;
data[index + 1] = g;
data[index + 2] = b;
if ( maskRgn )
- {
+ {
Point pt ;
pt.h = xx ;
pt.v = yy ;
return image.SaveFile(filename, type);
}
-
- wxLogWarning("no bitmap handler for type %d defined.", type);
+
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
return false;
}
M_BITMAPDATA->m_ok = isOk;
}
+#if wxUSE_PALETTE
wxPalette *wxBitmap::GetPalette() const
{
wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") );
M_BITMAPDATA->m_bitmapPalette = palette ;
}
+#endif // wxUSE_PALETTE
void wxBitmap::SetMask(wxMask *mask)
{
m_refData = new wxBitmapRefData;
// Remove existing mask if there is one.
- if (M_BITMAPDATA->m_bitmapMask)
- delete M_BITMAPDATA->m_bitmapMask;
+ delete M_BITMAPDATA->m_bitmapMask;
M_BITMAPDATA->m_bitmapMask = mask ;
}
WXHMETAFILE wxBitmap::GetPict( bool *created ) const
{
wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
-
+
PicHandle picture = NULL ; // This is the returned picture
if ( created )
(*created) = false ;
wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap"));
- wxCHECK_MSG(bitmap.GetDepth() == 1, false,
- wxT("Cannot create mask from colour bitmap"));
-
- m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), 1);
+ m_depth = bitmap.GetDepth() ;
+ m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() );
Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) );
}
wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
wxT("Cannot create mask from this bitmap type (TODO)"));
- // other types would require a temporary bitmap. not yet implemented
-
+ // other types would require a temporary bitmap. not yet implemented
+
wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap"));
- m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 );
+ m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 );
+ m_depth = 1 ;
LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap ) );
LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) );
RGBColor maskColor = MAC_WXCOLORREF(colour.GetPixel());
RGBColor colors[2] = {
{ 0xFFFF, 0xFFFF, 0xFFFF },
{ 0, 0, 0 }};
-
+
GetGWorld( &origPort , &origDevice ) ;
for (int w = 0; w < bitmap.GetWidth(); w++)
{
for (int h = 0; h < bitmap.GetHeight(); h++)
- {
+ {
SetGWorld( (GWorldPtr) bitmap.GetHBITMAP(), NULL ) ;
GetCPixel( w , h , &col ) ;
SetGWorld( (GWorldPtr) m_maskBitmap , NULL ) ;
public:
inline wxPICTResourceHandler()
{
- m_name = "Macintosh Pict resource";
- m_extension = "";
+ m_name = wxT("Macintosh Pict resource");
+ m_extension = wxEmptyString;
m_type = wxBITMAP_TYPE_PICT_RESOURCE;
};
int desiredWidth, int desiredHeight)
{
Str255 theName ;
-
-#if TARGET_CARBON
- c2pstrcpy( (StringPtr) theName , name ) ;
-#else
- strcpy( (char *) theName , name ) ;
- c2pstr( (char *)theName ) ;
-#endif
-
+ wxMacStringToPascal( name , theName ) ;
+
PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
if ( thePict )
{
PictInfo theInfo ;
-
+
GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
DetachResource( (Handle) thePict ) ;
M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
M_BITMAPHANDLERDATA->m_hPict = thePict ;
M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
-
+
M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
M_BITMAPHANDLERDATA->m_ok = true ;
M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
AddHandler(new wxPICTResourceHandler) ;
AddHandler(new wxICONResourceHandler) ;
}
+
+// ----------------------------------------------------------------------------
+// raw bitmap access support
+// ----------------------------------------------------------------------------
+
+void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
+{
+ if ( !Ok() )
+ {
+ // no bitmap, no data (raw or otherwise)
+ return NULL;
+ }
+
+ if ( M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld )
+ {
+ wxFAIL_MSG( _T("GetRawData() only supported for GWorlds") );
+
+ return NULL;
+ }
+
+ GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
+ PixMapHandle hPixMap = GetGWorldPixMap(gworld);
+ wxCHECK_MSG( hPixMap && *hPixMap, NULL,
+ _T("GetRawData(): failed to get PixMap from GWorld?") );
+
+ wxCHECK_MSG( (*hPixMap)->pixelSize == bpp, NULL,
+ _T("GetRawData(): pixel format mismatch") );
+
+ if ( !LockPixels(hPixMap) )
+ {
+ wxFAIL_MSG( _T("failed to lock PixMap in GetRawData()") );
+
+ return NULL;
+ }
+
+ data.m_width = GetWidth();
+ data.m_height = GetHeight();
+ data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
+
+ M_BITMAPDATA->m_hasAlpha = false;
+
+ return GetPixBaseAddr(hPixMap);
+}
+
+void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
+{
+ if ( !Ok() )
+ return;
+
+ if ( M_BITMAPDATA->m_hasAlpha )
+ {
+ wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase;
+
+ int w = data.GetWidth(),
+ h = data.GetHeight();
+
+ wxBitmap bmpMask(GetWidth(), GetHeight(), 32);
+ wxAlphaPixelData dataMask(bmpMask, data.GetOrigin(), wxSize(w, h));
+ wxAlphaPixelData::Iterator pMask(dataMask),
+ p(data);
+ for ( int y = 0; y < h; y++ )
+ {
+ wxAlphaPixelData::Iterator rowStartMask = pMask,
+ rowStart = p;
+
+ for ( int x = 0; x < w; x++ )
+ {
+ const wxAlphaPixelData::Iterator::ChannelType
+ alpha = p.Alpha();
+
+ pMask.Red() = alpha;
+ pMask.Green() = alpha;
+ pMask.Blue() = alpha;
+
+ ++p;
+ ++pMask;
+ }
+
+ p = rowStart;
+ p.OffsetY(data, 1);
+
+ pMask = rowStartMask;
+ pMask.OffsetY(dataMask, 1);
+ }
+
+ SetMask(new wxMask(bmpMask));
+ }
+
+ GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
+ PixMapHandle hPixMap = GetGWorldPixMap(gworld);
+ if ( hPixMap )
+ {
+ UnlockPixels(hPixMap);
+ }
+}
+
+void wxBitmap::UseAlpha()
+{
+ // remember that we are using alpha channel, we'll need to create a proper
+ // mask in UngetRawData()
+ M_BITMAPDATA->m_hasAlpha = true;
+}
+