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
) : wxGDIRefData() 
 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
) 
 296         m_width 
= CGImageGetWidth(image
); 
 297         m_height 
= CGImageGetHeight(image
); 
 301         m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 302         size_t size 
= m_bytesPerRow 
* m_height 
; 
 303         void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 306             memset( data 
, 0 , size 
) ; 
 307             m_memBuf
.UngetWriteBuf( size 
) ; 
 308             CGImageAlphaInfo alpha 
= CGImageGetAlphaInfo(image
); 
 309             if ( alpha 
== kCGImageAlphaNone 
|| alpha 
== kCGImageAlphaNoneSkipLast 
|| alpha 
== kCGImageAlphaNoneSkipLast 
) 
 311                 m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 316                 m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst 
); 
 318             CGRect rect 
= {{0,0},{m_width
,m_height
}};  
 319             CGContextDrawImage(m_hBitmap
, rect
, image
); 
 321             wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 322             CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 323             CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 326     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 332 bool wxBitmapRefData::Create( int w 
, int h 
, int d 
) 
 334     m_width 
= wxMax(1, w
); 
 335     m_height 
= wxMax(1, h
); 
 339     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 340     size_t size 
= m_bytesPerRow 
* m_height 
; 
 341     void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 344         memset( data 
, 0 , size 
) ; 
 345         m_memBuf
.UngetWriteBuf( size 
) ; 
 347         m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 348         wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 349         CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 350         CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 352     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 357 void wxBitmapRefData::UseAlpha( bool use 
) 
 359     if ( m_hasAlpha 
== use 
) 
 364     CGContextRelease( m_hBitmap 
); 
 365     m_hBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), m_hasAlpha 
? kCGImageAlphaPremultipliedFirst 
: kCGImageAlphaNoneSkipFirst 
); 
 366     wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 367     CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 368     CGContextScaleCTM( m_hBitmap
, 1, -1 ); 
 371 void *wxBitmapRefData::GetRawAccess() const 
 373     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
 374     return m_memBuf
.GetData() ; 
 377 void *wxBitmapRefData::BeginRawAccess() 
 379     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ) ; 
 380     wxASSERT( m_rawAccessCount 
== 0 ) ; 
 381 #ifndef __WXOSX_IPHONE__ 
 382     wxASSERT_MSG( m_pictHandle 
== NULL 
&& m_iconRef 
== NULL 
, 
 383         wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; 
 387     // we must destroy an existing cached image, as 
 388     // the bitmap data may change now 
 391         CGImageRelease( m_cgImageRef 
) ; 
 392         m_cgImageRef 
= NULL 
; 
 395     return m_memBuf
.GetData() ; 
 398 void wxBitmapRefData::EndRawAccess() 
 400     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
 401     wxASSERT( m_rawAccessCount 
== 1 ) ; 
 406 bool wxBitmapRefData::HasNativeSize() 
 409     int h 
= GetHeight() ; 
 410     int sz 
= wxMax( w 
, h 
) ; 
 412     return ( sz 
== 128 || sz 
== 48 || sz 
== 32 || sz 
== 16 ); 
 415 #ifndef __WXOSX_IPHONE__ 
 416 IconRef 
wxBitmapRefData::GetIconRef() 
 418     if ( m_iconRef 
== NULL 
) 
 420         // Create Icon Family Handle 
 422         IconFamilyHandle iconFamily 
= (IconFamilyHandle
) NewHandle( 0 ); 
 425         int h 
= GetHeight() ; 
 426         int sz 
= wxMax( w 
, h 
) ; 
 428         OSType dataType 
= 0 ; 
 429         OSType maskType 
= 0 ; 
 434 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 435                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 437                     dataType 
= kIconServices128PixelDataARGB 
; 
 442                     dataType 
= kThumbnail32BitData 
; 
 443                     maskType 
= kThumbnail8BitMask 
; 
 448 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 449                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 451                     dataType 
= kIconServices48PixelDataARGB 
; 
 456                     dataType 
= kHuge32BitData 
; 
 457                     maskType 
= kHuge8BitMask 
; 
 462 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 463                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 465                     dataType 
= kIconServices32PixelDataARGB 
; 
 470                     dataType 
= kLarge32BitData 
; 
 471                     maskType 
= kLarge8BitMask 
; 
 476 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 477                 if ( UMAGetSystemVersion() >= 0x1050 ) 
 479                     dataType 
= kIconServices16PixelDataARGB 
; 
 484                     dataType 
= kSmall32BitData 
; 
 485                     maskType 
= kSmall8BitMask 
; 
 495 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
 496             if (  maskType 
== 0 && UMAGetSystemVersion() >= 0x1050 ) 
 498                 size_t datasize 
= sz 
* sz 
* 4 ; 
 499                 Handle data 
= NewHandle( datasize 
) ; 
 501                 unsigned char* ptr 
= (unsigned char*) *data 
; 
 502                 memset( ptr
, 0, datasize 
); 
 503                 bool hasAlpha 
= HasAlpha() ; 
 504                 wxMask 
*mask 
= m_bitmapMask 
; 
 505                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 506                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 508                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 510                     unsigned char * source 
= sourcePtr
; 
 511                     unsigned char * masksource 
= masksourcePtr
; 
 512                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 513                     unsigned char a
, r
, g
, b
; 
 515                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 524                             a 
= 0xFF - *masksource
++ ; 
 526                         else if ( !hasAlpha 
) 
 530 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 531                             // this must be non-premultiplied data 
 532                             if ( a 
!= 0xFF && a
!= 0 ) 
 549                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
); 
 552                     wxFAIL_MSG("Error when adding bitmap"); 
 555                 DisposeHandle( data 
); 
 560                 // setup the header properly 
 563                 Handle maskdata 
= NULL 
; 
 564                 unsigned char * maskptr 
= NULL 
; 
 565                 unsigned char * ptr 
= NULL 
; 
 566                 size_t datasize
, masksize 
; 
 568                 datasize 
= sz 
* sz 
* 4 ; 
 569                 data 
= NewHandle( datasize 
) ; 
 571                 ptr 
= (unsigned char*) *data 
; 
 572                 memset( ptr 
, 0, datasize 
) ; 
 575                 maskdata 
= NewHandle( masksize 
) ; 
 577                 maskptr 
= (unsigned char*) *maskdata 
; 
 578                 memset( maskptr 
, 0 , masksize 
) ; 
 580                 bool hasAlpha 
= HasAlpha() ; 
 581                 wxMask 
*mask 
= m_bitmapMask 
; 
 582                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 583                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 585                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 587                     unsigned char * source 
= sourcePtr
; 
 588                     unsigned char * masksource 
= masksourcePtr
; 
 589                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 590                     unsigned char * maskdest 
= maskptr 
+ y 
* sz 
; 
 591                     unsigned char a
, r
, g
, b
; 
 593                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 606                             *maskdest
++ = 0xFF - *masksource
++ ; 
 614                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
) ; 
 615                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding bitmap") ) ; 
 617                 err 
= SetIconFamilyData( iconFamily
, maskType 
, maskdata 
) ; 
 618                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding mask") ) ; 
 621                 HUnlock( maskdata 
) ; 
 622                 DisposeHandle( data 
) ; 
 623                 DisposeHandle( maskdata 
) ; 
 628             PicHandle pic 
= GetPictHandle() ; 
 629             SetIconFamilyData( iconFamily
, 'PICT' , (Handle
) pic 
) ; 
 631         // transform into IconRef 
 633         // cleaner version existing from 10.3 upwards 
 634         HLock((Handle
) iconFamily
); 
 635         OSStatus err 
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &m_iconRef 
); 
 636         HUnlock((Handle
) iconFamily
); 
 637         DisposeHandle( (Handle
) iconFamily 
) ; 
 639         wxCHECK_MSG( err 
== noErr
, NULL
, wxT("Error when constructing icon ref") ); 
 645 PicHandle 
wxBitmapRefData::GetPictHandle() 
 647     if ( m_pictHandle 
== NULL 
) 
 650         GraphicsExportComponent exporter 
= 0; 
 651         OSStatus err 
= OpenADefaultComponent(GraphicsExporterComponentType
, kQTFileTypePicture
, &exporter
); 
 654             m_pictHandle 
= (PicHandle
) NewHandle(0); 
 657                 // QT does not correctly export the mask 
 658                 // TODO if we get around to it create a synthetic PICT with the CopyBits and Mask commands 
 659                 CGImageRef imageRef 
= CreateCGImage(); 
 660                 err 
= GraphicsExportSetInputCGImage( exporter
, imageRef 
); 
 661                 err 
= GraphicsExportSetOutputHandle(exporter
, (Handle
)m_pictHandle
); 
 662                 err 
= GraphicsExportDoExport(exporter
, NULL
); 
 663                 CGImageRelease( imageRef 
); 
 665                 size_t handleSize 
= GetHandleSize( (Handle
) m_pictHandle 
); 
 666                 // the 512 bytes header is only needed for pict files, but not in memory 
 667                 if ( handleSize 
>= 512 ) 
 669                     memmove( *m_pictHandle 
, (char*)(*m_pictHandle
)+512, handleSize 
- 512 ); 
 670                     SetHandleSize( (Handle
) m_pictHandle
, handleSize 
- 512 ); 
 673             CloseComponent( exporter 
); 
 678     return m_pictHandle 
; 
 682 CGImageRef 
wxBitmapRefData::CreateCGImage() const 
 685     wxASSERT( m_rawAccessCount 
>= 0 ) ; 
 687     if ( m_rawAccessCount 
> 0 || m_cgImageRef 
== NULL 
) 
 689         if ( m_depth 
!= 1 && m_bitmapMask 
== NULL 
) 
 692             // in order for this code to work properly, wxMask would have to invert black and white 
 693             // in the native bitmap 
 696                 CGImageRef tempImage 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 697                 CGImageRef tempMask 
= CGBitmapContextCreateImage((CGContextRef
) m_bitmapMask
->GetHBITMAP() ); 
 698                 image 
= CGImageCreateWithMask( tempImage
, tempMask 
); 
 699                 CGImageRelease(tempMask
); 
 700                 CGImageRelease(tempImage
); 
 704                 image 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 708             size_t imageSize 
= m_height 
* m_bytesPerRow 
; 
 709             void * dataBuffer 
= m_memBuf
.GetData() ; 
 712             CGImageAlphaInfo alphaInfo 
= kCGImageAlphaNoneSkipFirst 
; 
 713             wxMemoryBuffer membuf
; 
 717                 alphaInfo 
= kCGImageAlphaFirst 
; 
 718                 unsigned char *destalphastart 
= (unsigned char*) membuf
.GetWriteBuf( imageSize 
) ; 
 719                 memcpy( destalphastart 
, dataBuffer 
, imageSize 
) ; 
 720                 unsigned char *sourcemaskstart 
= (unsigned char *) m_bitmapMask
->GetRawAccess() ; 
 721                 int maskrowbytes 
= m_bitmapMask
->GetBytesPerRow() ; 
 722                 for ( int y 
= 0 ; y 
< h 
; ++y 
, destalphastart 
+= m_bytesPerRow
, sourcemaskstart 
+= maskrowbytes
) 
 724                     unsigned char *sourcemask 
= sourcemaskstart 
; 
 725                     unsigned char *destalpha 
= destalphastart 
; 
 726                     for ( int x 
= 0 ; x 
< w 
; ++x 
, sourcemask 
+= kMaskBytesPerPixel 
, destalpha 
+= 4 ) 
 728                         *destalpha 
= 0xFF - *sourcemask 
; 
 731                 membuf
.UngetWriteBuf( imageSize 
); 
 737 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 738                     alphaInfo 
= kCGImageAlphaPremultipliedFirst 
; 
 740                     alphaInfo 
= kCGImageAlphaFirst 
; 
 747             CGDataProviderRef dataProvider 
= NULL 
; 
 750                 // TODO CHECK ALIGNMENT 
 751                 wxMemoryBuffer maskBuf
; 
 752                 unsigned char * maskBufData 
= (unsigned char*) maskBuf
.GetWriteBuf( m_width 
* m_height 
); 
 753                 unsigned char * bufData 
= (unsigned char *) membuf
.GetData() ; 
 754                 // copy one color component 
 756                 for( int y 
= 0 ; y 
< m_height 
; bufData
+= m_bytesPerRow
, ++y 
) 
 758                     unsigned char *bufDataIter 
= bufData
+3; 
 759                     for ( int x 
= 0 ; x 
< m_width 
; bufDataIter 
+= 4, ++x
, ++i 
) 
 761                         maskBufData
[i
] = *bufDataIter
; 
 764                 maskBuf
.UngetWriteBuf( m_width 
* m_height 
); 
 767                     wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf 
); 
 769                 image 
= ::CGImageMaskCreate( w
, h
, 8, 8, m_width 
, dataProvider
, NULL
, false ); 
 773                 CGColorSpaceRef colorSpace 
= wxMacGetGenericRGBColorSpace(); 
 774                 dataProvider 
= wxMacCGDataProviderCreateWithMemoryBuffer( membuf 
); 
 777                                     w
, h
, 8 , 32 , m_bytesPerRow 
, colorSpace
, alphaInfo 
, 
 778                                     dataProvider
, NULL 
, false , kCGRenderingIntentDefault 
); 
 780             CGDataProviderRelease( dataProvider
); 
 785         image 
= m_cgImageRef 
; 
 786         CGImageRetain( image 
) ; 
 789     if ( m_rawAccessCount 
== 0 && m_cgImageRef 
== NULL
) 
 791         // we keep it for later use 
 792         m_cgImageRef 
= image 
; 
 793         CGImageRetain( image 
) ; 
 799 CGContextRef 
wxBitmapRefData::GetBitmapContext() const 
 804 void wxBitmapRefData::Free() 
 806     wxASSERT_MSG( m_rawAccessCount 
== 0 , wxT("Bitmap still selected when destroyed") ) ; 
 810         CGImageRelease( m_cgImageRef 
) ; 
 811         m_cgImageRef 
= NULL 
; 
 813 #ifndef __WXOSX_IPHONE__ 
 816         ReleaseIconRef( m_iconRef 
) ; 
 823         KillPicture( m_pictHandle 
) ; 
 824         m_pictHandle 
= NULL 
; 
 830         CGContextRelease(m_hBitmap
); 
 834     wxDELETE(m_bitmapMask
); 
 837 wxBitmapRefData::~wxBitmapRefData() 
 844 // ---------------------------------------------------------------------------- 
 846 // ---------------------------------------------------------------------------- 
 848 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 850     bool created 
= false ; 
 851     int w 
= icon
.GetWidth() ; 
 852     int h 
= icon
.GetHeight() ; 
 855 #ifdef __WXOSX_CARBON__ 
 856     if ( w 
== h 
&& ( w 
== 16 || w 
== 32 || w 
== 48 || w 
== 128 ) ) 
 858         IconFamilyHandle iconFamily 
= NULL 
; 
 859         Handle imagehandle 
= NewHandle( 0 ) ; 
 860         Handle maskhandle 
= NewHandle( 0 ) ; 
 864         IconSelectorValue selector 
= 0 ; 
 869                 dataType 
= kThumbnail32BitData 
; 
 870                 maskType 
= kThumbnail8BitMask 
; 
 871                 selector 
= kSelectorAllAvailableData 
; 
 875                 dataType 
= kHuge32BitData 
; 
 876                 maskType 
= kHuge8BitMask 
; 
 877                 selector 
= kSelectorHuge32Bit 
| kSelectorHuge8BitMask 
; 
 881                 dataType 
= kLarge32BitData 
; 
 882                 maskType 
= kLarge8BitMask 
; 
 883                 selector 
= kSelectorLarge32Bit 
| kSelectorLarge8BitMask 
; 
 887                 dataType 
= kSmall32BitData 
; 
 888                 maskType 
= kSmall8BitMask 
; 
 889                 selector 
= kSelectorSmall32Bit 
| kSelectorSmall8BitMask 
; 
 896         OSStatus err 
= IconRefToIconFamily( MAC_WXHICON(icon
.GetHICON()) , selector 
, &iconFamily 
) ; 
 898         err 
= GetIconFamilyData( iconFamily 
, dataType 
, imagehandle 
) ; 
 899         err 
= GetIconFamilyData( iconFamily 
, maskType 
, maskhandle 
) ; 
 900         size_t imagehandlesize 
= GetHandleSize( imagehandle 
) ; 
 901         size_t maskhandlesize 
= GetHandleSize( maskhandle 
) ; 
 903         if ( imagehandlesize 
!= 0 && maskhandlesize 
!= 0 ) 
 905             wxASSERT( GetHandleSize( imagehandle 
) == w 
* 4 * h 
) ; 
 906             wxASSERT( GetHandleSize( maskhandle 
) == w 
* h 
) ; 
 910             unsigned char *source 
= (unsigned char *) *imagehandle 
; 
 911             unsigned char *sourcemask 
= (unsigned char *) *maskhandle 
; 
 912             unsigned char* destination 
= (unsigned char*) BeginRawAccess() ; 
 914             for ( int y 
= 0 ; y 
< h 
; ++y 
) 
 916                 for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 918                     unsigned char a 
= *sourcemask
++; 
 921 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 922                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 923                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 924                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 926                     *destination
++ = *source
++ ; 
 927                     *destination
++ = *source
++ ; 
 928                     *destination
++ = *source
++ ; 
 934             DisposeHandle( imagehandle 
) ; 
 935             DisposeHandle( maskhandle 
) ; 
 939         DisposeHandle( (Handle
) iconFamily 
) ; 
 945         dc
.SelectObject( *this ) ; 
 946         dc
.DrawIcon( icon 
, 0 , 0 ) ; 
 947         dc
.SelectObject( wxNullBitmap 
) ; 
 953 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 955     wxBitmapRefData
* bitmapRefData
; 
 957     m_refData 
= bitmapRefData 
= new wxBitmapRefData( the_width 
, the_height 
, no_bits 
) ; 
 959     if (bitmapRefData
->IsOk()) 
 963             int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 964             if ( the_width 
% (sizeof(unsigned char) * 8) ) 
 965                 linesize 
+= sizeof(unsigned char); 
 967             unsigned char* linestart 
= (unsigned char*) bits 
; 
 968             unsigned char* destptr 
= (unsigned char*) BeginRawAccess() ; 
 970             for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize
, destptr 
+= M_BITMAPDATA
->GetBytesPerRow() ) 
 972                 unsigned char* destination 
= destptr
; 
 973                 int index
, bit
, mask
; 
 975                 for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 981                     if ( linestart
[index
] & mask 
) 
 983                         *destination
++ = 0xFF ; 
 990                         *destination
++ = 0xFF ; 
 991                         *destination
++ = 0xFF ; 
 992                         *destination
++ = 0xFF ; 
 993                         *destination
++ = 0xFF ; 
1002             wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
1004     } /* bitmapRefData->IsOk() */ 
1007 wxBitmap::wxBitmap(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1009     (void) Create(data
, type
, width
, height
, depth
); 
1012 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
) 
1014     LoadFile(filename
, type
); 
1017 wxBitmap::wxBitmap(CGImageRef image
) 
1019     (void) Create(image
); 
1022 wxGDIRefData
* wxBitmap::CreateGDIRefData() const 
1024     return new wxBitmapRefData
; 
1027 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
1029     return new wxBitmapRefData(*static_cast<const wxBitmapRefData 
*>(data
)); 
1032 void * wxBitmap::GetRawAccess() const 
1034     wxCHECK_MSG( IsOk() , NULL 
, wxT("invalid bitmap") ) ; 
1036     return M_BITMAPDATA
->GetRawAccess() ; 
1039 void * wxBitmap::BeginRawAccess() 
1041     wxCHECK_MSG( IsOk() , NULL 
, wxT("invalid bitmap") ) ; 
1043     return M_BITMAPDATA
->BeginRawAccess() ; 
1046 void wxBitmap::EndRawAccess() 
1048     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
1050     M_BITMAPDATA
->EndRawAccess() ; 
1053 CGImageRef 
wxBitmap::CreateCGImage() const 
1055     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
1057     return M_BITMAPDATA
->CreateCGImage() ; 
1060 #ifndef  __WXOSX_IPHONE__ 
1061 IconRef 
wxBitmap::GetIconRef() const 
1063     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
1065     return M_BITMAPDATA
->GetIconRef() ; 
1068 IconRef 
wxBitmap::CreateIconRef() const 
1070     IconRef icon 
= GetIconRef(); 
1071     verify_noerr( AcquireIconRef(icon
) ); 
1078 WX_NSImage 
wxBitmap::GetNSImage() const 
1080     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1081     return wxOSXGetNSImageFromCGImage( cgimage 
); 
1086 #if wxOSX_USE_IPHONE 
1088 WX_UIImage 
wxBitmap::GetUIImage() const 
1090     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1091     return wxOSXGetUIImageFromCGImage( cgimage 
); 
1095 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
1097     wxCHECK_MSG( IsOk() && 
1098                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
1099                 (rect
.x
+rect
.width 
<= GetWidth()) && 
1100                 (rect
.y
+rect
.height 
<= GetHeight()), 
1101                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
1103     wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
1104     wxASSERT_MSG( ret
.IsOk(), wxT("GetSubBitmap error") ); 
1106     int destwidth 
= rect
.width 
; 
1107     int destheight 
= rect
.height 
; 
1110         unsigned char *sourcedata 
= (unsigned char*) GetRawAccess() ; 
1111         unsigned char *destdata 
= (unsigned char*) ret
.BeginRawAccess() ; 
1112         wxASSERT( (sourcedata 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1114         int sourcelinesize 
= GetBitmapData()->GetBytesPerRow() ; 
1115         int destlinesize 
= ret
.GetBitmapData()->GetBytesPerRow() ; 
1116         unsigned char *source 
= sourcedata 
+ rect
.x 
* 4 + rect
.y 
* sourcelinesize 
; 
1117         unsigned char *dest 
= destdata 
; 
1119         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1121             memcpy( dest 
, source 
, destlinesize 
) ; 
1125     ret
.EndRawAccess() ; 
1127     if ( M_BITMAPDATA
->m_bitmapMask 
) 
1129         wxMemoryBuffer maskbuf 
; 
1130         int rowBytes 
= GetBestBytesPerRow( destwidth 
* kMaskBytesPerPixel 
); 
1131         size_t maskbufsize 
= rowBytes 
* destheight 
; 
1133         int sourcelinesize 
= M_BITMAPDATA
->m_bitmapMask
->GetBytesPerRow() ; 
1134         int destlinesize 
= rowBytes 
; 
1136         unsigned char *source 
= (unsigned char *) M_BITMAPDATA
->m_bitmapMask
->GetRawAccess() ; 
1137         unsigned char *destdata 
= (unsigned char * ) maskbuf
.GetWriteBuf( maskbufsize 
) ; 
1138         wxASSERT( (source 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1140         source 
+= rect
.x 
* kMaskBytesPerPixel 
+ rect
.y 
* sourcelinesize 
; 
1141         unsigned char *dest 
= destdata 
; 
1143         for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1145             memcpy( dest 
, source 
, destlinesize 
) ; 
1148         maskbuf
.UngetWriteBuf( maskbufsize 
) ; 
1149         ret
.SetMask( new wxMask( maskbuf 
, destwidth 
, destheight 
, rowBytes 
) ) ; 
1151     else if ( HasAlpha() ) 
1157 bool wxBitmap::Create(int w
, int h
, int d
) 
1162         d 
= wxDisplayDepth() ; 
1164     m_refData 
= new wxBitmapRefData( w 
, h 
, d 
); 
1166     return M_BITMAPDATA
->IsOk() ; 
1170 bool wxBitmap::Create(CGImageRef image
) 
1174     m_refData 
= new wxBitmapRefData( image 
); 
1176     return M_BITMAPDATA
->IsOk() ; 
1179 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
1183     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1187         m_refData 
= new wxBitmapRefData
; 
1189         return handler
->LoadFile(this, filename
, type
, -1, -1); 
1194         wxImage 
loadimage(filename
, type
); 
1195         if (loadimage
.IsOk()) 
1204     wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1209 bool wxBitmap::Create(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1213     m_refData 
= new wxBitmapRefData
; 
1215     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1217     if ( handler 
== NULL 
) 
1219         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1224     return handler
->Create(this, data
, type
, width
, height
, depth
); 
1229 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
1231     wxCHECK_RET( image
.IsOk(), wxT("invalid image") ); 
1233     // width and height of the device-dependent bitmap 
1234     int width 
= image
.GetWidth(); 
1235     int height 
= image
.GetHeight(); 
1237     wxBitmapRefData
* bitmapRefData
; 
1239     m_refData 
= bitmapRefData 
= new wxBitmapRefData( width 
, height 
, depth 
) ; 
1241     if ( bitmapRefData
->IsOk()) 
1245         bool hasAlpha 
= false ; 
1247         if ( image
.HasMask() ) 
1249             // takes precedence, don't mix with alpha info 
1253             hasAlpha 
= image
.HasAlpha() ; 
1259         unsigned char* destinationstart 
= (unsigned char*) BeginRawAccess() ; 
1260         register unsigned char* data 
= image
.GetData(); 
1261         if ( destinationstart 
!= NULL 
&& data 
!= NULL 
) 
1263             const unsigned char *alpha 
= hasAlpha 
? image
.GetAlpha() : NULL 
; 
1264             for (int y 
= 0; y 
< height
; destinationstart 
+= M_BITMAPDATA
->GetBytesPerRow(), y
++) 
1266                 unsigned char * destination 
= destinationstart
; 
1267                 for (int x 
= 0; x 
< width
; x
++) 
1271                         const unsigned char a 
= *alpha
++; 
1272                         *destination
++ = a 
; 
1274     #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1275                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1276                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1277                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1279                         *destination
++ = *data
++ ; 
1280                         *destination
++ = *data
++ ; 
1281                         *destination
++ = *data
++ ; 
1286                         *destination
++ = 0xFF ; 
1287                         *destination
++ = *data
++ ; 
1288                         *destination
++ = *data
++ ; 
1289                         *destination
++ = *data
++ ; 
1296         if ( image
.HasMask() ) 
1297             SetMask( new wxMask( *this , wxColour( image
.GetMaskRed() , image
.GetMaskGreen() , image
.GetMaskBlue() ) ) ) ; 
1298     } /* bitmapRefData->IsOk() */ 
1301 wxImage 
wxBitmap::ConvertToImage() const 
1305     wxCHECK_MSG( IsOk(), wxNullImage
, wxT("invalid bitmap") ); 
1307     // create an wxImage object 
1308     int width 
= GetWidth(); 
1309     int height 
= GetHeight(); 
1310     image
.Create( width
, height 
); 
1312     unsigned char *data 
= image
.GetData(); 
1313     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
1315     unsigned char* sourcestart 
= (unsigned char*) GetRawAccess() ; 
1317     bool hasAlpha 
= false ; 
1318     bool hasMask 
= false ; 
1319     int maskBytesPerRow 
= 0 ; 
1320     unsigned char *alpha 
= NULL 
; 
1321     unsigned char *mask 
= NULL 
; 
1329         mask 
= (unsigned char*) GetMask()->GetRawAccess() ; 
1330         maskBytesPerRow 
= GetMask()->GetBytesPerRow() ; 
1336         alpha 
= image
.GetAlpha() ; 
1341     // The following masking algorithm is the same as well in msw/gtk: 
1342     // the colour used as transparent one in wxImage and the one it is 
1343     // replaced with when it actually occurs in the bitmap 
1344     static const int MASK_RED 
= 1; 
1345     static const int MASK_GREEN 
= 2; 
1346     static const int MASK_BLUE 
= 3; 
1347     static const int MASK_BLUE_REPLACEMENT 
= 2; 
1349     for (int yy 
= 0; yy 
< height
; yy
++ , sourcestart 
+= M_BITMAPDATA
->GetBytesPerRow() , mask 
+= maskBytesPerRow 
) 
1351         unsigned char * maskp 
= mask 
; 
1352         unsigned char * source 
= sourcestart
; 
1353         unsigned char a
, r
, g
, b
; 
1356         for (int xx 
= 0; xx 
< width
; xx
++) 
1358             color 
= *((long*) source
) ; 
1359 #ifdef WORDS_BIGENDIAN 
1360             a 
= ((color
&0xFF000000) >> 24) ; 
1361             r 
= ((color
&0x00FF0000) >> 16) ; 
1362             g 
= ((color
&0x0000FF00) >> 8) ; 
1363             b 
= (color
&0x000000FF); 
1365             b 
= ((color
&0xFF000000) >> 24) ; 
1366             g 
= ((color
&0x00FF0000) >> 16) ; 
1367             r 
= ((color
&0x0000FF00) >> 8) ; 
1368             a 
= (color
&0x000000FF); 
1372                 if ( *maskp
++ == 0xFF ) 
1378                 else if ( r 
== MASK_RED 
&& g 
== MASK_GREEN 
&& b 
== MASK_BLUE 
) 
1379                     b 
= MASK_BLUE_REPLACEMENT 
; 
1381             else if ( hasAlpha 
) 
1384 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1385                 // this must be non-premultiplied data 
1386                 if ( a 
!= 0xFF && a
!= 0 ) 
1396             data
[index 
+ 1] = g 
; 
1397             data
[index 
+ 2] = b 
; 
1405         image
.SetMaskColour( MASK_RED
, MASK_GREEN
, MASK_BLUE 
); 
1410 #endif //wxUSE_IMAGE 
1412 bool wxBitmap::SaveFile( const wxString
& filename
, 
1413     wxBitmapType type
, const wxPalette 
*palette 
) const 
1415     bool success 
= false; 
1416     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1420         success 
= handler
->SaveFile(this, filename
, type
, palette
); 
1425         wxImage image 
= ConvertToImage(); 
1426         success 
= image
.SaveFile(filename
, type
); 
1428         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1435 int wxBitmap::GetHeight() const 
1437    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1439    return M_BITMAPDATA
->GetHeight(); 
1442 int wxBitmap::GetWidth() const 
1444    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1446    return M_BITMAPDATA
->GetWidth() ; 
1449 int wxBitmap::GetDepth() const 
1451    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1453    return M_BITMAPDATA
->GetDepth(); 
1456 wxMask 
*wxBitmap::GetMask() const 
1458    wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ); 
1460    return M_BITMAPDATA
->m_bitmapMask
; 
1463 bool wxBitmap::HasAlpha() const 
1465    wxCHECK_MSG( IsOk(), false , wxT("invalid bitmap") ); 
1467    return M_BITMAPDATA
->HasAlpha() ; 
1470 void wxBitmap::SetWidth(int w
) 
1473     M_BITMAPDATA
->SetWidth(w
); 
1476 void wxBitmap::SetHeight(int h
) 
1479     M_BITMAPDATA
->SetHeight(h
); 
1482 void wxBitmap::SetDepth(int d
) 
1485     M_BITMAPDATA
->SetDepth(d
); 
1488 void wxBitmap::SetOk(bool isOk
) 
1491     M_BITMAPDATA
->SetOk(isOk
); 
1495 wxPalette 
*wxBitmap::GetPalette() const 
1497    wxCHECK_MSG( IsOk(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
1499    return &M_BITMAPDATA
->m_bitmapPalette
; 
1502 void wxBitmap::SetPalette(const wxPalette
& palette
) 
1505     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
1507 #endif // wxUSE_PALETTE 
1509 void wxBitmap::SetMask(wxMask 
*mask
) 
1512     // Remove existing mask if there is one. 
1513     delete M_BITMAPDATA
->m_bitmapMask
; 
1515     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
1518 WXHBITMAP 
wxBitmap::GetHBITMAP(WXHBITMAP
* mask
) const 
1522     return WXHBITMAP(M_BITMAPDATA
->GetBitmapContext()); 
1525 // ---------------------------------------------------------------------------- 
1527 // ---------------------------------------------------------------------------- 
1534 wxMask::wxMask(const wxMask 
&tocopy
) : wxObject() 
1538     m_bytesPerRow 
= tocopy
.m_bytesPerRow
; 
1539     m_width 
= tocopy
.m_width
; 
1540     m_height 
= tocopy
.m_height
; 
1542     size_t size 
= m_bytesPerRow 
* m_height
; 
1543     unsigned char* dest 
= (unsigned char*)m_memBuf
.GetWriteBuf( size 
); 
1544     unsigned char* source 
= (unsigned char*)tocopy
.m_memBuf
.GetData(); 
1545     memcpy( dest
, source
, size 
); 
1546     m_memBuf
.UngetWriteBuf( size 
) ; 
1550 // Construct a mask from a bitmap and a colour indicating 
1551 // the transparent area 
1552 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
1555     Create( bitmap
, colour 
); 
1558 // Construct a mask from a mono bitmap (copies the bitmap). 
1559 wxMask::wxMask( const wxBitmap
& bitmap 
) 
1565 // Construct a mask from a mono bitmap (copies the bitmap). 
1567 wxMask::wxMask( const wxMemoryBuffer
& data
, int width 
, int height 
, int bytesPerRow 
) 
1570     Create( data
, width 
, height 
, bytesPerRow 
); 
1577         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1578         m_maskBitmap 
= NULL 
; 
1584     m_width 
= m_height 
= m_bytesPerRow 
= 0 ; 
1585     m_maskBitmap 
= NULL 
; 
1588 void *wxMask::GetRawAccess() const 
1590     return m_memBuf
.GetData() ; 
1593 // The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed 
1594 // bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well 
1596 void wxMask::RealizeNative() 
1600         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1601        m_maskBitmap 
= NULL 
; 
1604     CGColorSpaceRef colorspace 
= CGColorSpaceCreateDeviceGray(); 
1605     // from MouseTracking sample : 
1606     // Ironically, due to a bug in CGImageCreateWithMask, you cannot use 
1607     // CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) at this point! 
1609     m_maskBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, colorspace
, 
1610         kCGImageAlphaNone 
); 
1611     CGColorSpaceRelease( colorspace 
); 
1612     wxASSERT_MSG( m_maskBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
1615 // Create a mask from a mono bitmap (copies the bitmap). 
1617 bool wxMask::Create(const wxMemoryBuffer
& data
,int width 
, int height 
, int bytesPerRow
) 
1622     m_bytesPerRow 
= bytesPerRow 
; 
1624     wxASSERT( data
.GetDataLen() == (size_t)(height 
* bytesPerRow
) ) ; 
1631 // Create a mask from a mono bitmap (copies the bitmap). 
1632 bool wxMask::Create(const wxBitmap
& bitmap
) 
1634     m_width 
= bitmap
.GetWidth() ; 
1635     m_height 
= bitmap
.GetHeight() ; 
1636     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1638     size_t size 
= m_bytesPerRow 
* m_height 
; 
1639     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1640     wxASSERT( destdatabase 
!= NULL 
) ; 
1642     memset( destdatabase 
, 0 , size 
) ; 
1643     unsigned char * srcdata 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1645     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, destdatabase 
+= m_bytesPerRow 
) 
1647         unsigned char *destdata 
= destdatabase 
; 
1648         unsigned char r
, g
, b
; 
1650         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1657             if ( ( r 
+ g 
+ b 
) > 0x10 ) 
1658                 *destdata
++ = 0xFF ; 
1660                 *destdata
++ = 0x00 ; 
1664     m_memBuf
.UngetWriteBuf( size 
) ; 
1670 // Create a mask from a bitmap and a colour indicating 
1671 // the transparent area 
1672 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1674     m_width 
= bitmap
.GetWidth() ; 
1675     m_height 
= bitmap
.GetHeight() ; 
1676     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1678     size_t size 
= m_bytesPerRow 
* m_height 
; 
1679     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1680     wxASSERT( destdatabase 
!= NULL 
) ; 
1682     memset( destdatabase 
, 0 , size 
) ; 
1683     unsigned char * srcdatabase 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1684     size_t sourceBytesRow 
= bitmap
.GetBitmapData()->GetBytesPerRow(); 
1686     for ( int y 
= 0 ; y 
< m_height 
; ++y 
, srcdatabase
+= sourceBytesRow
, destdatabase 
+= m_bytesPerRow
) 
1688         unsigned char *srcdata 
= srcdatabase 
; 
1689         unsigned char *destdata 
= destdatabase 
; 
1690         unsigned char r
, g
, b
; 
1692         for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1699             if ( colour 
== wxColour( r 
, g 
, b 
) ) 
1700                 *destdata
++ = 0xFF ; 
1702                 *destdata
++ = 0x00 ; 
1706     m_memBuf
.UngetWriteBuf( size 
) ; 
1712 WXHBITMAP 
wxMask::GetHBITMAP() const 
1714     return m_maskBitmap 
; 
1717 // ---------------------------------------------------------------------------- 
1718 // Standard Handlers 
1719 // ---------------------------------------------------------------------------- 
1721 class WXDLLEXPORT wxBundleResourceHandler
: public wxBitmapHandler
 
1723     DECLARE_ABSTRACT_CLASS(wxPNGResourceHandler
) 
1726     inline wxBundleResourceHandler() 
1730     virtual bool LoadFile(wxBitmap 
*bitmap
, 
1731                           const wxString
& name
, 
1737 IMPLEMENT_ABSTRACT_CLASS(wxBundleResourceHandler
, wxBitmapHandler
); 
1739 class WXDLLEXPORT wxPNGResourceHandler
: public wxBundleResourceHandler
 
1741     DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler
) 
1744     inline wxPNGResourceHandler() 
1746         SetName(wxT("PNG resource")); 
1747         SetExtension("PNG"); 
1748         SetType(wxBITMAP_TYPE_PNG_RESOURCE
); 
1752 IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler
, wxBundleResourceHandler
) 
1754 class WXDLLEXPORT wxJPEGResourceHandler
: public wxBundleResourceHandler
 
1756     DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler
) 
1759     inline wxJPEGResourceHandler() 
1761         SetName(wxT("JPEG resource")); 
1762         SetExtension("JPEG"); 
1763         SetType(wxBITMAP_TYPE_JPEG_RESOURCE
); 
1767 IMPLEMENT_DYNAMIC_CLASS(wxJPEGResourceHandler
, wxBundleResourceHandler
) 
1769 bool wxBundleResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1770                                      const wxString
& name
, 
1771                                      wxBitmapType 
WXUNUSED(type
), 
1772                                      int WXUNUSED(desiredWidth
), 
1773                                      int WXUNUSED(desiredHeight
)) 
1775     wxString ext 
= GetExtension().Lower(); 
1776     wxCFStringRef 
resname(name
); 
1777     wxCFStringRef 
restype(ext
); 
1779     wxCFRef
<CFURLRef
> imageURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname
, restype
, NULL
)); 
1781     if ( imageURL
.get() != NULL 
) 
1783         // Create the data provider object 
1784         wxCFRef
<CGDataProviderRef
> provider(CGDataProviderCreateWithURL (imageURL
) ); 
1785         CGImageRef image 
= NULL
; 
1787         if ( ext 
== "jpeg" ) 
1788             image 
= CGImageCreateWithJPEGDataProvider (provider
, NULL
, true, 
1789                                                    kCGRenderingIntentDefault
); 
1790         else if ( ext 
== "png" ) 
1791             image 
= CGImageCreateWithPNGDataProvider (provider
, NULL
, true, 
1792                                                        kCGRenderingIntentDefault
); 
1793         if ( image 
!= NULL 
) 
1795             bitmap
->Create(image
); 
1796             CGImageRelease(image
); 
1803 #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) 
1805 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1807     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1810     inline wxPICTResourceHandler() 
1812         SetName(wxT("Macintosh Pict resource")); 
1813         SetExtension(wxEmptyString
); 
1814         SetType(wxBITMAP_TYPE_PICT_RESOURCE
); 
1817     virtual bool LoadFile(wxBitmap 
*bitmap
, 
1818                           const wxString
& name
, 
1824 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1827 bool wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1828                                      const wxString
& name
, 
1829                                      wxBitmapType 
WXUNUSED(type
), 
1830                                      int WXUNUSED(desiredWidth
), 
1831                                      int WXUNUSED(desiredHeight
)) 
1835     wxMacStringToPascal( name 
, theName 
) ; 
1837     PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1842         mf
.SetPICT( thePict 
) ; 
1843         bitmap
->Create( mf
.GetWidth() , mf
.GetHeight() ) ; 
1845         dc
.SelectObject( *bitmap 
) ; 
1847         dc
.SelectObject( wxNullBitmap 
) ; 
1857 void wxBitmap::InitStandardHandlers() 
1859 #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) 
1860     AddHandler( new wxPICTResourceHandler 
) ; 
1862 #if wxOSX_USE_COCOA_OR_CARBON 
1863     AddHandler( new wxICONResourceHandler 
) ; 
1865     AddHandler( new wxPNGResourceHandler 
); 
1866     AddHandler( new wxJPEGResourceHandler 
); 
1869 // ---------------------------------------------------------------------------- 
1870 // raw bitmap access support 
1871 // ---------------------------------------------------------------------------- 
1873 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int WXUNUSED(bpp
)) 
1876         // no bitmap, no data (raw or otherwise) 
1879     data
.m_width 
= GetWidth() ; 
1880     data
.m_height 
= GetHeight() ; 
1881     data
.m_stride 
= GetBitmapData()->GetBytesPerRow() ; 
1883     return BeginRawAccess() ; 
1886 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(dataBase
)) 
1891 void wxBitmap::UseAlpha() 
1893     // remember that we are using alpha channel: 
1894     // we'll need to create a proper mask in UngetRawData() 
1895     M_BITMAPDATA
->UseAlpha( true );