X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2edd0e7c6689e0668a9fcc4fcde74dcdee3e69d8..d109c5849ed117966311a44875c97ae3d77b44e5:/src/mac/carbon/bitmap.cpp diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index 688ce82584..67ec567512 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -1,16 +1,15 @@ ///////////////////////////////////////////////////////////////////////////// // Name: bitmap.cpp // Purpose: wxBitmap -// Author: AUTHOR +// Author: Stefan Csomor // Modified by: -// Created: ??/??/98 +// Created: 1998-01-01 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR +// Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -#pragma implementation "bitmapbase.h" #pragma implementation "bitmap.h" #endif @@ -22,12 +21,11 @@ #include "wx/image.h" #include "wx/xpmdecod.h" -#if !USE_SHARED_LIBRARIES +#include "wx/rawbmp.h" + IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) -IMPLEMENT_ABSTRACT_CLASS(wxBitmapBase , wxGDIObject ) -IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandlerBase, wxObject ) -#endif +IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject ) #ifdef __DARWIN__ #include @@ -39,75 +37,75 @@ IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandlerBase, wxObject ) 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) ); - if (newColors != nil) - { - /* Initialize the fields */ - (**newColors).ctSeed = GetCTSeed(); - (**newColors).ctFlags = 0; - (**newColors).ctSize = numColors - 1; - /* Initialize the table of colors */ - } - return newColors ; + CTabHandle newColors; /* Handle to the new color table */ + + /* Allocate memory for the color table */ + newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) + + sizeof (ColorSpec) * (numColors - 1) ); + if (newColors != nil) + { + /* Initialize the fields */ + (**newColors).ctSeed = GetCTSeed(); + (**newColors).ctFlags = 0; + (**newColors).ctSize = numColors - 1; + /* Initialize the table of colors */ + } + return newColors ; } -void wxMacDestroyColorTable( CTabHandle colors ) +void wxMacDestroyColorTable( CTabHandle colors ) { - DisposeHandle( (Handle) colors ) ; + DisposeHandle( (Handle) colors ) ; } void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue ) { - (**newColors).ctTable[index].value = index; - (**newColors).ctTable[index].rgb.red = 0 ;// someRedValue; - (**newColors).ctTable[index].rgb.green = 0 ; // someGreenValue; - (**newColors).ctTable[index].rgb.blue = 0 ; // someBlueValue; + (**newColors).ctTable[index].value = index; + (**newColors).ctTable[index].rgb.red = red ; // someRedValue; + (**newColors).ctTable[index].rgb.green = green ; // someGreenValue; + (**newColors).ctTable[index].rgb.blue = blue ; // someBlueValue; } GWorldPtr wxMacCreateGWorld( int width , int height , int depth ) { - OSErr err = noErr ; - GWorldPtr port ; - Rect rect = { 0 , 0 , height , width } ; - - if ( depth < 0 ) - { - depth = wxDisplayDepth() ; - } - - err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ; - if ( err == noErr ) - { - return port ; - } - return NULL ; + OSErr err = noErr ; + GWorldPtr port ; + Rect rect = { 0 , 0 , height , width } ; + + if ( depth < 0 ) + { + depth = wxDisplayDepth() ; + } + + err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ; + if ( err == noErr ) + { + return port ; + } + return NULL ; } void wxMacDestroyGWorld( GWorldPtr gw ) { - if ( gw ) - DisposeGWorld( gw ) ; + if ( gw ) + DisposeGWorld( gw ) ; } #define kDefaultRes 0x00480000 /* Default resolution is 72 DPI; Fixed type */ OSErr SetupCIconHandlePixMap( CIconHandle icon , short depth , Rect *bounds , CTabHandle colors ) { - CTabHandle newColors; /* Color table used for the off-screen PixMap */ - Ptr offBaseAddr; /* Pointer to the off-screen pixel image */ - OSErr error; /* Returns error code */ - short bytesPerRow; /* Number of bytes per row in the PixMap */ + CTabHandle newColors; /* Color table used for the off-screen PixMap */ + Ptr offBaseAddr; /* Pointer to the off-screen pixel image */ + OSErr error; /* Returns error code */ + short bytesPerRow; /* Number of bytes per row in the PixMap */ error = noErr; newColors = nil; offBaseAddr = nil; - bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) / 32) * 4; + bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) / 32) * 4; /* Clone the clut if indexed color; allocate a dummy clut if direct color*/ if (depth <= 8) @@ -183,15 +181,15 @@ OSErr SetupCIconHandlePixMap( CIconHandle icon , short depth , Rect *bounds , C CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , short iconSize ) { - GWorldPtr saveWorld; - GDHandle saveHandle; + GWorldPtr saveWorld; + GDHandle saveHandle; - GetGWorld(&saveWorld,&saveHandle); // save Graphics env state - SetGWorld(image,nil); + GetGWorld(&saveWorld,&saveHandle); // save Graphics env state + SetGWorld(image,nil); Rect frame = { 0 , 0 , iconSize , iconSize } ; Rect imageBounds = frame ; - GetPortBounds( image , &imageBounds ) ; + GetPortBounds( image , &imageBounds ) ; int bwSize = iconSize / 8 * iconSize ; CIconHandle icon = (CIconHandle) NewHandleClear( sizeof ( CIcon ) + 2 * bwSize) ; @@ -200,18 +198,18 @@ CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , HLock( (**icon).iconData ) ; (**icon).iconPMap.baseAddr = *(**icon).iconData ; - LockPixels(GetGWorldPixMap(image)); - - CopyBits(GetPortBitMapForCopyBits(image), - (BitMapPtr)&((**icon).iconPMap), - &imageBounds, - &imageBounds, - srcCopy | ditherCopy, nil); - - - UnlockPixels(GetGWorldPixMap(image)); + 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 ; @@ -222,30 +220,34 @@ CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , if ( mask ) { + Rect r ; + GetPortBounds( image , &r ) ; LockPixels(GetGWorldPixMap(mask) ) ; CopyBits(GetPortBitMapForCopyBits(mask) , - &(**icon).iconBMap , &imageBounds , &imageBounds, srcCopy , nil ) ; + &(**icon).iconBMap , &r , &r, srcCopy , nil ) ; CopyBits(GetPortBitMapForCopyBits(mask) , - &(**icon).iconMask , &imageBounds , &imageBounds, srcCopy , nil ) ; + &(**icon).iconMask , &r , &r, srcCopy , nil ) ; UnlockPixels(GetGWorldPixMap( mask ) ) ; } else { - LockPixels(GetGWorldPixMap(image)); + Rect r ; + GetPortBounds( image , &r ) ; + LockPixels(GetGWorldPixMap(image)); CopyBits(GetPortBitMapForCopyBits(image) , - &(**icon).iconBMap , &imageBounds , &imageBounds, srcCopy , nil ) ; + &(**icon).iconBMap , &r , &r, srcCopy , nil ) ; CopyBits(GetPortBitMapForCopyBits(image) , - &(**icon).iconMask , &imageBounds , &imageBounds, srcCopy , nil ) ; - UnlockPixels(GetGWorldPixMap(image)); + &(**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; + SetGWorld(saveWorld,saveHandle); + + return icon; } PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) @@ -253,7 +255,7 @@ PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) CGrafPtr origPort ; GDHandle origDev ; - PicHandle pict; + PicHandle pict; RGBColor white = { 0xffff ,0xffff , 0xffff } ; RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; @@ -269,85 +271,147 @@ PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( mask ) ) ; UnlockPixels( GetGWorldPixMap( mask ) ) ; } - + SetGWorld( wp , NULL ) ; Rect portRect ; - GetPortBounds( wp , &portRect ) ; - - pict = OpenPicture(&portRect); - if(pict) + if ( clipRgn ) + GetRegionBounds( clipRgn , &portRect ) ; + else + GetPortBounds( wp , &portRect ) ; + 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 ) ; - return pict; + if ( clipRgn ) + DisposeRgn( clipRgn ) ; + return pict; +} + +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->u.picture = MAC_WXHMETAFILE(bmap->m_hPict) ; + } + else if ( bmap->m_bitmapType == kMacBitmapTypeGrafWorld ) + { + if ( (forceType == kControlContentCIconHandle || ( bmap->m_width == bmap->m_height && forceType != kControlContentPictHandle ) ) && ((bmap->m_width & 0x3) == 0) ) + { + info->contentType = kControlContentCIconHandle ; + if ( bitmap.GetMask() ) + { + info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap()) , + 8 , bmap->m_width ) ; + } + else + { + info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL , + 8 , bmap->m_width ) ; + } + } + else + { + info->contentType = kControlContentPictHandle ; + if ( bitmap.GetMask() ) + { + info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap() ) ) ; + } + else + { + info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL ) ; + } + } + } + else if ( bmap->m_bitmapType == kMacBitmapTypeIcon ) + { + info->contentType = kControlContentCIconHandle ; + info->u.cIconHandle = MAC_WXHICON(bmap->m_hIcon) ; + } + } } wxBitmapRefData::wxBitmapRefData() + : m_width(0) + , m_height(0) + , m_depth(0) + , m_ok(FALSE) + , m_numColors(0) + , m_quality(0) { - m_ok = FALSE; - m_width = 0; - m_height = 0; - m_depth = 0; - m_quality = 0; - m_numColors = 0; m_bitmapMask = NULL; m_hBitmap = NULL ; m_hPict = NULL ; m_hIcon = NULL ; m_bitmapType = kMacBitmapTypeUnknownType ; + m_hasAlpha = false; } -// TODO move this do a public function of Bitmap Ref +// TODO move this to a public function of Bitmap Ref static void DisposeBitmapRefData(wxBitmapRefData *data) { - switch (data->m_bitmapType) - { - case kMacBitmapTypePict : - { - if ( data->m_hPict ) - { - KillPicture( data->m_hPict ) ; - data->m_hPict = NULL ; - } - } - break ; - case kMacBitmapTypeGrafWorld : - { - if ( data->m_hBitmap ) - { - wxMacDestroyGWorld( data->m_hBitmap ) ; - data->m_hBitmap = NULL ; - } - } - break ; - case kMacBitmapTypeIcon : - if ( data->m_hIcon ) - { - DisposeCIcon( data->m_hIcon ) ; - data->m_hIcon = NULL ; - } - - default : - // unkown type ? - break ; - } - - if (data->m_bitmapMask) - { - delete data->m_bitmapMask; - data->m_bitmapMask = NULL; - } + if ( !data ) + return ; + + switch (data->m_bitmapType) + { + case kMacBitmapTypePict : + { + if ( data->m_hPict ) + { + KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; + data->m_hPict = NULL ; + } + } + break ; + case kMacBitmapTypeGrafWorld : + { + if ( data->m_hBitmap ) + { + wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; + data->m_hBitmap = NULL ; + } + } + break ; + case kMacBitmapTypeIcon : + if ( data->m_hIcon ) + { + DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; + data->m_hIcon = NULL ; + } + + default : + // unkown type ? + break ; + } + + if (data->m_bitmapMask) + { + delete data->m_bitmapMask; + data->m_bitmapMask = NULL; + } } wxBitmapRefData::~wxBitmapRefData() @@ -355,9 +419,6 @@ wxBitmapRefData::~wxBitmapRefData() DisposeBitmapRefData( this ) ; } -wxList wxBitmapBase::sm_handlers; - - bool wxBitmap::CopyFromIcon(const wxIcon& icon) { Ref(icon) ; @@ -385,28 +446,28 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits { M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ; - M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; - - CGrafPtr origPort ; - GDHandle origDevice ; - + M_BITMAPDATA->m_ok = (MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) != NULL ) ; + + CGrafPtr origPort ; + GDHandle origDevice ; + GetGWorld( &origPort , &origDevice ) ; - SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ; - LockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; - + 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 ) @@ -424,8 +485,8 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits } } } - UnlockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; - + UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ; + SetGWorld( origPort , origDevice ) ; } else @@ -454,8 +515,8 @@ bool wxBitmap::CreateFromXpm(const char **bits) 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; } @@ -477,11 +538,11 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const (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") ); - WXHBITMAP origPort; + GWorldPtr origPort; GDHandle origDevice; GetGWorld( &origPort, &origDevice ); @@ -490,7 +551,9 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const 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 @@ -503,11 +566,11 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const // Copy mask if(GetMask()) { - WXHBITMAP submask, mask; + GWorldPtr submask, mask; RGBColor color; - mask = GetMask()->GetMaskBitmap(); - submask = wxMacCreateGWorld(rect.width, rect.height, 1); + mask = (GWorldPtr) GetMask()->GetMaskBitmap(); + submask = wxMacCreateGWorld(rect.width, rect.height, GetMask()->GetDepth() ); LockPixels(GetGWorldPixMap(mask)); LockPixels(GetGWorldPixMap(submask)); @@ -530,11 +593,11 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const // Copy bitmap if(GetHBITMAP()) { - WXHBITMAP subbitmap, bitmap; + GWorldPtr subbitmap, bitmap; RGBColor color; - bitmap = GetHBITMAP(); - subbitmap = ref->m_hBitmap ; + bitmap = (GWorldPtr) GetHBITMAP(); + subbitmap = (GWorldPtr) ref->m_hBitmap ; LockPixels(GetGWorldPixMap(bitmap)); LockPixels(GetGWorldPixMap(subbitmap)); @@ -569,7 +632,7 @@ bool wxBitmap::Create(int w, int h, int d) M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ; - M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; return M_BITMAPDATA->m_ok; } @@ -582,11 +645,38 @@ int wxBitmap::GetBitmapType() const void wxBitmap::SetHBITMAP(WXHBITMAP bmp) { - DisposeBitmapRefData( M_BITMAPDATA ) ; - + if (!M_BITMAPDATA) + 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_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; +} + +void wxBitmap::SetHICON(WXHICON ico) +{ + if (!M_BITMAPDATA) + 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 ) ; +} + +void wxBitmap::SetPict(WXHMETAFILE pict) +{ + if (!M_BITMAPDATA) + 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 ) ; } bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) @@ -597,7 +687,7 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) if ( handler ) { - m_refData = new wxBitmapRefData; + m_refData = new wxBitmapRefData; return handler->LoadFile(this, filename, type, -1, -1); } @@ -609,7 +699,7 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) return true; } } - wxLogWarning("no bitmap handler for type %d defined.", type); + wxLogWarning(wxT("no bitmap handler for type %d defined."), type); return false; } @@ -622,7 +712,7 @@ bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int 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; } @@ -633,10 +723,9 @@ bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int 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(); @@ -644,19 +733,17 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) // Create picture Create( width , height , 32 ) ; - + CGrafPtr origPort ; GDHandle origDevice ; - PixMapHandle pixMap = GetGWorldPixMap(GetHBITMAP()) ; + PixMapHandle pixMap = GetGWorldPixMap((GWorldPtr)GetHBITMAP()) ; LockPixels( pixMap ); GetGWorld( &origPort , &origDevice ) ; - SetGWorld( GetHBITMAP() , NULL ) ; - - // Render image - RGBColor colorRGB ; + SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ; + // Render image register unsigned char* data = image.GetData(); char* destinationBase = GetPixBaseAddr( pixMap ); register unsigned char* destination = (unsigned char*) destinationBase ; @@ -665,25 +752,51 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) 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() ) { - data = image.GetData(); - + 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(); + wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); RGBColor white = { 0xffff, 0xffff, 0xffff }; RGBColor black = { 0 , 0 , 0 }; wxBitmap maskBitmap ; maskBitmap.Create( width, height, 1); - LockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) ); - SetGWorld(maskBitmap.GetHBITMAP(), NULL); + LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); + SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL); for (int y = 0; y < height; y++) { @@ -694,24 +807,24 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) SetCPixel(x,y, &white); } else { - SetCPixel(x,y, &black); + SetCPixel(x,y, &black); } data += 3 ; } } // for height - SetGWorld(GetHBITMAP(), NULL); + SetGWorld( (GWorldPtr) GetHBITMAP(), NULL); SetMask(new wxMask( maskBitmap )); - UnlockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) ); + UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) ); } - - UnlockPixels( GetGWorldPixMap(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 @@ -723,8 +836,10 @@ wxImage wxBitmap::ConvertToImage() const wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); - WXHBITMAP origPort; + GWorldPtr origPort; GDHandle origDevice; + RgnHandle maskRgn = NULL ; + GWorldPtr tempPort = NULL ; int index; RGBColor color; // background color set to RGB(16,16,16) in consistent with wxGTK @@ -733,9 +848,28 @@ wxImage wxBitmap::ConvertToImage() const wxMask *mask = GetMask(); GetGWorld( &origPort, &origDevice ); - LockPixels(GetGWorldPixMap(GetHBITMAP())); - SetGWorld( GetHBITMAP(), NULL); - + if ( GetBitmapType() != kMacBitmapTypeGrafWorld ) + { + tempPort = wxMacCreateGWorld( width , height , -1) ; + } + else + { + tempPort = (GWorldPtr) GetHBITMAP() ; + } + LockPixels(GetGWorldPixMap(tempPort)); + SetGWorld( tempPort, NULL); + if ( GetBitmapType() == kMacBitmapTypePict || GetBitmapType() == kMacBitmapTypeIcon ) + { + Rect bitmaprect = { 0 , 0 , height, width }; + if ( GetBitmapType() == kMacBitmapTypeIcon ) + { + ::PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(GetHICON()) ) ; + maskRgn = NewRgn() ; + BitMapToRegion( maskRgn , &(**(MAC_WXHICON(GetHICON()))).iconMask ) ; + } + else + ::DrawPicture( (PicHandle) GetPict(), &bitmaprect ) ; + } // Copy data into image index = 0; for (int yy = 0; yy < height; yy++) @@ -749,27 +883,50 @@ wxImage wxBitmap::ConvertToImage() const data[index ] = r; data[index + 1] = g; data[index + 2] = b; - if (mask) + if ( maskRgn ) { - if (mask->PointMasked(xx,yy)) + Point pt ; + pt.h = xx ; + pt.v = yy ; + if ( !PtInRgn( pt , maskRgn ) ) { data[index ] = mask_r; data[index + 1] = mask_g; data[index + 2] = mask_b; } } + else + { + if (mask) + { + if (mask->PointMasked(xx,yy)) + { + data[index ] = mask_r; + data[index + 1] = mask_g; + data[index + 2] = mask_b; + } + } + } index += 3; } } - if (mask) + if (mask || maskRgn ) { image.SetMaskColour( mask_r, mask_g, mask_b ); image.SetMask( true ); } // Free resources - UnlockPixels(GetGWorldPixMap(GetHBITMAP())); + UnlockPixels(GetGWorldPixMap( tempPort )); SetGWorld(origPort, origDevice); + if ( GetBitmapType() != kMacBitmapTypeGrafWorld ) + { + wxMacDestroyGWorld( tempPort ) ; + } + if ( maskRgn ) + { + DisposeRgn( maskRgn ) ; + } return image; } @@ -790,8 +947,8 @@ bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, 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; } @@ -875,6 +1032,7 @@ void wxBitmap::SetOk(bool isOk) M_BITMAPDATA->m_ok = isOk; } +#if wxUSE_PALETTE wxPalette *wxBitmap::GetPalette() const { wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") ); @@ -889,6 +1047,7 @@ void wxBitmap::SetPalette(const wxPalette& palette) M_BITMAPDATA->m_bitmapPalette = palette ; } +#endif // wxUSE_PALETTE void wxBitmap::SetMask(wxMask *mask) { @@ -896,8 +1055,7 @@ 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 ; } @@ -906,161 +1064,38 @@ WXHBITMAP wxBitmap::GetHBITMAP() const { wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - return M_BITMAPDATA->m_hBitmap; + return MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); } -PicHandle wxBitmap::GetPict() const +WXHMETAFILE wxBitmap::GetPict( bool *created ) const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - - PicHandle picture; // This is the returned picture + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - // If bitmap already in Pict format return pointer - if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { + PicHandle picture = NULL ; // This is the returned picture + if ( created ) + (*created) = false ; + // If bitmap already in Pict format return pointer + if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { return M_BITMAPDATA->m_hPict; - } - else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { + } + else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { // Invalid bitmap return NULL; - } - - RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; - RGBColor white = { 0xffff ,0xffff , 0xffff } ; - RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; - CGrafPtr origPort; - GDHandle origDev ; - wxMask *mask; - Rect portRect ; - - GetPortBounds( GetHBITMAP() , &portRect ) ; - int width = portRect.right - portRect.left ; - int height = portRect.bottom - portRect.top ; - - LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; - GetGWorld( &origPort , &origDev ) ; - - mask = GetMask(); - - SetGWorld( GetHBITMAP() , NULL ) ; - - picture = OpenPicture(&portRect); // open a picture, this disables drawing - if(!picture) { - return NULL; - } - - if( mask ) - { -#ifdef __DARWIN__ - RGBColor trans = white; -#else - RGBBackColor( &gray ); - EraseRect( &portRect ); - RGBColor trans = gray; -#endif - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - PenMode(transparent); - - for ( int y = 0 ; y < height ; ++y ) - { - for( int x = 0 ; x < width ; ++x ) - { - if ( !mask->PointMasked(x,y) ) - { - RGBColor col ; - - GetCPixel( x + portRect.left , y + portRect.top , &col ) ; - SetCPixel( x + portRect.left , y + portRect.top , &col ) ; - } - else { - // With transparency this sets a blank pixel - SetCPixel( x + portRect.left , y + portRect.top , &trans); - } - } - } - } - else - { - RGBBackColor( &gray ) ; - EraseRect(&portRect); - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - - CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()), - // src PixMap - we copy image over itself - - GetPortBitMapForCopyBits(GetHBITMAP()), - // dst PixMap - no drawing occurs - &portRect, // srcRect - it will be recorded and compressed - - &portRect, // dstRect - into the picture that is open - - srcCopy,NULL); // copyMode and no clip region - } - ClosePicture(); // We are done recording the picture - UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; - SetGWorld( origPort , origDev ) ; - - return picture; // return our groovy pict handle -} - -void wxBitmap::AddHandler(wxBitmapHandler *handler) -{ - sm_handlers.Append(handler); -} - -void wxBitmap::InsertHandler(wxBitmapHandler *handler) -{ - sm_handlers.Insert(handler); -} - -bool wxBitmap::RemoveHandler(const wxString& name) -{ - wxBitmapHandler *handler = FindHandler(name); - if ( handler ) - { - sm_handlers.DeleteObject(handler); - return TRUE; } else - return FALSE; -} - -wxBitmapHandler *wxBitmap::FindHandler(const wxString& name) -{ - wxNode *node = sm_handlers.First(); - while ( node ) { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetName() == name ) - return handler; - node = node->Next(); - } - return NULL; -} - -wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, wxBitmapType type) -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetExtension() == extension && - (type == -1 || handler->GetType() == type) ) - return handler; - node = node->Next(); - } - return NULL; -} - -wxBitmapHandler *wxBitmap::FindHandler(wxBitmapType type) -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if (handler->GetType() == type) - return handler; - node = node->Next(); + if ( GetMask() ) + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , MAC_WXHBITMAP(GetMask()->GetMaskBitmap() ) ) ; + } + else + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ; + } + if ( created && picture ) + (*created) = true ; } - return NULL; + return picture ; } /* @@ -1068,40 +1103,40 @@ wxBitmapHandler *wxBitmap::FindHandler(wxBitmapType type) */ wxMask::wxMask() + : m_maskBitmap(NULL) { - m_maskBitmap = 0; } // Construct a mask from a bitmap and a colour indicating // the transparent area wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) + : m_maskBitmap(NULL) { - m_maskBitmap = 0; Create(bitmap, colour); } // Construct a mask from a bitmap and a palette index indicating // the transparent area wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) + : m_maskBitmap(NULL) { - m_maskBitmap = 0; Create(bitmap, paletteIndex); } // Construct a mask from a mono bitmap (copies the bitmap). wxMask::wxMask(const wxBitmap& bitmap) + : m_maskBitmap(NULL) { - m_maskBitmap = 0; Create(bitmap); } wxMask::~wxMask() { - if ( m_maskBitmap ) - { - wxMacDestroyGWorld( m_maskBitmap ) ; - m_maskBitmap = NULL ; - } + if ( m_maskBitmap ) + { + wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; + m_maskBitmap = NULL ; + } } // Create a mask from a mono bitmap (copies the bitmap). @@ -1109,7 +1144,7 @@ bool wxMask::Create(const wxBitmap& bitmap) { if ( m_maskBitmap ) { - wxMacDestroyGWorld( m_maskBitmap ) ; + wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; m_maskBitmap = NULL ; } wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, @@ -1118,19 +1153,17 @@ bool wxMask::Create(const wxBitmap& bitmap) 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(m_maskBitmap) ); - LockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) ); - CopyBits(GetPortBitMapForCopyBits(bitmap.GetHBITMAP()), - GetPortBitMapForCopyBits(m_maskBitmap), + LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) ); + LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) ); + CopyBits(GetPortBitMapForCopyBits( (GWorldPtr) bitmap.GetHBITMAP()), + GetPortBitMapForCopyBits( (GWorldPtr) m_maskBitmap), &rect, &rect, srcCopy, 0); - UnlockPixels( GetGWorldPixMap(m_maskBitmap) ); - UnlockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) ); + UnlockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) ); + UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) ); return FALSE; } @@ -1139,8 +1172,8 @@ bool wxMask::Create(const wxBitmap& bitmap) // the transparent area bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) { -// TODO - wxCHECK_MSG( 0, false, wxT("Not implemented")); + // TODO + wxCHECK_MSG( 0, false, wxT("wxMask::Create not yet implemented")); return FALSE; } @@ -1148,59 +1181,60 @@ bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) // the transparent area bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) { - if ( m_maskBitmap ) - { - wxMacDestroyGWorld( m_maskBitmap ) ; - m_maskBitmap = NULL ; - } - wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, + if ( m_maskBitmap ) + { + wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ; + m_maskBitmap = NULL ; + } + 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 ); - LockPixels( GetGWorldPixMap( m_maskBitmap ) ); - LockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ); - RGBColor maskColor = colour.GetPixel(); + 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()); // this is not very efficient, but I can't think // of a better way of doing it - CGrafPtr origPort ; - GDHandle origDevice ; + CGrafPtr origPort ; + GDHandle origDevice ; RGBColor col; RGBColor colors[2] = { { 0xFFFF, 0xFFFF, 0xFFFF }, { 0, 0, 0 }}; - - GetGWorld( &origPort , &origDevice ) ; - for (int w = 0; w < bitmap.GetWidth(); w++) + + GetGWorld( &origPort , &origDevice ) ; + for (int w = 0; w < bitmap.GetWidth(); w++) { for (int h = 0; h < bitmap.GetHeight(); h++) - { - SetGWorld( bitmap.GetHBITMAP(), NULL ) ; - GetCPixel( w , h , &col ) ; - SetGWorld( m_maskBitmap , NULL ) ; + { + SetGWorld( (GWorldPtr) bitmap.GetHBITMAP(), NULL ) ; + GetCPixel( w , h , &col ) ; + SetGWorld( (GWorldPtr) m_maskBitmap , NULL ) ; if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue) { - SetCPixel( w , h , &colors[0] ) ; + SetCPixel( w , h , &colors[0] ) ; } else { - SetCPixel( w , h , &colors[1] ) ; + SetCPixel( w , h , &colors[1] ) ; } } } - UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ; - UnlockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ) ; - SetGWorld( origPort , origDevice ) ; + UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ; + UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) ) ; + SetGWorld( origPort , origDevice ) ; return TRUE; } bool wxMask::PointMasked(int x, int y) { - WXHBITMAP origPort; + GWorldPtr origPort; GDHandle origDevice; RGBColor color; bool masked = true; @@ -1208,11 +1242,11 @@ bool wxMask::PointMasked(int x, int y) GetGWorld( &origPort, &origDevice); //Set port to mask and see if it masked (1) or not ( 0 ) - SetGWorld(m_maskBitmap, NULL); - LockPixels(GetGWorldPixMap(m_maskBitmap)); + SetGWorld( (GWorldPtr) m_maskBitmap, NULL); + LockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap)); GetCPixel(x,y, &color); masked = !(color.red == 0 && color.green == 0 && color.blue == 0); - UnlockPixels(GetGWorldPixMap(m_maskBitmap)); + UnlockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap)); SetGWorld( origPort, origDevice); @@ -1223,7 +1257,9 @@ bool wxMask::PointMasked(int x, int y) * wxBitmapHandler */ -IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) +wxBitmapHandler::~wxBitmapHandler() +{ +} bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) { @@ -1251,8 +1287,8 @@ class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler 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; }; @@ -1264,73 +1300,136 @@ IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler) bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight) { - Str255 theName ; - -#if TARGET_CARBON - c2pstrcpy( (StringPtr) theName , name ) ; -#else - strcpy( (char *) theName , name ) ; - c2pstr( (char *)theName ) ; -#endif - - 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 ; -// M_BITMAPHANDLERDATA->m_bitmapPalette; -// M_BITMAPHANDLERDATA->m_quality; - return TRUE ; - } - return FALSE ; -} - -#if 0 // The following is an example for creating a bitmap handler - -// TODO: bitmap handlers, a bit like this: -class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler -{ - DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) -public: - inline wxBMPResourceHandler() + Str255 theName ; + wxMacStringToPascal( name , theName ) ; + + PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ; + if ( thePict ) { - m_name = "Windows bitmap resource"; - m_extension = ""; - m_type = wxBITMAP_TYPE_BMP_RESOURCE; - }; + 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 ; +// M_BITMAPHANDLERDATA->m_bitmapPalette; +// M_BITMAPHANDLERDATA->m_quality; + return TRUE ; + } + return FALSE ; +} - virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth, int desiredHeight); -}; -IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) +void wxBitmap::InitStandardHandlers() +{ + AddHandler(new wxPICTResourceHandler) ; + AddHandler(new wxICONResourceHandler) ; +} -#endif +// ---------------------------------------------------------------------------- +// 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; + } -void wxBitmap::CleanUpHandlers() + 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) { - wxNode *node = sm_handlers.First(); - while ( node ) + if ( !Ok() ) + return; + + if ( M_BITMAPDATA->m_hasAlpha ) { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - wxNode *next = node->Next(); - delete handler; - delete node; - node = next; + 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::InitStandardHandlers() +void wxBitmap::UseAlpha() { - AddHandler(new wxPICTResourceHandler) ; - AddHandler(new wxICONResourceHandler) ; + // remember that we are using alpha channel, we'll need to create a proper + // mask in UngetRawData() + M_BITMAPDATA->m_hasAlpha = true; } +