1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/osx/core/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
) 
  32 #include "wx/osx/uma.h" 
  34 #include "wx/osx/private.h" 
  37 #ifndef __WXOSX_IPHONE__ 
  38 #include <QuickTime/QuickTime.h> 
  41 CGColorSpaceRef 
wxMacGetGenericRGBColorSpace(); 
  42 CGDataProviderRef 
wxMacCGDataProviderCreateWithMemoryBuffer( const wxMemoryBuffer
& buf 
); 
  44 // Implementation Notes 
  45 // -------------------- 
  47 // we are always working with a 32 bit deep pixel buffer 
  48 // under QuickDraw its alpha parts are going to be ignored in the GWorld, 
  49 // therefore we have a separate GWorld there for blitting the mask in 
  51 // under Quartz then content is transformed into a CGImageRef representing the same data 
  52 // which can be transferred to the GPU by the OS for fast rendering 
  54 class WXDLLEXPORT wxBitmapRefData
: public wxGDIRefData
 
  56     friend class WXDLLIMPEXP_FWD_CORE wxIcon
; 
  57     friend class WXDLLIMPEXP_FWD_CORE wxCursor
; 
  59     wxBitmapRefData(int width 
, int height 
, int depth
); 
  60     wxBitmapRefData(CGImageRef image
); 
  62     wxBitmapRefData(const wxBitmapRefData 
&tocopy
); 
  64     virtual ~wxBitmapRefData(); 
  66     virtual bool IsOk() const { return m_ok
; } 
  69     void SetOk( bool isOk
) { m_ok 
= isOk
; } 
  71     void SetWidth( int width 
) { m_width 
= width
; } 
  72     void SetHeight( int height 
) { m_height 
= height
; } 
  73     void SetDepth( int depth 
) { m_depth 
= depth
; } 
  75     int GetWidth() const { return m_width
; } 
  76     int GetHeight() const { return m_height
; } 
  77     int GetDepth() const { return m_depth
; } 
  79     void *GetRawAccess() const; 
  80     void *BeginRawAccess(); 
  83     bool HasAlpha() const { return m_hasAlpha
; } 
  84     void UseAlpha( bool useAlpha 
); 
  88     wxPalette     m_bitmapPalette
; 
  89 #endif // wxUSE_PALETTE 
  91     wxMask 
*      m_bitmapMask
; // Optional mask 
  92     CGImageRef    
CreateCGImage() const; 
  94     // returns true if the bitmap has a size that 
  95     // can be natively transferred into a true icon 
  96     // if no is returned GetIconRef will still produce 
  97     // an icon but it will be generated via a PICT and 
  98     // rescaled to 16 x 16 
 101     // caller should increase ref count if needed longer 
 102     // than the bitmap exists 
 103     IconRef       
GetIconRef(); 
 105 #ifndef __WXOSX_IPHONE__ 
 106     // returns a Pict from the bitmap content 
 107     PicHandle     
GetPictHandle(); 
 110     CGContextRef  
GetBitmapContext() const; 
 112     int           GetBytesPerRow() const { return m_bytesPerRow
; } 
 114     bool Create(int width 
, int height 
, int depth
); 
 115     bool Create( CGImageRef image 
); 
 123     wxMemoryBuffer m_memBuf
; 
 124     int           m_rawAccessCount
; 
 126     mutable CGImageRef    m_cgImageRef
; 
 129 #ifndef __WXOSX_IPHONE__ 
 130     PicHandle     m_pictHandle
; 
 132     CGContextRef  m_hBitmap
; 
 136 #define wxOSX_USE_PREMULTIPLIED_ALPHA 1 
 137 static const int kBestByteAlignement 
= 16; 
 138 static const int kMaskBytesPerPixel 
= 1; 
 140 static int GetBestBytesPerRow( int rawBytes 
) 
 142     return (((rawBytes
)+kBestByteAlignement
-1) & ~(kBestByteAlignement
-1) ); 
 145 #if wxUSE_GUI && !defined(__WXOSX_IPHONE__) 
 147 // this is used for more controls than just the wxBitmap button, also for notebooks etc 
 149 void wxMacCreateBitmapButton( ControlButtonContentInfo
*info 
, const wxBitmap
& bitmap 
, int forceType 
) 
 151     memset( info 
, 0 , sizeof(ControlButtonContentInfo
) ) ; 
 154         wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 158         if ( forceType 
== 0  ) 
 160             forceType 
= kControlContentCGImageRef
; 
 163         if ( forceType 
== kControlContentIconRef 
) 
 166             wxBitmapRefData
* bmp 
= bmap 
; 
 168             if ( !bmap
->HasNativeSize() ) 
 170                 // as PICT conversion will only result in a 16x16 icon, let's attempt 
 171                 // a few scales for better results 
 173                 int w 
= bitmap
.GetWidth() ; 
 174                 int h 
= bitmap
.GetHeight() ; 
 175                 int sz 
= wxMax( w 
, h 
) ; 
 176                 if ( sz 
== 24 || sz 
== 64 ) 
 178                     scaleBmp 
= wxBitmap( bitmap
.ConvertToImage().Scale( w 
* 2 , h 
* 2 ) ) ; 
 179                     bmp 
= scaleBmp
.GetBitmapData() ; 
 183             info
->contentType 
= kControlContentIconRef 
; 
 184             info
->u
.iconRef 
= bmp
->GetIconRef() ; 
 185             AcquireIconRef( info
->u
.iconRef 
) ; 
 187         else if ( forceType 
== kControlContentCGImageRef 
) 
 189             info
->contentType 
= kControlContentCGImageRef 
; 
 190             info
->u
.imageRef 
= (CGImageRef
) bmap
->CreateCGImage() ; 
 195             info
->contentType 
= kControlContentPictHandle 
; 
 196             info
->u
.picture 
= bmap
->GetPictHandle() ; 
 202 CGImageRef 
wxMacCreateCGImageFromBitmap( const wxBitmap
& bitmap 
) 
 204     wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 207     return (CGImageRef
) bmap
->CreateCGImage(); 
 210 void wxMacReleaseBitmapButton( ControlButtonContentInfo
*info 
) 
 212     if ( info
->contentType 
== kControlContentIconRef 
) 
 214         ReleaseIconRef( info
->u
.iconRef 
) ; 
 216     else if ( info
->contentType 
== kControlNoContent 
) 
 218         // there's no bitmap at all, fall through silently 
 220     else if ( info
->contentType 
== kControlContentPictHandle 
) 
 222         // owned by the bitmap, no release here 
 224     else if ( info
->contentType 
== kControlContentCGImageRef 
) 
 226         CGImageRelease( info
->u
.imageRef 
) ; 
 230         wxFAIL_MSG(wxT("Unexpected bitmap type") ) ; 
 234 #endif //wxUSE_BMPBUTTON 
 236 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData) 
 238 void wxBitmapRefData::Init() 
 245     m_bitmapMask 
= NULL 
; 
 246     m_cgImageRef 
= NULL 
; 
 248 #ifndef __WXOSX_IPHONE__ 
 250     m_pictHandle 
= NULL 
; 
 254     m_rawAccessCount 
= 0 ; 
 258 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData 
&tocopy
) 
 261     Create(tocopy
.m_width
, tocopy
.m_height
, tocopy
.m_depth
); 
 263     if (tocopy
.m_bitmapMask
) 
 264         m_bitmapMask 
= new wxMask(*tocopy
.m_bitmapMask
); 
 265     else if (tocopy
.m_hasAlpha
) 
 268     unsigned char* dest 
= (unsigned char*)GetRawAccess(); 
 269     unsigned char* source 
= (unsigned char*)tocopy
.GetRawAccess(); 
 270     size_t numbytes 
= m_bytesPerRow 
* m_height
; 
 271     memcpy( dest
, source
, numbytes 
); 
 274 wxBitmapRefData::wxBitmapRefData() 
 279 wxBitmapRefData::wxBitmapRefData( int w 
, int h 
, int d 
) 
 282     Create( w 
, h 
, d 
) ; 
 285 wxBitmapRefData::wxBitmapRefData(CGImageRef image
) 
 290 // code from Technical Q&A QA1509 
 292 bool wxBitmapRefData::Create(CGImageRef image
) 
 294     m_width 
= CGImageGetWidth(image
); 
 295     m_height 
= CGImageGetHeight(image
); 
 299     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 300     size_t size 
= m_bytesPerRow 
* m_height 
; 
 301     void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 304         memset( data 
, 0 , size 
) ; 
 305         m_memBuf
.UngetWriteBuf( size 
) ; 
 306         CGImageAlphaInfo alpha 
= CGImageGetAlphaInfo(image
); 
 307         if ( alpha 
== kCGImageAlphaNone 
|| alpha 
== kCGImageAlphaNoneSkipLast 
|| alpha 
== kCGImageAlphaNoneSkipLast 
) 
 309             m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 314             m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst 
); 
 316         CGRect rect 
= {{0,0},{m_width
,m_height
}};  
 317         CGContextDrawImage(m_hBitmap
, rect
, image
); 
 319         wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 320         CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 321         CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 323     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 329 bool wxBitmapRefData::Create( int w 
, int h 
, int d 
) 
 331     m_width 
= wxMax(1, w
); 
 332     m_height 
= wxMax(1, h
); 
 336     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 337     size_t size 
= m_bytesPerRow 
* m_height 
; 
 338     void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 341         memset( data 
, 0 , size 
) ; 
 342         m_memBuf
.UngetWriteBuf( size 
) ; 
 344         m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 345         wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 346         CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 347         CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 349     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 354 void wxBitmapRefData::UseAlpha( bool use 
) 
 356     if ( m_hasAlpha 
== use 
) 
 361     CGContextRelease( m_hBitmap 
); 
 362     m_hBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), m_hasAlpha 
? kCGImageAlphaPremultipliedFirst 
: kCGImageAlphaNoneSkipFirst 
); 
 363     wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 364     CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 365     CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 368 void *wxBitmapRefData::GetRawAccess() const 
 370     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
 371     return m_memBuf
.GetData() ; 
 374 void *wxBitmapRefData::BeginRawAccess() 
 376     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ) ; 
 377     wxASSERT( m_rawAccessCount 
== 0 ) ; 
 378 #ifndef __WXOSX_IPHONE__ 
 379     wxASSERT_MSG( m_pictHandle 
== NULL 
&& m_iconRef 
== NULL 
, 
 380         wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; 
 384     // we must destroy an existing cached image, as 
 385     // the bitmap data may change now 
 388         CGImageRelease( m_cgImageRef 
) ; 
 389         m_cgImageRef 
= NULL 
; 
 392     return m_memBuf
.GetData() ; 
 395 void wxBitmapRefData::EndRawAccess() 
 397     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
 398     wxASSERT( m_rawAccessCount 
== 1 ) ; 
 403 bool wxBitmapRefData::HasNativeSize() 
 406     int h 
= GetHeight() ; 
 407     int sz 
= wxMax( w 
, h 
) ; 
 409     return ( sz 
== 128 || sz 
== 48 || sz 
== 32 || sz 
== 16 ); 
 412 #ifndef __WXOSX_IPHONE__ 
 413 IconRef 
wxBitmapRefData::GetIconRef() 
 415     if ( m_iconRef 
== NULL 
) 
 417         // Create Icon Family Handle 
 419         IconFamilyHandle iconFamily 
= (IconFamilyHandle
) NewHandle( 0 ); 
 422         int h 
= GetHeight() ; 
 423         int sz 
= wxMax( w 
, h 
) ; 
 425         OSType dataType 
= 0 ; 
 426         OSType maskType 
= 0 ; 
 431 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 432                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 434                     dataType 
= kIconServices128PixelDataARGB 
; 
 439                     dataType 
= kThumbnail32BitData 
; 
 440                     maskType 
= kThumbnail8BitMask 
; 
 445 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 446                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 448                     dataType 
= kIconServices48PixelDataARGB 
; 
 453                     dataType 
= kHuge32BitData 
; 
 454                     maskType 
= kHuge8BitMask 
; 
 459 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 460                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 462                     dataType 
= kIconServices32PixelDataARGB 
; 
 467                     dataType 
= kLarge32BitData 
; 
 468                     maskType 
= kLarge8BitMask 
; 
 473 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 474                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 476                     dataType 
= kIconServices16PixelDataARGB 
; 
 481                     dataType 
= kSmall32BitData 
; 
 482                     maskType 
= kSmall8BitMask 
; 
 492 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 493             if (  maskType 
== 0 && UMAGetSystemVersion() >= 0x1050 ) 
 495                 size_t datasize 
= sz 
* sz 
* 4 ; 
 496                 Handle data 
= NewHandle( datasize 
) ; 
 498                 unsigned char* ptr 
= (unsigned char*) *data 
; 
 499                 memset( ptr
, 0, datasize 
); 
 500                 bool hasAlpha 
= HasAlpha() ; 
 501                 wxMask 
*mask 
= m_bitmapMask 
; 
 502                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 503                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 505                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 507                     unsigned char * source 
= sourcePtr
; 
 508                     unsigned char * masksource 
= masksourcePtr
; 
 509                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 510                     unsigned char a
, r
, g
, b
; 
 512                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 521                             a 
= 0xFF - *masksource
++ ; 
 523                         else if ( !hasAlpha 
) 
 527 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 528                             // this must be non-premultiplied data 
 529                             if ( a 
!= 0xFF && a
!= 0 ) 
 546                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
); 
 549                     wxFAIL_MSG("Error when adding bitmap"); 
 552                 DisposeHandle( data 
); 
 557                 // setup the header properly 
 560                 Handle maskdata 
= NULL 
; 
 561                 unsigned char * maskptr 
= NULL 
; 
 562                 unsigned char * ptr 
= NULL 
; 
 563                 size_t datasize
, masksize 
; 
 565                 datasize 
= sz 
* sz 
* 4 ; 
 566                 data 
= NewHandle( datasize 
) ; 
 568                 ptr 
= (unsigned char*) *data 
; 
 569                 memset( ptr 
, 0, datasize 
) ; 
 572                 maskdata 
= NewHandle( masksize 
) ; 
 574                 maskptr 
= (unsigned char*) *maskdata 
; 
 575                 memset( maskptr 
, 0 , masksize 
) ; 
 577                 bool hasAlpha 
= HasAlpha() ; 
 578                 wxMask 
*mask 
= m_bitmapMask 
; 
 579                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 580                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 582                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 584                     unsigned char * source 
= sourcePtr
; 
 585                     unsigned char * masksource 
= masksourcePtr
; 
 586                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 587                     unsigned char * maskdest 
= maskptr 
+ y 
* sz 
; 
 588                     unsigned char a
, r
, g
, b
; 
 590                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 603                             *maskdest
++ = 0xFF - *masksource
++ ; 
 611                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
) ; 
 612                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding bitmap") ) ; 
 614                 err 
= SetIconFamilyData( iconFamily
, maskType 
, maskdata 
) ; 
 615                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding mask") ) ; 
 618                 HUnlock( maskdata 
) ; 
 619                 DisposeHandle( data 
) ; 
 620                 DisposeHandle( maskdata 
) ; 
 625             PicHandle pic 
= GetPictHandle() ; 
 626             SetIconFamilyData( iconFamily
, 'PICT' , (Handle
) pic 
) ; 
 628         // transform into IconRef 
 630         // cleaner version existing from 10.3 upwards 
 631         HLock((Handle
) iconFamily
); 
 632         OSStatus err 
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &m_iconRef 
); 
 633         HUnlock((Handle
) iconFamily
); 
 634         DisposeHandle( (Handle
) iconFamily 
) ; 
 636         wxCHECK_MSG( err 
== noErr
, NULL
, wxT("Error when constructing icon ref") ); 
 642 PicHandle 
wxBitmapRefData::GetPictHandle() 
 644     if ( m_pictHandle 
== NULL 
) 
 647         GraphicsExportComponent exporter 
= 0; 
 648         OSStatus err 
= OpenADefaultComponent(GraphicsExporterComponentType
, kQTFileTypePicture
, &exporter
); 
 651             m_pictHandle 
= (PicHandle
) NewHandle(0); 
 654                 // QT does not correctly export the mask 
 655                 // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands 
 656                 CGImageRef imageRef 
= CreateCGImage(); 
 657                 err 
= GraphicsExportSetInputCGImage( exporter
, imageRef 
); 
 658                 err 
= GraphicsExportSetOutputHandle(exporter
, (Handle
)m_pictHandle
); 
 659                 err 
= GraphicsExportDoExport(exporter
, NULL
); 
 660                 CGImageRelease( imageRef 
); 
 662                 size_t handleSize 
= GetHandleSize( (Handle
) m_pictHandle 
); 
 663                 // the 512 bytes header is only needed for pict files, but not in memory 
 664                 if ( handleSize 
>= 512 ) 
 666                     memmove( *m_pictHandle 
, (char*)(*m_pictHandle
)+512, handleSize 
- 512 ); 
 667                     SetHandleSize( (Handle
) m_pictHandle
, handleSize 
- 512 ); 
 670             CloseComponent( exporter 
); 
 675     return m_pictHandle 
; 
 679 CGImageRef 
wxBitmapRefData::CreateCGImage() const 
 682     wxASSERT( m_rawAccessCount 
>= 0 ) ; 
 684     if ( m_rawAccessCount 
> 0 || m_cgImageRef 
== NULL 
) 
 686         if ( m_depth 
!= 1 && m_bitmapMask 
== NULL 
) 
 689             // in order for this code to work properly, wxMask would have to invert black and white 
 690             // in the native bitmap 
 693                 CGImageRef tempImage 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 694                 CGImageRef tempMask 
= CGBitmapContextCreateImage((CGContextRef
) m_bitmapMask
->GetHBITMAP() ); 
 695                 image 
= CGImageCreateWithMask( tempImage
, tempMask 
); 
 696                 CGImageRelease(tempMask
); 
 697                 CGImageRelease(tempImage
); 
 701                 image 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 705             size_t imageSize 
= m_height 
* m_bytesPerRow 
; 
 706             void * dataBuffer 
= m_memBuf
.GetData() ; 
 709             CGImageAlphaInfo alphaInfo 
= kCGImageAlphaNoneSkipFirst 
; 
 710             wxMemoryBuffer membuf
; 
 714                 alphaInfo 
= kCGImageAlphaFirst 
; 
 715                 unsigned char *destalphastart 
= (unsigned char*) membuf
.GetWriteBuf( imageSize 
) ; 
 716                 memcpy( destalphastart 
, dataBuffer 
, imageSize 
) ; 
 717                 unsigned char *sourcemaskstart 
= (unsigned char *) m_bitmapMask
->GetRawAccess() ; 
 718                 int maskrowbytes 
= m_bitmapMask
->GetBytesPerRow() ; 
 719                 for ( int y 
= 0 ; y 
< h 
; ++y 
, destalphastart 
+= m_bytesPerRow
, sourcemaskstart 
+= maskrowbytes
) 
 721                     unsigned char *sourcemask 
= sourcemaskstart 
; 
 722                     unsigned char *destalpha 
= destalphastart 
; 
 723                     for ( int x 
= 0 ; x 
< w 
; ++x 
, sourcemask 
+= kMaskBytesPerPixel 
, destalpha 
+= 4 ) 
 725                         *destalpha 
= 0xFF - *sourcemask 
; 
 728                 membuf
.UngetWriteBuf( imageSize 
); 
 734 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 735                     alphaInfo 
= kCGImageAlphaPremultipliedFirst 
; 
 737                     alphaInfo 
= kCGImageAlphaFirst 
; 
 744             CGDataProviderRef dataProvider 
= NULL 
; 
 747                 // TODO CHECK ALIGNMENT 
 748                 wxMemoryBuffer maskBuf
; 
 749                 unsigned char * maskBufData 
= (unsigned char*) maskBuf
.GetWriteBuf( m_width 
* m_height 
); 
 750                 unsigned char * bufData 
= (unsigned char *) membuf
.GetData() ; 
 751                 // copy one color component 
 753                 for( int y 
= 0 ; y 
< m_height 
; bufData
+= m_bytesPerRow
, ++y 
) 
 755                     unsigned char *bufDataIter 
= bufData
+3; 
 756                     for ( int x 
= 0 ; x 
< m_width 
; bufDataIter 
+= 4, ++x
, ++i 
) 
 758                         maskBufData
[i
] = *bufDataIter
; 
 761                 maskBuf
.UngetWriteBuf( m_width 
* m_height 
); 
 764                     wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf 
); 
 766                 image 
= ::CGImageMaskCreate( w
, h
, 8, 8, m_width 
, dataProvider
, NULL
, false ); 
 770                 CGColorSpaceRef colorSpace 
= wxMacGetGenericRGBColorSpace(); 
 771                 dataProvider 
= wxMacCGDataProviderCreateWithMemoryBuffer( membuf 
); 
 774                                     w
, h
, 8 , 32 , m_bytesPerRow 
, colorSpace
, alphaInfo 
, 
 775                                     dataProvider
, NULL 
, false , kCGRenderingIntentDefault 
); 
 777             CGDataProviderRelease( dataProvider
); 
 782         image 
= m_cgImageRef 
; 
 783         CGImageRetain( image 
) ; 
 786     if ( m_rawAccessCount 
== 0 && m_cgImageRef 
== NULL
) 
 788         // we keep it for later use 
 789         m_cgImageRef 
= image 
; 
 790         CGImageRetain( image 
) ; 
 796 CGContextRef 
wxBitmapRefData::GetBitmapContext() const 
 801 void wxBitmapRefData::Free() 
 803     wxASSERT_MSG( m_rawAccessCount 
== 0 , wxT("Bitmap still selected when destroyed") ) ; 
 807         CGImageRelease( m_cgImageRef 
) ; 
 808         m_cgImageRef 
= NULL 
; 
 810 #ifndef __WXOSX_IPHONE__ 
 813         ReleaseIconRef( m_iconRef 
) ; 
 820         KillPicture( m_pictHandle 
) ; 
 821         m_pictHandle 
= NULL 
; 
 827         CGContextRelease(m_hBitmap
); 
 831     wxDELETE(m_bitmapMask
); 
 834 wxBitmapRefData::~wxBitmapRefData() 
 841 // ---------------------------------------------------------------------------- 
 843 // ---------------------------------------------------------------------------- 
 845 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 847     bool created 
= false ; 
 848     int w 
= icon
.GetWidth() ; 
 849     int h 
= icon
.GetHeight() ; 
 852 #ifdef __WXOSX_CARBON__ 
 853     if ( w 
== h 
&& ( w 
== 16 || w 
== 32 || w 
== 48 || w 
== 128 ) ) 
 855         IconFamilyHandle iconFamily 
= NULL 
; 
 856         Handle imagehandle 
= NewHandle( 0 ) ; 
 857         Handle maskhandle 
= NewHandle( 0 ) ; 
 861         IconSelectorValue selector 
= 0 ; 
 866                 dataType 
= kThumbnail32BitData 
; 
 867                 maskType 
= kThumbnail8BitMask 
; 
 868                 selector 
= kSelectorAllAvailableData 
; 
 872                 dataType 
= kHuge32BitData 
; 
 873                 maskType 
= kHuge8BitMask 
; 
 874                 selector 
= kSelectorHuge32Bit 
| kSelectorHuge8BitMask 
; 
 878                 dataType 
= kLarge32BitData 
; 
 879                 maskType 
= kLarge8BitMask 
; 
 880                 selector 
= kSelectorLarge32Bit 
| kSelectorLarge8BitMask 
; 
 884                 dataType 
= kSmall32BitData 
; 
 885                 maskType 
= kSmall8BitMask 
; 
 886                 selector 
= kSelectorSmall32Bit 
| kSelectorSmall8BitMask 
; 
 893         OSStatus err 
= IconRefToIconFamily( MAC_WXHICON(icon
.GetHICON()) , selector 
, &iconFamily 
) ; 
 895         err 
= GetIconFamilyData( iconFamily 
, dataType 
, imagehandle 
) ; 
 896         err 
= GetIconFamilyData( iconFamily 
, maskType 
, maskhandle 
) ; 
 897         size_t imagehandlesize 
= GetHandleSize( imagehandle 
) ; 
 898         size_t maskhandlesize 
= GetHandleSize( maskhandle 
) ; 
 900         if ( imagehandlesize 
!= 0 && maskhandlesize 
!= 0 ) 
 902             wxASSERT( GetHandleSize( imagehandle 
) == w 
* 4 * h 
) ; 
 903             wxASSERT( GetHandleSize( maskhandle 
) == w 
* h 
) ; 
 907             unsigned char *source 
= (unsigned char *) *imagehandle 
; 
 908             unsigned char *sourcemask 
= (unsigned char *) *maskhandle 
; 
 909             unsigned char* destination 
= (unsigned char*) BeginRawAccess() ; 
 911             for ( int y 
= 0 ; y 
< h 
; ++y 
) 
 913                 for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 915                     unsigned char a 
= *sourcemask
++; 
 918 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 919                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 920                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 921                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 923                     *destination
++ = *source
++ ; 
 924                     *destination
++ = *source
++ ; 
 925                     *destination
++ = *source
++ ; 
 931             DisposeHandle( imagehandle 
) ; 
 932             DisposeHandle( maskhandle 
) ; 
 936         DisposeHandle( (Handle
) iconFamily 
) ; 
 942         dc
.SelectObject( *this ) ; 
 943         dc
.DrawIcon( icon 
, 0 , 0 ) ; 
 944         dc
.SelectObject( wxNullBitmap 
) ; 
 950 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 952     wxBitmapRefData
* bitmapRefData
; 
 954     m_refData 
= bitmapRefData 
= new wxBitmapRefData( the_width 
, the_height 
, no_bits 
) ; 
 956     if (bitmapRefData
->IsOk()) 
 960             int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 961             if ( the_width 
% (sizeof(unsigned char) * 8) ) 
 962                 linesize 
+= sizeof(unsigned char); 
 964             unsigned char* linestart 
= (unsigned char*) bits 
; 
 965             unsigned char* destptr 
= (unsigned char*) BeginRawAccess() ; 
 967             for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize
, destptr 
+= M_BITMAPDATA
->GetBytesPerRow() ) 
 969                 unsigned char* destination 
= destptr
; 
 970                 int index
, bit
, mask
; 
 972                 for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 978                     if ( linestart
[index
] & mask 
) 
 980                         *destination
++ = 0xFF ; 
 987                         *destination
++ = 0xFF ; 
 988                         *destination
++ = 0xFF ; 
 989                         *destination
++ = 0xFF ; 
 990                         *destination
++ = 0xFF ; 
 999             wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
1001     } /* bitmapRefData->IsOk() */ 
1004 wxBitmap::wxBitmap(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1006     (void) Create(data
, type
, width
, height
, depth
); 
1009 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
) 
1011     LoadFile(filename
, type
); 
1014 wxBitmap::wxBitmap(CGImageRef image
) 
1016     (void) Create(image
); 
1019 wxGDIRefData
* wxBitmap::CreateGDIRefData() const 
1021     return new wxBitmapRefData
; 
1024 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
1026     return new wxBitmapRefData(*static_cast<const wxBitmapRefData 
*>(data
)); 
1029 void * wxBitmap::GetRawAccess() const 
1031     wxCHECK_MSG( Ok() , NULL 
, wxT("invalid bitmap") ) ; 
1033     return M_BITMAPDATA
->GetRawAccess() ; 
1036 void * wxBitmap::BeginRawAccess() 
1038     wxCHECK_MSG( Ok() , NULL 
, wxT("invalid bitmap") ) ; 
1040     return M_BITMAPDATA
->BeginRawAccess() ; 
1043 void wxBitmap::EndRawAccess() 
1045     wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ; 
1047     M_BITMAPDATA
->EndRawAccess() ; 
1050 CGImageRef 
wxBitmap::CreateCGImage() const 
1052     wxCHECK_MSG( Ok(), NULL 
, wxT("invalid bitmap") ) ; 
1054     return M_BITMAPDATA
->CreateCGImage() ; 
1057 #ifndef  __WXOSX_IPHONE__ 
1058 IconRef 
wxBitmap::GetIconRef() const 
1060     wxCHECK_MSG( Ok(), NULL 
, wxT("invalid bitmap") ) ; 
1062     return M_BITMAPDATA
->GetIconRef() ; 
1065 IconRef 
wxBitmap::CreateIconRef() const 
1067     IconRef icon 
= GetIconRef(); 
1068     verify_noerr( AcquireIconRef(icon
) ); 
1075 WX_NSImage 
wxBitmap::GetNSImage() const 
1077     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1078     return wxOSXGetNSImageFromCGImage( cgimage 
); 
1083 #if wxOSX_USE_IPHONE 
1085 WX_UIImage 
wxBitmap::GetUIImage() const 
1087     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1088     return wxOSXGetUIImageFromCGImage( cgimage 
); 
1092 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
1094     wxCHECK_MSG( Ok() && 
1095                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
1096                 (rect
.x
+rect
.width 
<= GetWidth()) && 
1097                 (rect
.y
+rect
.height 
<= GetHeight()), 
1098                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
1100     wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
1101     wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
1103     int destwidth 
= rect
.width 
; 
1104     int destheight 
= rect
.height 
; 
1107         unsigned char *sourcedata 
= (unsigned char*) GetRawAccess() ; 
1108         unsigned char *destdata 
= (unsigned char*) ret
.BeginRawAccess() ; 
1109         wxASSERT( (sourcedata 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1111         int sourcelinesize 
= GetBitmapData()->GetBytesPerRow() ; 
1112         int destlinesize 
= ret
.GetBitmapData()->GetBytesPerRow() ; 
1113         unsigned char *source 
= sourcedata 
+ rect
.x 
* 4 + rect
.y 
* sourcelinesize 
; 
1114         unsigned char *dest 
= destdata 
; 
1116         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1118             memcpy( dest 
, source 
, destlinesize 
) ; 
1122     ret
.EndRawAccess() ; 
1124     if ( M_BITMAPDATA
->m_bitmapMask 
) 
1126         wxMemoryBuffer maskbuf 
; 
1127         int rowBytes 
= GetBestBytesPerRow( destwidth 
* kMaskBytesPerPixel 
); 
1128         size_t maskbufsize 
= rowBytes 
* destheight 
; 
1130         int sourcelinesize 
= M_BITMAPDATA
->m_bitmapMask
->GetBytesPerRow() ; 
1131         int destlinesize 
= rowBytes 
; 
1133         unsigned char *source 
= (unsigned char *) M_BITMAPDATA
->m_bitmapMask
->GetRawAccess() ; 
1134         unsigned char *destdata 
= (unsigned char * ) maskbuf
.GetWriteBuf( maskbufsize 
) ; 
1135         wxASSERT( (source 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1137         source 
+= rect
.x 
* kMaskBytesPerPixel 
+ rect
.y 
* sourcelinesize 
; 
1138         unsigned char *dest 
= destdata 
; 
1140         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1142             memcpy( dest 
, source 
, destlinesize 
) ; 
1145         maskbuf
.UngetWriteBuf( maskbufsize 
) ; 
1146         ret
.SetMask( new wxMask( maskbuf 
, destwidth 
, destheight 
, rowBytes 
) ) ; 
1148     else if ( HasAlpha() ) 
1154 bool wxBitmap::Create(int w
, int h
, int d
) 
1159         d 
= wxDisplayDepth() ; 
1161     m_refData 
= new wxBitmapRefData( w 
, h 
, d 
); 
1163     return M_BITMAPDATA
->IsOk() ; 
1167 bool wxBitmap::Create(CGImageRef image
) 
1171     m_refData 
= new wxBitmapRefData( image 
); 
1173     return M_BITMAPDATA
->IsOk() ; 
1176 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
1180     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1184         m_refData 
= new wxBitmapRefData
; 
1186         return handler
->LoadFile(this, filename
, type
, -1, -1); 
1191         wxImage 
loadimage(filename
, type
); 
1201     wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1206 bool wxBitmap::Create(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1210     m_refData 
= new wxBitmapRefData
; 
1212     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1214     if ( handler 
== NULL 
) 
1216         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1221     return handler
->Create(this, data
, type
, width
, height
, depth
); 
1226 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
1228     wxCHECK_RET( image
.Ok(), wxT("invalid image") ); 
1230     // width and height of the device-dependent bitmap 
1231     int width 
= image
.GetWidth(); 
1232     int height 
= image
.GetHeight(); 
1234     wxBitmapRefData
* bitmapRefData
; 
1236     m_refData 
= bitmapRefData 
= new wxBitmapRefData( width 
, height 
, depth 
) ; 
1238     if ( bitmapRefData
->IsOk()) 
1242         bool hasAlpha 
= false ; 
1244         if ( image
.HasMask() ) 
1246             // takes precedence, don't mix with alpha info 
1250             hasAlpha 
= image
.HasAlpha() ; 
1256         unsigned char* destinationstart 
= (unsigned char*) BeginRawAccess() ; 
1257         register unsigned char* data 
= image
.GetData(); 
1258         if ( destinationstart 
!= NULL 
&& data 
!= NULL 
) 
1260             const unsigned char *alpha 
= hasAlpha 
? image
.GetAlpha() : NULL 
; 
1261             for (int y 
= 0; y 
< height
; destinationstart 
+= M_BITMAPDATA
->GetBytesPerRow(), y
++) 
1263                 unsigned char * destination 
= destinationstart
; 
1264                 for (int x 
= 0; x 
< width
; x
++) 
1268                         const unsigned char a 
= *alpha
++; 
1269                         *destination
++ = a 
; 
1271     #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1272                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1273                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1274                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1276                         *destination
++ = *data
++ ; 
1277                         *destination
++ = *data
++ ; 
1278                         *destination
++ = *data
++ ; 
1283                         *destination
++ = 0xFF ; 
1284                         *destination
++ = *data
++ ; 
1285                         *destination
++ = *data
++ ; 
1286                         *destination
++ = *data
++ ; 
1293         if ( image
.HasMask() ) 
1294             SetMask( new wxMask( *this , wxColour( image
.GetMaskRed() , image
.GetMaskGreen() , image
.GetMaskBlue() ) ) ) ; 
1295     } /* bitmapRefData->IsOk() */ 
1298 wxImage 
wxBitmap::ConvertToImage() const 
1302     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
1304     // create an wxImage object 
1305     int width 
= GetWidth(); 
1306     int height 
= GetHeight(); 
1307     image
.Create( width
, height 
); 
1309     unsigned char *data 
= image
.GetData(); 
1310     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
1312     unsigned char* sourcestart 
= (unsigned char*) GetRawAccess() ; 
1314     bool hasAlpha 
= false ; 
1315     bool hasMask 
= false ; 
1316     int maskBytesPerRow 
= 0 ; 
1317     unsigned char *alpha 
= NULL 
; 
1318     unsigned char *mask 
= NULL 
; 
1326         mask 
= (unsigned char*) GetMask()->GetRawAccess() ; 
1327         maskBytesPerRow 
= GetMask()->GetBytesPerRow() ; 
1333         alpha 
= image
.GetAlpha() ; 
1338     // The following masking algorithm is the same as well in msw/gtk: 
1339     // the colour used as transparent one in wxImage and the one it is 
1340     // replaced with when it actually occurs in the bitmap 
1341     static const int MASK_RED 
= 1; 
1342     static const int MASK_GREEN 
= 2; 
1343     static const int MASK_BLUE 
= 3; 
1344     static const int MASK_BLUE_REPLACEMENT 
= 2; 
1346     for (int yy 
= 0; yy 
< height
; yy
++ , sourcestart 
+= M_BITMAPDATA
->GetBytesPerRow() , mask 
+= maskBytesPerRow 
) 
1348         unsigned char * maskp 
= mask 
; 
1349         unsigned char * source 
= sourcestart
; 
1350         unsigned char a
, r
, g
, b
; 
1353         for (int xx 
= 0; xx 
< width
; xx
++) 
1355             color 
= *((long*) source
) ; 
1356 #ifdef WORDS_BIGENDIAN 
1357             a 
= ((color
&0xFF000000) >> 24) ; 
1358             r 
= ((color
&0x00FF0000) >> 16) ; 
1359             g 
= ((color
&0x0000FF00) >> 8) ; 
1360             b 
= (color
&0x000000FF); 
1362             b 
= ((color
&0xFF000000) >> 24) ; 
1363             g 
= ((color
&0x00FF0000) >> 16) ; 
1364             r 
= ((color
&0x0000FF00) >> 8) ; 
1365             a 
= (color
&0x000000FF); 
1369                 if ( *maskp
++ == 0xFF ) 
1375                 else if ( r 
== MASK_RED 
&& g 
== MASK_GREEN 
&& b 
== MASK_BLUE 
) 
1376                     b 
= MASK_BLUE_REPLACEMENT 
; 
1378             else if ( hasAlpha 
) 
1381 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1382                 // this must be non-premultiplied data 
1383                 if ( a 
!= 0xFF && a
!= 0 ) 
1393             data
[index 
+ 1] = g 
; 
1394             data
[index 
+ 2] = b 
; 
1402         image
.SetMaskColour( MASK_RED
, MASK_GREEN
, MASK_BLUE 
); 
1407 #endif //wxUSE_IMAGE 
1409 bool wxBitmap::SaveFile( const wxString
& filename
, 
1410     wxBitmapType type
, const wxPalette 
*palette 
) const 
1412     bool success 
= false; 
1413     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1417         success 
= handler
->SaveFile(this, filename
, type
, palette
); 
1422         wxImage image 
= ConvertToImage(); 
1423         success 
= image
.SaveFile(filename
, type
); 
1425         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1432 int wxBitmap::GetHeight() const 
1434    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1436    return M_BITMAPDATA
->GetHeight(); 
1439 int wxBitmap::GetWidth() const 
1441    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1443    return M_BITMAPDATA
->GetWidth() ; 
1446 int wxBitmap::GetDepth() const 
1448    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
1450    return M_BITMAPDATA
->GetDepth(); 
1453 wxMask 
*wxBitmap::GetMask() const 
1455    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
1457    return M_BITMAPDATA
->m_bitmapMask
; 
1460 bool wxBitmap::HasAlpha() const 
1462    wxCHECK_MSG( Ok(), false , wxT("invalid bitmap") ); 
1464    return M_BITMAPDATA
->HasAlpha() ; 
1467 void wxBitmap::SetWidth(int w
) 
1470     M_BITMAPDATA
->SetWidth(w
); 
1473 void wxBitmap::SetHeight(int h
) 
1476     M_BITMAPDATA
->SetHeight(h
); 
1479 void wxBitmap::SetDepth(int d
) 
1482     M_BITMAPDATA
->SetDepth(d
); 
1485 void wxBitmap::SetOk(bool isOk
) 
1488     M_BITMAPDATA
->SetOk(isOk
); 
1492 wxPalette 
*wxBitmap::GetPalette() const 
1494    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
1496    return &M_BITMAPDATA
->m_bitmapPalette
; 
1499 void wxBitmap::SetPalette(const wxPalette
& palette
) 
1502     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
1504 #endif // wxUSE_PALETTE 
1506 void wxBitmap::SetMask(wxMask 
*mask
) 
1509     // Remove existing mask if there is one. 
1510     delete M_BITMAPDATA
->m_bitmapMask
; 
1512     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
1515 WXHBITMAP 
wxBitmap::GetHBITMAP(WXHBITMAP
* mask
) const 
1519     return WXHBITMAP(M_BITMAPDATA
->GetBitmapContext()); 
1522 // ---------------------------------------------------------------------------- 
1524 // ---------------------------------------------------------------------------- 
1531 wxMask::wxMask(const wxMask 
&tocopy
) 
1535     m_bytesPerRow 
= tocopy
.m_bytesPerRow
; 
1536     m_width 
= tocopy
.m_width
; 
1537     m_height 
= tocopy
.m_height
; 
1539     size_t size 
= m_bytesPerRow 
* m_height
; 
1540     unsigned char* dest 
= (unsigned char*)m_memBuf
.GetWriteBuf( size 
); 
1541     unsigned char* source 
= (unsigned char*)tocopy
.m_memBuf
.GetData(); 
1542     memcpy( dest
, source
, size 
); 
1543     m_memBuf
.UngetWriteBuf( size 
) ; 
1547 // Construct a mask from a bitmap and a colour indicating 
1548 // the transparent area 
1549 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
1552     Create( bitmap
, colour 
); 
1555 // Construct a mask from a mono bitmap (copies the bitmap). 
1556 wxMask::wxMask( const wxBitmap
& bitmap 
) 
1562 // Construct a mask from a mono bitmap (copies the bitmap). 
1564 wxMask::wxMask( const wxMemoryBuffer
& data
, int width 
, int height 
, int bytesPerRow 
) 
1567     Create( data
, width 
, height 
, bytesPerRow 
); 
1574         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1575         m_maskBitmap 
= NULL 
; 
1581     m_width 
= m_height 
= m_bytesPerRow 
= 0 ; 
1582     m_maskBitmap 
= NULL 
; 
1585 void *wxMask::GetRawAccess() const 
1587     return m_memBuf
.GetData() ; 
1590 // The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed 
1591 // bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well 
1593 void wxMask::RealizeNative() 
1597         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1598        m_maskBitmap 
= NULL 
; 
1601     CGColorSpaceRef colorspace 
= CGColorSpaceCreateDeviceGray(); 
1602     // from MouseTracking sample : 
1603     // Ironically, due to a bug in CGImageCreateWithMask, you cannot use 
1604     // CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) at this point! 
1606     m_maskBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, colorspace
, 
1607         kCGImageAlphaNone 
); 
1608     CGColorSpaceRelease( colorspace 
); 
1609     wxASSERT_MSG( m_maskBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
1612 // Create a mask from a mono bitmap (copies the bitmap). 
1614 bool wxMask::Create(const wxMemoryBuffer
& data
,int width 
, int height 
, int bytesPerRow
) 
1619     m_bytesPerRow 
= bytesPerRow 
; 
1621     wxASSERT( data
.GetDataLen() == (size_t)(height 
* bytesPerRow
) ) ; 
1628 // Create a mask from a mono bitmap (copies the bitmap). 
1629 bool wxMask::Create(const wxBitmap
& bitmap
) 
1631     m_width 
= bitmap
.GetWidth() ; 
1632     m_height 
= bitmap
.GetHeight() ; 
1633     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1635     size_t size 
= m_bytesPerRow 
* m_height 
; 
1636     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1637     wxASSERT( destdatabase 
!= NULL 
) ; 
1639     memset( destdatabase 
, 0 , size 
) ; 
1640     unsigned char * srcdata 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1642     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, destdatabase 
+= m_bytesPerRow 
) 
1644         unsigned char *destdata 
= destdatabase 
; 
1645         unsigned char r
, g
, b
; 
1647         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1654             if ( ( r 
+ g 
+ b 
) > 0x10 ) 
1655                 *destdata
++ = 0xFF ; 
1657                 *destdata
++ = 0x00 ; 
1661     m_memBuf
.UngetWriteBuf( size 
) ; 
1667 // Create a mask from a bitmap and a colour indicating 
1668 // the transparent area 
1669 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1671     m_width 
= bitmap
.GetWidth() ; 
1672     m_height 
= bitmap
.GetHeight() ; 
1673     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1675     size_t size 
= m_bytesPerRow 
* m_height 
; 
1676     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1677     wxASSERT( destdatabase 
!= NULL 
) ; 
1679     memset( destdatabase 
, 0 , size 
) ; 
1680     unsigned char * srcdatabase 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1681     size_t sourceBytesRow 
= bitmap
.GetBitmapData()->GetBytesPerRow(); 
1683     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, srcdatabase
+= sourceBytesRow
, destdatabase 
+= m_bytesPerRow
) 
1685         unsigned char *srcdata 
= srcdatabase 
; 
1686         unsigned char *destdata 
= destdatabase 
; 
1687         unsigned char r
, g
, b
; 
1689         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1696             if ( colour 
== wxColour( r 
, g 
, b 
) ) 
1697                 *destdata
++ = 0xFF ; 
1699                 *destdata
++ = 0x00 ; 
1703     m_memBuf
.UngetWriteBuf( size 
) ; 
1709 WXHBITMAP 
wxMask::GetHBITMAP() const 
1711     return m_maskBitmap 
; 
1714 // ---------------------------------------------------------------------------- 
1715 // Standard Handlers 
1716 // ---------------------------------------------------------------------------- 
1718 class WXDLLEXPORT wxBundleResourceHandler
: public wxBitmapHandler
 
1720     DECLARE_ABSTRACT_CLASS(wxPNGResourceHandler
) 
1723     inline wxBundleResourceHandler() 
1727     virtual bool LoadFile(wxBitmap 
*bitmap
, 
1728                           const wxString
& name
, 
1734 IMPLEMENT_ABSTRACT_CLASS(wxBundleResourceHandler
, wxBitmapHandler
); 
1736 class WXDLLEXPORT wxPNGResourceHandler
: public wxBundleResourceHandler
 
1738     DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler
) 
1741     inline wxPNGResourceHandler() 
1743         SetName(wxT("PNG resource")); 
1744         SetExtension("PNG"); 
1745         SetType(wxBITMAP_TYPE_PNG_RESOURCE
); 
1749 IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler
, wxBundleResourceHandler
) 
1751 class WXDLLEXPORT wxJPEGResourceHandler
: public wxBundleResourceHandler
 
1753     DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler
) 
1756     inline wxJPEGResourceHandler() 
1758         SetName(wxT("JPEG resource")); 
1759         SetExtension("JPEG"); 
1760         SetType(wxBITMAP_TYPE_JPEG_RESOURCE
); 
1764 IMPLEMENT_DYNAMIC_CLASS(wxJPEGResourceHandler
, wxBundleResourceHandler
) 
1766 bool wxBundleResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1767                                      const wxString
& name
, 
1768                                      wxBitmapType 
WXUNUSED(type
), 
1769                                      int WXUNUSED(desiredWidth
), 
1770                                      int WXUNUSED(desiredHeight
)) 
1772     wxString ext 
= GetExtension().Lower(); 
1773     wxCFStringRef 
resname(name
); 
1774     wxCFStringRef 
restype(ext
); 
1776     wxCFRef
<CFURLRef
> imageURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname
, restype
, NULL
)); 
1778     if ( imageURL
.get() != NULL 
) 
1780         // Create the data provider object 
1781         wxCFRef
<CGDataProviderRef
> provider(CGDataProviderCreateWithURL (imageURL
) ); 
1782         CGImageRef image 
= NULL
; 
1784         if ( ext 
== "jpeg" ) 
1785             image 
= CGImageCreateWithJPEGDataProvider (provider
, NULL
, true, 
1786                                                    kCGRenderingIntentDefault
); 
1787         else if ( ext 
== "png" ) 
1788             image 
= CGImageCreateWithPNGDataProvider (provider
, NULL
, true, 
1789                                                        kCGRenderingIntentDefault
); 
1790         if ( image 
!= NULL 
) 
1792             bitmap
->Create(image
); 
1793             CGImageRelease(image
); 
1800 #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) 
1802 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1804     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1807     inline wxPICTResourceHandler() 
1809         SetName(wxT("Macintosh Pict resource")); 
1810         SetExtension(wxEmptyString
); 
1811         SetType(wxBITMAP_TYPE_PICT_RESOURCE
); 
1814     virtual bool LoadFile(wxBitmap 
*bitmap
, 
1815                           const wxString
& name
, 
1821 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1824 bool wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1825                                      const wxString
& name
, 
1826                                      wxBitmapType 
WXUNUSED(type
), 
1827                                      int WXUNUSED(desiredWidth
), 
1828                                      int WXUNUSED(desiredHeight
)) 
1832     wxMacStringToPascal( name 
, theName 
) ; 
1834     PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1839         mf
.SetPICT( thePict 
) ; 
1840         bitmap
->Create( mf
.GetWidth() , mf
.GetHeight() ) ; 
1842         dc
.SelectObject( *bitmap 
) ; 
1844         dc
.SelectObject( wxNullBitmap 
) ; 
1854 void wxBitmap::InitStandardHandlers() 
1856 #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) 
1857     AddHandler( new wxPICTResourceHandler 
) ; 
1859 #if wxOSX_USE_COCOA_OR_CARBON 
1860     AddHandler( new wxICONResourceHandler 
) ; 
1862     AddHandler( new wxPNGResourceHandler 
); 
1863     AddHandler( new wxJPEGResourceHandler 
); 
1866 // ---------------------------------------------------------------------------- 
1867 // raw bitmap access support 
1868 // ---------------------------------------------------------------------------- 
1870 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int WXUNUSED(bpp
)) 
1873         // no bitmap, no data (raw or otherwise) 
1876     data
.m_width 
= GetWidth() ; 
1877     data
.m_height 
= GetHeight() ; 
1878     data
.m_stride 
= GetBitmapData()->GetBytesPerRow() ; 
1880     return BeginRawAccess() ; 
1883 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(dataBase
)) 
1888 void wxBitmap::UseAlpha() 
1890     // remember that we are using alpha channel: 
1891     // we'll need to create a proper mask in UngetRawData() 
1892     M_BITMAPDATA
->UseAlpha( true );