1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/bitmap.cpp 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #include "wx/bitmap.h" 
  18     #include "wx/dcmemory.h" 
  23 #include "wx/metafile.h" 
  24 #include "wx/xpmdecod.h" 
  26 #include "wx/rawbmp.h" 
  28 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  29 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  31 #include <ApplicationServices/ApplicationServices.h> 
  32 #include <QuickTime/QuickTime.h> 
  34 #include "wx/mac/uma.h" 
  36 // Implementation Notes 
  37 // -------------------- 
  39 // we are always working with a 32 bit deep pixel buffer 
  40 // under QuickDraw its alpha parts are going to be ignored in the GWorld, 
  41 // therefore we have a separate GWorld there for blitting the mask in 
  43 // under Quartz then content is transformed into a CGImageRef representing the same data 
  44 // which can be transferred to the GPU by the OS for fast rendering 
  46 class WXDLLEXPORT wxBitmapRefData
: public wxGDIRefData
 
  48     friend class WXDLLIMPEXP_FWD_CORE wxIcon
; 
  49     friend class WXDLLIMPEXP_FWD_CORE wxCursor
; 
  51     wxBitmapRefData(int width 
, int height 
, int depth
); 
  53     wxBitmapRefData(const wxBitmapRefData 
&tocopy
); 
  55     virtual ~wxBitmapRefData(); 
  57     virtual bool IsOk() const { return m_ok
; } 
  60     void SetOk( bool isOk
) { m_ok 
= isOk
; } 
  62     void SetWidth( int width 
) { m_width 
= width
; } 
  63     void SetHeight( int height 
) { m_height 
= height
; } 
  64     void SetDepth( int depth 
) { m_depth 
= depth
; } 
  66     int GetWidth() const { return m_width
; } 
  67     int GetHeight() const { return m_height
; } 
  68     int GetDepth() const { return m_depth
; } 
  70     void *GetRawAccess() const; 
  71     void *BeginRawAccess(); 
  74     bool HasAlpha() const { return m_hasAlpha
; } 
  75     void UseAlpha( bool useAlpha 
); 
  79     wxPalette     m_bitmapPalette
; 
  80 #endif // wxUSE_PALETTE 
  82     wxMask 
*      m_bitmapMask
; // Optional mask 
  83     CGImageRef    
CreateCGImage() const; 
  85     // returns true if the bitmap has a size that 
  86     // can be natively transferred into a true icon 
  87     // if no is returned GetIconRef will still produce 
  88     // an icon but it will be generated via a PICT and 
  89     // rescaled to 16 x 16 
  92     // caller should increase ref count if needed longer 
  93     // than the bitmap exists 
  96     // returns a Pict from the bitmap content 
  97     PicHandle     
GetPictHandle(); 
  99     CGContextRef  
GetBitmapContext() const; 
 101     int           GetBytesPerRow() const { return m_bytesPerRow
; } 
 103     bool Create(int width 
, int height 
, int depth
); 
 111     wxMemoryBuffer m_memBuf
; 
 112     int           m_rawAccessCount
; 
 114     mutable CGImageRef    m_cgImageRef
; 
 117     PicHandle     m_pictHandle
; 
 119     CGContextRef  m_hBitmap
; 
 123 #define wxMAC_USE_PREMULTIPLIED_ALPHA 1 
 124 static const int kBestByteAlignement 
= 16; 
 125 static const int kMaskBytesPerPixel 
= 1; 
 127 static int GetBestBytesPerRow( int rawBytes 
) 
 129     return (((rawBytes
)+kBestByteAlignement
-1) & ~(kBestByteAlignement
-1) ); 
 134 // this is used for more controls than just the wxBitmap button, also for notebooks etc 
 136 void wxMacCreateBitmapButton( ControlButtonContentInfo
*info 
, const wxBitmap
& bitmap 
, int forceType 
) 
 138     memset( info 
, 0 , sizeof(ControlButtonContentInfo
) ) ; 
 141         wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 145         if ( forceType 
== 0  ) 
 147             forceType 
= kControlContentCGImageRef
; 
 150         if ( forceType 
== kControlContentIconRef 
) 
 153             wxBitmapRefData
* bmp 
= bmap 
; 
 155             if ( !bmap
->HasNativeSize() ) 
 157                 // as PICT conversion will only result in a 16x16 icon, let's attempt 
 158                 // a few scales for better results 
 160                 int w 
= bitmap
.GetWidth() ; 
 161                 int h 
= bitmap
.GetHeight() ; 
 162                 int sz 
= wxMax( w 
, h 
) ; 
 163                 if ( sz 
== 24 || sz 
== 64 ) 
 165                     scaleBmp 
= wxBitmap( bitmap
.ConvertToImage().Scale( w 
* 2 , h 
* 2 ) ) ; 
 166                     bmp 
= scaleBmp
.GetBitmapData() ; 
 170             info
->contentType 
= kControlContentIconRef 
; 
 171             info
->u
.iconRef 
= bmp
->GetIconRef() ; 
 172             AcquireIconRef( info
->u
.iconRef 
) ; 
 174         else if ( forceType 
== kControlContentCGImageRef 
) 
 176             info
->contentType 
= kControlContentCGImageRef 
; 
 177             info
->u
.imageRef 
= (CGImageRef
) bmap
->CreateCGImage() ; 
 182             info
->contentType 
= kControlContentPictHandle 
; 
 183             info
->u
.picture 
= bmap
->GetPictHandle() ; 
 189 CGImageRef 
wxMacCreateCGImageFromBitmap( const wxBitmap
& bitmap 
) 
 191     wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 194     return (CGImageRef
) bmap
->CreateCGImage(); 
 197 void wxMacReleaseBitmapButton( ControlButtonContentInfo
*info 
) 
 199     if ( info
->contentType 
== kControlContentIconRef 
) 
 201         ReleaseIconRef( info
->u
.iconRef 
) ; 
 203     else if ( info
->contentType 
== kControlNoContent 
) 
 205         // there's no bitmap at all, fall through silently 
 207     else if ( info
->contentType 
== kControlContentPictHandle 
) 
 209         // owned by the bitmap, no release here 
 211     else if ( info
->contentType 
== kControlContentCGImageRef 
) 
 213         CGImageRelease( info
->u
.imageRef 
) ; 
 217         wxFAIL_MSG(wxT("Unexpected bitmap type") ) ; 
 221 #endif //wxUSE_BMPBUTTON 
 223 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData) 
 225 void wxBitmapRefData::Init() 
 232     m_bitmapMask 
= NULL 
; 
 233     m_cgImageRef 
= NULL 
; 
 236     m_pictHandle 
= NULL 
; 
 239     m_rawAccessCount 
= 0 ; 
 243 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData 
&tocopy
) 
 246     Create(tocopy
.m_width
, tocopy
.m_height
, tocopy
.m_depth
); 
 248     if (tocopy
.m_bitmapMask
) 
 249         m_bitmapMask 
= new wxMask(*tocopy
.m_bitmapMask
); 
 250     else if (tocopy
.m_hasAlpha
) 
 253     unsigned char* dest 
= (unsigned char*)GetRawAccess(); 
 254     unsigned char* source 
= (unsigned char*)tocopy
.GetRawAccess(); 
 255     size_t numbytes 
= m_bytesPerRow 
* m_height
; 
 256     memcpy( dest
, source
, numbytes 
); 
 259 wxBitmapRefData::wxBitmapRefData() 
 264 wxBitmapRefData::wxBitmapRefData( int w 
, int h 
, int d 
) 
 267     Create( w 
, h 
, d 
) ; 
 270 bool wxBitmapRefData::Create( int w 
, int h 
, int d 
) 
 272     m_width 
= wxMax(1, w
); 
 273     m_height 
= wxMax(1, h
); 
 277     m_bytesPerRow 
= GetBestBytesPerRow( w 
* 4 ) ; 
 278     size_t size 
= m_bytesPerRow 
* h 
; 
 279     void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 282         memset( data 
, 0 , size 
) ; 
 283         m_memBuf
.UngetWriteBuf( size 
) ; 
 285         m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 286         wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 287         CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 288         CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 290     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 295 void wxBitmapRefData::UseAlpha( bool use 
) 
 297     if ( m_hasAlpha 
== use 
) 
 302     CGContextRelease( m_hBitmap 
); 
 303     m_hBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), m_hasAlpha 
? kCGImageAlphaPremultipliedFirst 
: kCGImageAlphaNoneSkipFirst 
); 
 304     wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 305     CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 306     CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 309 void *wxBitmapRefData::GetRawAccess() const 
 311     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
 312     return m_memBuf
.GetData() ; 
 315 void *wxBitmapRefData::BeginRawAccess() 
 317     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ) ; 
 318     wxASSERT( m_rawAccessCount 
== 0 ) ; 
 319     wxASSERT_MSG( m_pictHandle 
== NULL 
&& m_iconRef 
== NULL 
, 
 320         wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; 
 324     // we must destroy an existing cached image, as 
 325     // the bitmap data may change now 
 328         CGImageRelease( m_cgImageRef 
) ; 
 329         m_cgImageRef 
= NULL 
; 
 332     return m_memBuf
.GetData() ; 
 335 void wxBitmapRefData::EndRawAccess() 
 337     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
 338     wxASSERT( m_rawAccessCount 
== 1 ) ; 
 343 bool wxBitmapRefData::HasNativeSize() 
 346     int h 
= GetHeight() ; 
 347     int sz 
= wxMax( w 
, h 
) ; 
 349     return ( sz 
== 128 || sz 
== 48 || sz 
== 32 || sz 
== 16 ); 
 352 IconRef 
wxBitmapRefData::GetIconRef() 
 354     if ( m_iconRef 
== NULL 
) 
 356         // Create Icon Family Handle 
 358         IconFamilyHandle iconFamily 
= (IconFamilyHandle
) NewHandle( 0 ); 
 361         int h 
= GetHeight() ; 
 362         int sz 
= wxMax( w 
, h 
) ; 
 364         OSType dataType 
= 0 ; 
 365         OSType maskType 
= 0 ; 
 370 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 371                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 373                     dataType 
= kIconServices128PixelDataARGB 
; 
 378                     dataType 
= kThumbnail32BitData 
; 
 379                     maskType 
= kThumbnail8BitMask 
; 
 384 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 385                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 387                     dataType 
= kIconServices48PixelDataARGB 
; 
 392                     dataType 
= kHuge32BitData 
; 
 393                     maskType 
= kHuge8BitMask 
; 
 398 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 399                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 401                     dataType 
= kIconServices32PixelDataARGB 
; 
 406                     dataType 
= kLarge32BitData 
; 
 407                     maskType 
= kLarge8BitMask 
; 
 412 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 413                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 415                     dataType 
= kIconServices16PixelDataARGB 
; 
 420                     dataType 
= kSmall32BitData 
; 
 421                     maskType 
= kSmall8BitMask 
; 
 431 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 432             if (  maskType 
== 0 && UMAGetSystemVersion() >= 0x1050 ) 
 434                 size_t datasize 
= sz 
* sz 
* 4 ; 
 435                 Handle data 
= NewHandle( datasize 
) ; 
 437                 unsigned char* ptr 
= (unsigned char*) *data 
; 
 438                 memset( ptr
, 0, datasize 
); 
 439                 bool hasAlpha 
= HasAlpha() ; 
 440                 wxMask 
*mask 
= m_bitmapMask 
; 
 441                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 442                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 444                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 446                     unsigned char * source 
= sourcePtr
; 
 447                     unsigned char * masksource 
= masksourcePtr
; 
 448                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 449                     unsigned char a
, r
, g
, b
; 
 451                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 460                             a 
= 0xFF - *masksource
++ ; 
 462                         else if ( !hasAlpha 
) 
 466 #if wxMAC_USE_PREMULTIPLIED_ALPHA 
 467                             // this must be non-premultiplied data 
 468                             if ( a 
!= 0xFF && a
!= 0 ) 
 484                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
); 
 485                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding bitmap") ); 
 486                 DisposeHandle( data 
); 
 491                 // setup the header properly 
 494                 Handle maskdata 
= NULL 
; 
 495                 unsigned char * maskptr 
= NULL 
; 
 496                 unsigned char * ptr 
= NULL 
; 
 497                 size_t datasize
, masksize 
; 
 499                 datasize 
= sz 
* sz 
* 4 ; 
 500                 data 
= NewHandle( datasize 
) ; 
 502                 ptr 
= (unsigned char*) *data 
; 
 503                 memset( ptr 
, 0, datasize 
) ; 
 506                 maskdata 
= NewHandle( masksize 
) ; 
 508                 maskptr 
= (unsigned char*) *maskdata 
; 
 509                 memset( maskptr 
, 0 , masksize 
) ; 
 511                 bool hasAlpha 
= HasAlpha() ; 
 512                 wxMask 
*mask 
= m_bitmapMask 
; 
 513                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 514                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 516                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 518                     unsigned char * source 
= sourcePtr
; 
 519                     unsigned char * masksource 
= masksourcePtr
; 
 520                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 521                     unsigned char * maskdest 
= maskptr 
+ y 
* sz 
; 
 522                     unsigned char a
, r
, g
, b
; 
 524                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 537                             *maskdest
++ = 0xFF - *masksource
++ ; 
 545                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
) ; 
 546                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding bitmap") ) ; 
 548                 err 
= SetIconFamilyData( iconFamily
, maskType 
, maskdata 
) ; 
 549                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding mask") ) ; 
 552                 HUnlock( maskdata 
) ; 
 553                 DisposeHandle( data 
) ; 
 554                 DisposeHandle( maskdata 
) ; 
 559             PicHandle pic 
= GetPictHandle() ; 
 560             SetIconFamilyData( iconFamily
, 'PICT' , (Handle
) pic 
) ; 
 562         // transform into IconRef 
 564         // cleaner version existing from 10.3 upwards 
 565         HLock((Handle
) iconFamily
); 
 566         OSStatus err 
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &m_iconRef 
); 
 567         HUnlock((Handle
) iconFamily
); 
 568         wxASSERT_MSG( err 
== noErr 
, wxT("Error when constructing icon ref") ); 
 569         DisposeHandle( (Handle
) iconFamily 
) ; 
 575 PicHandle 
wxBitmapRefData::GetPictHandle() 
 577     if ( m_pictHandle 
== NULL 
) 
 580         GraphicsExportComponent exporter 
= 0; 
 581         OSStatus err 
= OpenADefaultComponent(GraphicsExporterComponentType
, kQTFileTypePicture
, &exporter
); 
 584             m_pictHandle 
= (PicHandle
) NewHandle(0); 
 587                 // QT does not correctly export the mask 
 588                 // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands 
 589                 CGImageRef imageRef 
= CreateCGImage(); 
 590                 err 
= GraphicsExportSetInputCGImage( exporter
, imageRef 
); 
 591                 err 
= GraphicsExportSetOutputHandle(exporter
, (Handle
)m_pictHandle
); 
 592                 err 
= GraphicsExportDoExport(exporter
, NULL
); 
 593                 CGImageRelease( imageRef 
); 
 595                                 size_t handleSize 
= GetHandleSize( (Handle
) m_pictHandle 
); 
 596                                 // the 512 bytes header is only needed for pict files, but not in memory 
 597                                 if ( handleSize 
>= 512 ) 
 599                                         memmove( *m_pictHandle 
, (char*)(*m_pictHandle
)+512, handleSize 
- 512 ); 
 600                                         SetHandleSize( (Handle
) m_pictHandle
, handleSize 
- 512 ); 
 603             CloseComponent( exporter 
); 
 608     return m_pictHandle 
; 
 611 CGImageRef 
wxBitmapRefData::CreateCGImage() const 
 614     wxASSERT( m_rawAccessCount 
>= 0 ) ; 
 616     if ( m_rawAccessCount 
> 0 || m_cgImageRef 
== NULL 
) 
 618         if ( m_depth 
!= 1 && m_bitmapMask 
== NULL 
) 
 622                 CGImageRef tempImage 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 623                 CGImageRef tempMask 
= CGBitmapContextCreateImage((CGContextRef
) m_bitmapMask
->GetHBITMAP() ); 
 624                 image 
= CGImageCreateWithMask( tempImage
, tempMask 
); 
 625                 CGImageRelease(tempMask
); 
 626                 CGImageRelease(tempImage
); 
 629                 image 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 633             size_t imageSize 
= m_height 
* m_bytesPerRow 
; 
 634             void * dataBuffer 
= m_memBuf
.GetData() ; 
 637             CGImageAlphaInfo alphaInfo 
= kCGImageAlphaNoneSkipFirst 
; 
 638             wxMemoryBuffer membuf
; 
 642                 alphaInfo 
= kCGImageAlphaFirst 
; 
 643                 unsigned char *destalphastart 
= (unsigned char*) membuf
.GetWriteBuf( imageSize 
) ; 
 644                 memcpy( destalphastart 
, dataBuffer 
, imageSize 
) ; 
 645                 unsigned char *sourcemaskstart 
= (unsigned char *) m_bitmapMask
->GetRawAccess() ; 
 646                 int maskrowbytes 
= m_bitmapMask
->GetBytesPerRow() ; 
 647                 for ( int y 
= 0 ; y 
< h 
; ++y 
, destalphastart 
+= m_bytesPerRow
, sourcemaskstart 
+= maskrowbytes
) 
 649                     unsigned char *sourcemask 
= sourcemaskstart 
; 
 650                     unsigned char *destalpha 
= destalphastart 
; 
 651                     for ( int x 
= 0 ; x 
< w 
; ++x 
, sourcemask 
+= kMaskBytesPerPixel 
, destalpha 
+= 4 ) 
 653                         *destalpha 
= 0xFF - *sourcemask 
; 
 656                 membuf
.UngetWriteBuf( imageSize 
); 
 662 #if wxMAC_USE_PREMULTIPLIED_ALPHA 
 663                     alphaInfo 
= kCGImageAlphaPremultipliedFirst 
; 
 665                     alphaInfo 
= kCGImageAlphaFirst 
; 
 672             CGDataProviderRef dataProvider 
= NULL 
; 
 675                 // TODO CHECK ALIGNMENT 
 676                 wxMemoryBuffer maskBuf
; 
 677                 unsigned char * maskBufData 
= (unsigned char*) maskBuf
.GetWriteBuf( m_width 
* m_height 
); 
 678                 unsigned char * bufData 
= (unsigned char *) membuf
.GetData() ; 
 679                 // copy one color component 
 681                 for( int y 
= 0 ; y 
< m_height 
; bufData
+= m_bytesPerRow
, ++y 
) 
 683                     unsigned char *bufDataIter 
= bufData
+3; 
 684                     for ( int x 
= 0 ; x 
< m_width 
; bufDataIter 
+= 4, ++x
, ++i 
) 
 686                         maskBufData
[i
] = *bufDataIter
; 
 689                 maskBuf
.UngetWriteBuf( m_width 
* m_height 
); 
 692                     wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf 
); 
 694                 image 
= ::CGImageMaskCreate( w
, h
, 8, 8, m_width 
, dataProvider
, NULL
, false ); 
 698                 CGColorSpaceRef colorSpace 
= wxMacGetGenericRGBColorSpace(); 
 699                 dataProvider 
= wxMacCGDataProviderCreateWithMemoryBuffer( membuf 
); 
 702                                     w
, h
, 8 , 32 , m_bytesPerRow 
, colorSpace
, alphaInfo 
, 
 703                                     dataProvider
, NULL 
, false , kCGRenderingIntentDefault 
); 
 705             CGDataProviderRelease( dataProvider
); 
 710         image 
= m_cgImageRef 
; 
 711         CGImageRetain( image 
) ; 
 714     if ( m_rawAccessCount 
== 0 && m_cgImageRef 
== NULL
) 
 716         // we keep it for later use 
 717         m_cgImageRef 
= image 
; 
 718         CGImageRetain( image 
) ; 
 724 CGContextRef 
wxBitmapRefData::GetBitmapContext() const 
 729 void wxBitmapRefData::Free() 
 731     wxASSERT_MSG( m_rawAccessCount 
== 0 , wxT("Bitmap still selected when destroyed") ) ; 
 735         CGImageRelease( m_cgImageRef 
) ; 
 736         m_cgImageRef 
= NULL 
; 
 741         ReleaseIconRef( m_iconRef 
) ; 
 748         KillPicture( m_pictHandle 
) ; 
 749         m_pictHandle 
= NULL 
; 
 755         CGContextRelease(m_hBitmap
); 
 766 wxBitmapRefData::~wxBitmapRefData() 
 771 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 773     bool created 
= false ; 
 774     int w 
= icon
.GetWidth() ; 
 775     int h 
= icon
.GetHeight() ; 
 777     Create( icon
.GetWidth() , icon
.GetHeight() ) ; 
 779     if ( w 
== h 
&& ( w 
== 16 || w 
== 32 || w 
== 48 || w 
== 128 ) ) 
 781         IconFamilyHandle iconFamily 
= NULL 
; 
 782         Handle imagehandle 
= NewHandle( 0 ) ; 
 783         Handle maskhandle 
= NewHandle( 0 ) ; 
 787         IconSelectorValue selector 
= 0 ; 
 792                 dataType 
= kThumbnail32BitData 
; 
 793                 maskType 
= kThumbnail8BitMask 
; 
 794                 selector 
= kSelectorAllAvailableData 
; 
 798                 dataType 
= kHuge32BitData 
; 
 799                 maskType 
= kHuge8BitMask 
; 
 800                 selector 
= kSelectorHuge32Bit 
| kSelectorHuge8BitMask 
; 
 804                 dataType 
= kLarge32BitData 
; 
 805                 maskType 
= kLarge8BitMask 
; 
 806                 selector 
= kSelectorLarge32Bit 
| kSelectorLarge8BitMask 
; 
 810                 dataType 
= kSmall32BitData 
; 
 811                 maskType 
= kSmall8BitMask 
; 
 812                 selector 
= kSelectorSmall32Bit 
| kSelectorSmall8BitMask 
; 
 819         OSStatus err 
= IconRefToIconFamily( MAC_WXHICON(icon
.GetHICON()) , selector 
, &iconFamily 
) ; 
 821         err 
= GetIconFamilyData( iconFamily 
, dataType 
, imagehandle 
) ; 
 822         err 
= GetIconFamilyData( iconFamily 
, maskType 
, maskhandle 
) ; 
 823         size_t imagehandlesize 
= GetHandleSize( imagehandle 
) ; 
 824         size_t maskhandlesize 
= GetHandleSize( maskhandle 
) ; 
 826         if ( imagehandlesize 
!= 0 && maskhandlesize 
!= 0 ) 
 828             wxASSERT( GetHandleSize( imagehandle 
) == w 
* 4 * h 
) ; 
 829             wxASSERT( GetHandleSize( maskhandle 
) == w 
* h 
) ; 
 833             unsigned char *source 
= (unsigned char *) *imagehandle 
; 
 834             unsigned char *sourcemask 
= (unsigned char *) *maskhandle 
; 
 835             unsigned char* destination 
= (unsigned char*) BeginRawAccess() ; 
 837             for ( int y 
= 0 ; y 
< h 
; ++y 
) 
 839                 for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 841                     unsigned char a 
= *sourcemask
++; 
 844 #if wxMAC_USE_PREMULTIPLIED_ALPHA 
 845                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 846                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 847                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 849                     *destination
++ = *source
++ ; 
 850                     *destination
++ = *source
++ ; 
 851                     *destination
++ = *source
++ ; 
 857             DisposeHandle( imagehandle 
) ; 
 858             DisposeHandle( maskhandle 
) ; 
 862         DisposeHandle( (Handle
) iconFamily 
) ; 
 868         dc
.SelectObject( *this ) ; 
 869         dc
.DrawIcon( icon 
, 0 , 0 ) ; 
 870         dc
.SelectObject( wxNullBitmap 
) ; 
 880 wxBitmap::~wxBitmap() 
 884 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 886     wxBitmapRefData
* bitmapRefData
; 
 888     m_refData 
= bitmapRefData 
= new wxBitmapRefData( the_width 
, the_height 
, no_bits 
) ; 
 890     if (bitmapRefData
->IsOk()) 
 894             int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 895             if ( the_width 
% (sizeof(unsigned char) * 8) ) 
 896                 linesize 
+= sizeof(unsigned char); 
 898             unsigned char* linestart 
= (unsigned char*) bits 
; 
 899             unsigned char* destptr 
= (unsigned char*) BeginRawAccess() ; 
 901             for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize
, destptr 
+= M_BITMAPDATA
->GetBytesPerRow() ) 
 903                 unsigned char* destination 
= destptr
; 
 904                 int index
, bit
, mask
; 
 906                 for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 912                     if ( linestart
[index
] & mask 
) 
 914                         *destination
++ = 0xFF ; 
 921                         *destination
++ = 0xFF ; 
 922                         *destination
++ = 0xFF ; 
 923                         *destination
++ = 0xFF ; 
 924                         *destination
++ = 0xFF ; 
 933             wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 935     } /* bitmapRefData->IsOk() */ 
 938 wxBitmap::wxBitmap(int w
, int h
, int d
) 
 940     (void)Create(w
, h
, d
); 
 943 wxBitmap::wxBitmap(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
 945     (void) Create(data
, type
, width
, height
, depth
); 
 948 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
) 
 950     LoadFile(filename
, type
); 
 953 wxGDIRefData
* wxBitmap::CreateGDIRefData() const 
 955     return new wxBitmapRefData
; 
 958 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
 960     return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData 
*, data
)); 
 963 void * wxBitmap::GetRawAccess() const 
 965     wxCHECK_MSG( Ok() , NULL 
, wxT("invalid bitmap") ) ; 
 967     return M_BITMAPDATA
->GetRawAccess() ; 
 970 void * wxBitmap::BeginRawAccess() 
 972     wxCHECK_MSG( Ok() , NULL 
, wxT("invalid bitmap") ) ; 
 974     return M_BITMAPDATA
->BeginRawAccess() ; 
 977 void wxBitmap::EndRawAccess() 
 979     wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ; 
 981     M_BITMAPDATA
->EndRawAccess() ; 
 984 CGImageRef 
wxBitmap::CreateCGImage() const 
 986     wxCHECK_MSG( Ok(), NULL 
, wxT("invalid bitmap") ) ; 
 988     return M_BITMAPDATA
->CreateCGImage() ; 
 991 IconRef 
wxBitmap::GetIconRef() const 
 993     wxCHECK_MSG( Ok(), NULL 
, wxT("invalid bitmap") ) ; 
 995     return M_BITMAPDATA
->GetIconRef() ; 
 998 IconRef 
wxBitmap::CreateIconRef() const 
1000     IconRef icon 
= GetIconRef(); 
1001     verify_noerr( AcquireIconRef(icon
) ); 
1005 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
1007     wxCHECK_MSG( Ok() && 
1008                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
1009                 (rect
.x
+rect
.width 
<= GetWidth()) && 
1010                 (rect
.y
+rect
.height 
<= GetHeight()), 
1011                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
1013     wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
1014     wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
1016     int destwidth 
= rect
.width 
; 
1017     int destheight 
= rect
.height 
; 
1020         unsigned char *sourcedata 
= (unsigned char*) GetRawAccess() ; 
1021         unsigned char *destdata 
= (unsigned char*) ret
.BeginRawAccess() ; 
1022         wxASSERT( (sourcedata 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1024         int sourcelinesize 
= GetBitmapData()->GetBytesPerRow() ; 
1025         int destlinesize 
= ret
.GetBitmapData()->GetBytesPerRow() ; 
1026         unsigned char *source 
= sourcedata 
+ rect
.x 
* 4 + rect
.y 
* sourcelinesize 
; 
1027         unsigned char *dest 
= destdata 
; 
1029         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1031             memcpy( dest 
, source 
, destlinesize 
) ; 
1035     ret
.EndRawAccess() ; 
1037     if ( M_BITMAPDATA
->m_bitmapMask 
) 
1039         wxMemoryBuffer maskbuf 
; 
1040         int rowBytes 
= GetBestBytesPerRow( destwidth 
* kMaskBytesPerPixel 
); 
1041         size_t maskbufsize 
= rowBytes 
* destheight 
; 
1043         int sourcelinesize 
= M_BITMAPDATA
->m_bitmapMask
->GetBytesPerRow() ; 
1044         int destlinesize 
= rowBytes 
; 
1046         unsigned char *source 
= (unsigned char *) M_BITMAPDATA
->m_bitmapMask
->GetRawAccess() ; 
1047         unsigned char *destdata 
= (unsigned char * ) maskbuf
.GetWriteBuf( maskbufsize 
) ; 
1048         wxASSERT( (source 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1050         source 
+= rect
.x 
* kMaskBytesPerPixel 
+ rect
.y 
* sourcelinesize 
; 
1051         unsigned char *dest 
= destdata 
; 
1053         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1055             memcpy( dest 
, source 
, destlinesize 
) ; 
1058         maskbuf
.UngetWriteBuf( maskbufsize 
) ; 
1059         ret
.SetMask( new wxMask( maskbuf 
, destwidth 
, destheight 
, rowBytes 
) ) ; 
1061     else if ( HasAlpha() ) 
1067 bool wxBitmap::Create(int w
, int h
, int d
) 
1072         d 
= wxDisplayDepth() ; 
1074     m_refData 
= new wxBitmapRefData( w 
, h 
, d 
); 
1076     return M_BITMAPDATA
->IsOk() ; 
1079 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
1083     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1087         m_refData 
= new wxBitmapRefData
; 
1089         return handler
->LoadFile(this, filename
, type
, -1, -1); 
1094         wxImage 
loadimage(filename
, type
); 
1104     wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1109 bool wxBitmap::Create(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1113     m_refData 
= new wxBitmapRefData
; 
1115     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1117     if ( handler 
== NULL 
) 
1119         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1124     return handler
->Create(this, data
, type
, width
, height
, depth
); 
1129 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
1131     wxCHECK_RET( image
.Ok(), wxT("invalid image") ); 
1133     // width and height of the device-dependent bitmap 
1134     int width 
= image
.GetWidth(); 
1135     int height 
= image
.GetHeight(); 
1137     wxBitmapRefData
* bitmapRefData
; 
1139     m_refData 
= bitmapRefData 
= new wxBitmapRefData( width 
, height 
, depth 
) ; 
1141     if ( bitmapRefData
->IsOk()) 
1145         bool hasAlpha 
= false ; 
1147         if ( image
.HasMask() ) 
1149             // takes precedence, don't mix with alpha info 
1153             hasAlpha 
= image
.HasAlpha() ; 
1159         unsigned char* destinationstart 
= (unsigned char*) BeginRawAccess() ; 
1160         register unsigned char* data 
= image
.GetData(); 
1161         if ( destinationstart 
!= NULL 
&& data 
!= NULL 
) 
1163             const unsigned char *alpha 
= hasAlpha 
? image
.GetAlpha() : NULL 
; 
1164             for (int y 
= 0; y 
< height
; destinationstart 
+= M_BITMAPDATA
->GetBytesPerRow(), y
++) 
1166                 unsigned char * destination 
= destinationstart
; 
1167                 for (int x 
= 0; x 
< width
; x
++) 
1171                         const unsigned char a 
= *alpha
++; 
1172                         *destination
++ = a 
; 
1174     #if wxMAC_USE_PREMULTIPLIED_ALPHA 
1175                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1176                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1177                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1179                         *destination
++ = *data
++ ; 
1180                         *destination
++ = *data
++ ; 
1181                         *destination
++ = *data
++ ; 
1186                         *destination
++ = 0xFF ; 
1187                         *destination
++ = *data
++ ; 
1188                         *destination
++ = *data
++ ; 
1189                         *destination
++ = *data
++ ; 
1196         if ( image
.HasMask() ) 
1197             SetMask( new wxMask( *this , wxColour( image
.GetMaskRed() , image
.GetMaskGreen() , image
.GetMaskBlue() ) ) ) ; 
1198     } /* bitmapRefData->IsOk() */ 
1201 wxImage 
wxBitmap::ConvertToImage() const 
1205     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
1207     // create an wxImage object 
1208     int width 
= GetWidth(); 
1209     int height 
= GetHeight(); 
1210     image
.Create( width
, height 
); 
1212     unsigned char *data 
= image
.GetData(); 
1213     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
1215     unsigned char* sourcestart 
= (unsigned char*) GetRawAccess() ; 
1217     bool hasAlpha 
= false ; 
1218     bool hasMask 
= false ; 
1219     int maskBytesPerRow 
= 0 ; 
1220     unsigned char *alpha 
= NULL 
; 
1221     unsigned char *mask 
= NULL 
; 
1229         mask 
= (unsigned char*) GetMask()->GetRawAccess() ; 
1230         maskBytesPerRow 
= GetMask()->GetBytesPerRow() ; 
1236         alpha 
= image
.GetAlpha() ; 
1241     // The following masking algorithm is the same as well in msw/gtk: 
1242     // the colour used as transparent one in wxImage and the one it is 
1243     // replaced with when it actually occurs in the bitmap 
1244     static const int MASK_RED 
= 1; 
1245     static const int MASK_GREEN 
= 2; 
1246     static const int MASK_BLUE 
= 3; 
1247     static const int MASK_BLUE_REPLACEMENT 
= 2; 
1249     for (int yy 
= 0; yy 
< height
; yy
++ , sourcestart 
+= M_BITMAPDATA
->GetBytesPerRow() , mask 
+= maskBytesPerRow 
) 
1251         unsigned char * maskp 
= mask 
; 
1252         unsigned char * source 
= sourcestart
; 
1253         unsigned char a
, r
, g
, b
; 
1256         for (int xx 
= 0; xx 
< width
; xx
++) 
1258             color 
= *((long*) source
) ; 
1259 #ifdef WORDS_BIGENDIAN 
1260             a 
= ((color
&0xFF000000) >> 24) ; 
1261             r 
= ((color
&0x00FF0000) >> 16) ; 
1262             g 
= ((color
&0x0000FF00) >> 8) ; 
1263             b 
= (color
&0x000000FF); 
1265             b 
= ((color
&0xFF000000) >> 24) ; 
1266             g 
= ((color
&0x00FF0000) >> 16) ; 
1267             r 
= ((color
&0x0000FF00) >> 8) ; 
1268             a 
= (color
&0x000000FF); 
1272                 if ( *maskp
++ == 0xFF ) 
1278                 else if ( r 
== MASK_RED 
&& g 
== MASK_GREEN 
&& b 
== MASK_BLUE 
) 
1279                     b 
= MASK_BLUE_REPLACEMENT 
; 
1281             else if ( hasAlpha 
) 
1284 #if wxMAC_USE_PREMULTIPLIED_ALPHA 
1285                 // this must be non-premultiplied data 
1286                 if ( a 
!= 0xFF && a
!= 0 ) 
1296             data
[index 
+ 1] = g 
; 
1297             data
[index 
+ 2] = b 
; 
1305         image
.SetMaskColour( MASK_RED
, MASK_GREEN
, MASK_BLUE 
); 
1310 #endif //wxUSE_IMAGE 
1312 bool wxBitmap::SaveFile( const wxString
& filename
, 
1313     wxBitmapType type
, const wxPalette 
*palette 
) const 
1315     bool success 
= false; 
1316     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1320         success 
= handler
->SaveFile(this, filename
, type
, palette
); 
1325         wxImage image 
= ConvertToImage(); 
1326         success 
= image
.SaveFile(filename
, type
); 
1328         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1335 int wxBitmap::GetHeight() const 
1337    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1339    return M_BITMAPDATA
->GetHeight(); 
1342 int wxBitmap::GetWidth() const 
1344    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1346    return M_BITMAPDATA
->GetWidth() ; 
1349 int wxBitmap::GetDepth() const 
1351    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1353    return M_BITMAPDATA
->GetDepth(); 
1356 wxMask 
*wxBitmap::GetMask() const 
1358    wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
1360    return M_BITMAPDATA
->m_bitmapMask
; 
1363 bool wxBitmap::HasAlpha() const 
1365    wxCHECK_MSG( Ok(), false , wxT("invalid bitmap") ); 
1367    return M_BITMAPDATA
->HasAlpha() ; 
1370 void wxBitmap::SetWidth(int w
) 
1373     M_BITMAPDATA
->SetWidth(w
); 
1376 void wxBitmap::SetHeight(int h
) 
1379     M_BITMAPDATA
->SetHeight(h
); 
1382 void wxBitmap::SetDepth(int d
) 
1385     M_BITMAPDATA
->SetDepth(d
); 
1388 void wxBitmap::SetOk(bool isOk
) 
1391     M_BITMAPDATA
->SetOk(isOk
); 
1395 wxPalette 
*wxBitmap::GetPalette() const 
1397    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
1399    return &M_BITMAPDATA
->m_bitmapPalette
; 
1402 void wxBitmap::SetPalette(const wxPalette
& palette
) 
1405     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
1407 #endif // wxUSE_PALETTE 
1409 void wxBitmap::SetMask(wxMask 
*mask
) 
1412     // Remove existing mask if there is one. 
1413     delete M_BITMAPDATA
->m_bitmapMask
; 
1415     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
1418 WXHBITMAP 
wxBitmap::GetHBITMAP(WXHBITMAP
* mask
) const 
1422     return WXHBITMAP(M_BITMAPDATA
->GetBitmapContext()); 
1425 // ---------------------------------------------------------------------------- 
1427 // ---------------------------------------------------------------------------- 
1434 wxMask::wxMask(const wxMask 
&tocopy
) 
1438     m_bytesPerRow 
= tocopy
.m_bytesPerRow
; 
1439     m_width 
= tocopy
.m_width
; 
1440     m_height 
= tocopy
.m_height
; 
1442     size_t size 
= m_bytesPerRow 
* m_height
; 
1443     unsigned char* dest 
= (unsigned char*)m_memBuf
.GetWriteBuf( size 
); 
1444     unsigned char* source 
= (unsigned char*)tocopy
.m_memBuf
.GetData(); 
1445     memcpy( dest
, source
, size 
); 
1446     m_memBuf
.UngetWriteBuf( size 
) ; 
1450 // Construct a mask from a bitmap and a colour indicating 
1451 // the transparent area 
1452 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
1455     Create( bitmap
, colour 
); 
1458 // Construct a mask from a mono bitmap (copies the bitmap). 
1459 wxMask::wxMask( const wxBitmap
& bitmap 
) 
1465 // Construct a mask from a mono bitmap (copies the bitmap). 
1467 wxMask::wxMask( const wxMemoryBuffer
& data
, int width 
, int height 
, int bytesPerRow 
) 
1470     Create( data
, width 
, height 
, bytesPerRow 
); 
1477         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1478         m_maskBitmap 
= NULL 
; 
1484     m_width 
= m_height 
= m_bytesPerRow 
= 0 ; 
1485     m_maskBitmap 
= NULL 
; 
1488 void *wxMask::GetRawAccess() const 
1490     return m_memBuf
.GetData() ; 
1493 // The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed 
1494 // bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well 
1496 void wxMask::RealizeNative() 
1500         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1501        m_maskBitmap 
= NULL 
; 
1504     CGColorSpaceRef colorspace 
= CGColorSpaceCreateDeviceGray(); 
1505     // from MouseTracking sample : 
1506     // Ironically, due to a bug in CGImageCreateWithMask, you cannot use 
1507     // CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) at this point! 
1509     m_maskBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, colorspace
, 
1510         kCGImageAlphaNone 
); 
1511     CGColorSpaceRelease( colorspace 
); 
1512     wxASSERT_MSG( m_maskBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
1515 // Create a mask from a mono bitmap (copies the bitmap). 
1517 bool wxMask::Create(const wxMemoryBuffer
& data
,int width 
, int height 
, int bytesPerRow
) 
1522     m_bytesPerRow 
= bytesPerRow 
; 
1524     wxASSERT( data
.GetDataLen() == (size_t)(height 
* bytesPerRow
) ) ; 
1531 // Create a mask from a mono bitmap (copies the bitmap). 
1532 bool wxMask::Create(const wxBitmap
& bitmap
) 
1534     m_width 
= bitmap
.GetWidth() ; 
1535     m_height 
= bitmap
.GetHeight() ; 
1536     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1538     size_t size 
= m_bytesPerRow 
* m_height 
; 
1539     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1540     wxASSERT( destdatabase 
!= NULL 
) ; 
1542     memset( destdatabase 
, 0 , size 
) ; 
1543     unsigned char * srcdata 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1545     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, destdatabase 
+= m_bytesPerRow 
) 
1547         unsigned char *destdata 
= destdatabase 
; 
1548         unsigned char r
, g
, b
; 
1550         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1557             if ( ( r 
+ g 
+ b 
) > 0x10 ) 
1558                 *destdata
++ = 0xFF ; 
1560                 *destdata
++ = 0x00 ; 
1564     m_memBuf
.UngetWriteBuf( size 
) ; 
1570 // Create a mask from a bitmap and a colour indicating 
1571 // the transparent area 
1572 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1574     m_width 
= bitmap
.GetWidth() ; 
1575     m_height 
= bitmap
.GetHeight() ; 
1576     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1578     size_t size 
= m_bytesPerRow 
* m_height 
; 
1579     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1580     wxASSERT( destdatabase 
!= NULL 
) ; 
1582     memset( destdatabase 
, 0 , size 
) ; 
1583     unsigned char * srcdatabase 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1584     size_t sourceBytesRow 
= bitmap
.GetBitmapData()->GetBytesPerRow(); 
1586     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, srcdatabase
+= sourceBytesRow
, destdatabase 
+= m_bytesPerRow
) 
1588         unsigned char *srcdata 
= srcdatabase 
; 
1589         unsigned char *destdata 
= destdatabase 
; 
1590         unsigned char r
, g
, b
; 
1592         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1599             if ( colour 
== wxColour( r 
, g 
, b 
) ) 
1600                 *destdata
++ = 0xFF ; 
1602                 *destdata
++ = 0x00 ; 
1606     m_memBuf
.UngetWriteBuf( size 
) ; 
1612 WXHBITMAP 
wxMask::GetHBITMAP() const 
1614     return m_maskBitmap 
; 
1617 // ---------------------------------------------------------------------------- 
1619 // ---------------------------------------------------------------------------- 
1621 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
, wxBitmapHandlerBase
) 
1623 // ---------------------------------------------------------------------------- 
1624 // Standard Handlers 
1625 // ---------------------------------------------------------------------------- 
1629 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1631     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1634     inline wxPICTResourceHandler() 
1636         SetName(wxT("Macintosh Pict resource")); 
1637         SetExtension(wxEmptyString
); 
1638         SetType(wxBITMAP_TYPE_PICT_RESOURCE
); 
1641     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1642           int desiredWidth
, int desiredHeight
); 
1645 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1648 bool wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1649                                      const wxString
& name
, 
1650                                      long WXUNUSED(flags
), 
1651                                      int WXUNUSED(desiredWidth
), 
1652                                      int WXUNUSED(desiredHeight
)) 
1656     wxMacStringToPascal( name 
, theName 
) ; 
1658     PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1663         mf
.SetPICT( thePict 
) ; 
1664         bitmap
->Create( mf
.GetWidth() , mf
.GetHeight() ) ; 
1666         dc
.SelectObject( *bitmap 
) ; 
1668         dc
.SelectObject( wxNullBitmap 
) ; 
1678 void wxBitmap::InitStandardHandlers() 
1681     AddHandler( new wxPICTResourceHandler 
) ; 
1683     AddHandler( new wxICONResourceHandler 
) ; 
1686 // ---------------------------------------------------------------------------- 
1687 // raw bitmap access support 
1688 // ---------------------------------------------------------------------------- 
1690 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int WXUNUSED(bpp
)) 
1693         // no bitmap, no data (raw or otherwise) 
1696     data
.m_width 
= GetWidth() ; 
1697     data
.m_height 
= GetHeight() ; 
1698     data
.m_stride 
= GetBitmapData()->GetBytesPerRow() ; 
1700     return BeginRawAccess() ; 
1703 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(dataBase
)) 
1708 void wxBitmap::UseAlpha() 
1710     // remember that we are using alpha channel: 
1711     // we'll need to create a proper mask in UngetRawData() 
1712     M_BITMAPDATA
->UseAlpha( true );