1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/osx/core/bitmap.cpp 
   4 // Author:      Stefan Csomor 
   7 // Copyright:   (c) Stefan Csomor 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 #include "wx/wxprec.h" 
  13 #include "wx/bitmap.h" 
  17     #include "wx/dcmemory.h" 
  22 #include "wx/metafile.h" 
  23 #include "wx/xpmdecod.h" 
  25 #include "wx/rawbmp.h" 
  27 #include "wx/filename.h" 
  29 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  30 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  33 #include "wx/osx/uma.h" 
  35 #include "wx/osx/private.h" 
  38 #ifndef __WXOSX_IPHONE__ 
  39 #include <QuickTime/QuickTime.h> 
  42 CGColorSpaceRef 
wxMacGetGenericRGBColorSpace(); 
  43 CGDataProviderRef 
wxMacCGDataProviderCreateWithMemoryBuffer( const wxMemoryBuffer
& buf 
); 
  45 // Implementation Notes 
  46 // -------------------- 
  48 // we are always working with a 32 bit deep pixel buffer 
  49 // under QuickDraw its alpha parts are going to be ignored in the GWorld, 
  50 // therefore we have a separate GWorld there for blitting the mask in 
  52 // under Quartz then content is transformed into a CGImageRef representing the same data 
  53 // which can be transferred to the GPU by the OS for fast rendering 
  55 class WXDLLEXPORT wxBitmapRefData
: public wxGDIRefData
 
  57     friend class WXDLLIMPEXP_FWD_CORE wxIcon
; 
  58     friend class WXDLLIMPEXP_FWD_CORE wxCursor
; 
  60     wxBitmapRefData(int width 
, int height 
, int depth
, double logicalscale
); 
  61     wxBitmapRefData(int width 
, int height 
, int depth
); 
  62     wxBitmapRefData(CGContextRef context
); 
  63     wxBitmapRefData(CGImageRef image
, double scale
); 
  65     wxBitmapRefData(const wxBitmapRefData 
&tocopy
); 
  67     virtual ~wxBitmapRefData(); 
  69     virtual bool IsOk() const { return m_ok
; } 
  72     void SetOk( bool isOk
) { m_ok 
= isOk
; } 
  74     void SetWidth( int width 
) { m_width 
= width
; } 
  75     void SetHeight( int height 
) { m_height 
= height
; } 
  76     void SetDepth( int depth 
) { m_depth 
= depth
; } 
  78     int GetWidth() const { return m_width
; } 
  79     int GetHeight() const { return m_height
; } 
  80     int GetDepth() const { return m_depth
; } 
  81     double GetScaleFactor() const { return m_scaleFactor
; } 
  82     void *GetRawAccess() const; 
  83     void *BeginRawAccess(); 
  86     bool HasAlpha() const { return m_hasAlpha
; } 
  87     void UseAlpha( bool useAlpha 
); 
  91     wxPalette     m_bitmapPalette
; 
  92 #endif // wxUSE_PALETTE 
  94     wxMask 
*      m_bitmapMask
; // Optional mask 
  95     CGImageRef    
CreateCGImage() const; 
  97     // returns true if the bitmap has a size that 
  98     // can be natively transferred into a true icon 
  99     // if no is returned GetIconRef will still produce 
 100     // an icon but it will be generated via a PICT and 
 101     // rescaled to 16 x 16 
 102     bool          HasNativeSize(); 
 104 #ifndef __WXOSX_IPHONE__ 
 105     // caller should increase ref count if needed longer 
 106     // than the bitmap exists 
 107     IconRef       
GetIconRef(); 
 110     CGContextRef  
GetBitmapContext() const; 
 112     int           GetBytesPerRow() const { return m_bytesPerRow
; } 
 114     bool Create(int width 
, int height 
, int depth
); 
 115     bool Create(int width 
, int height 
, int depth
, double logicalScale
); 
 116     bool Create( CGImageRef image
, double scale 
); 
 117     bool Create( CGContextRef bitmapcontext
); 
 125     wxMemoryBuffer m_memBuf
; 
 126     int           m_rawAccessCount
; 
 128     mutable CGImageRef    m_cgImageRef
; 
 130 #ifndef __WXOSX_IPHONE__ 
 134     CGContextRef  m_hBitmap
; 
 135     double        m_scaleFactor
; 
 139 #define wxOSX_USE_PREMULTIPLIED_ALPHA 1 
 140 static const int kBestByteAlignement 
= 16; 
 141 static const int kMaskBytesPerPixel 
= 1; 
 143 static int GetBestBytesPerRow( int rawBytes 
) 
 145     return (((rawBytes
)+kBestByteAlignement
-1) & ~(kBestByteAlignement
-1) ); 
 148 #if wxUSE_GUI && !defined(__WXOSX_IPHONE__) 
 150 // this is used for more controls than just the wxBitmap button, also for notebooks etc 
 152 void wxMacCreateBitmapButton( ControlButtonContentInfo
*info 
, const wxBitmap
& bitmap 
, int forceType 
) 
 154     memset( info 
, 0 , sizeof(ControlButtonContentInfo
) ) ; 
 157         wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 161         if ( forceType 
== 0  ) 
 163             forceType 
= kControlContentCGImageRef
; 
 166         if ( forceType 
== kControlContentIconRef 
) 
 169             wxBitmapRefData
* bmp 
= bmap 
; 
 171             if ( !bmap
->HasNativeSize() ) 
 173                 // as PICT conversion will only result in a 16x16 icon, let's attempt 
 174                 // a few scales for better results 
 176                 int w 
= bitmap
.GetWidth() ; 
 177                 int h 
= bitmap
.GetHeight() ; 
 178                 int sz 
= wxMax( w 
, h 
) ; 
 179                 if ( sz 
== 24 || sz 
== 64 ) 
 181                     scaleBmp 
= wxBitmap( bitmap
.ConvertToImage().Scale( w 
* 2 , h 
* 2 ) ) ; 
 182                     bmp 
= scaleBmp
.GetBitmapData() ; 
 186             info
->contentType 
= kControlContentIconRef 
; 
 187             info
->u
.iconRef 
= bmp
->GetIconRef() ; 
 188             AcquireIconRef( info
->u
.iconRef 
) ; 
 190         else if ( forceType 
== kControlContentCGImageRef 
) 
 192             info
->contentType 
= kControlContentCGImageRef 
; 
 193             info
->u
.imageRef 
= (CGImageRef
) bmap
->CreateCGImage() ; 
 198 CGImageRef 
wxMacCreateCGImageFromBitmap( const wxBitmap
& bitmap 
) 
 200     wxBitmapRefData 
* bmap 
= bitmap
.GetBitmapData() ; 
 203     return (CGImageRef
) bmap
->CreateCGImage(); 
 206 void wxMacReleaseBitmapButton( ControlButtonContentInfo
*info 
) 
 208     if ( info
->contentType 
== kControlContentIconRef 
) 
 210         ReleaseIconRef( info
->u
.iconRef 
) ; 
 212     else if ( info
->contentType 
== kControlNoContent 
) 
 214         // there's no bitmap at all, fall through silently 
 216     else if ( info
->contentType 
== kControlContentPictHandle 
) 
 218         // owned by the bitmap, no release here 
 220     else if ( info
->contentType 
== kControlContentCGImageRef 
) 
 222         CGImageRelease( info
->u
.imageRef 
) ; 
 226         wxFAIL_MSG(wxT("Unexpected bitmap type") ) ; 
 230 #endif //wxUSE_BMPBUTTON 
 232 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData) 
 234 void wxBitmapRefData::Init() 
 241     m_bitmapMask 
= NULL 
; 
 242     m_cgImageRef 
= NULL 
; 
 244 #ifndef __WXOSX_IPHONE__ 
 249     m_rawAccessCount 
= 0 ; 
 254 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData 
&tocopy
) : wxGDIRefData() 
 257     Create(tocopy
.m_width
, tocopy
.m_height
, tocopy
.m_depth
, tocopy
.m_scaleFactor
); 
 259     if (tocopy
.m_bitmapMask
) 
 260         m_bitmapMask 
= new wxMask(*tocopy
.m_bitmapMask
); 
 261     else if (tocopy
.m_hasAlpha
) 
 264     unsigned char* dest 
= (unsigned char*)GetRawAccess(); 
 265     unsigned char* source 
= (unsigned char*)tocopy
.GetRawAccess(); 
 266     size_t numbytes 
= m_bytesPerRow 
* m_height
; 
 267     memcpy( dest
, source
, numbytes 
); 
 270 wxBitmapRefData::wxBitmapRefData() 
 275 wxBitmapRefData::wxBitmapRefData( int w 
, int h 
, int d 
) 
 278     Create( w 
, h 
, d 
) ; 
 281 wxBitmapRefData::wxBitmapRefData(int w 
, int h 
, int d
, double logicalscale
) 
 284     Create( w 
, h 
, d
, logicalscale 
) ; 
 287 wxBitmapRefData::wxBitmapRefData(CGContextRef context
) 
 293 wxBitmapRefData::wxBitmapRefData(CGImageRef image
, double scale
) 
 296     Create( image
, scale 
); 
 298 // code from Technical Q&A QA1509 
 300 bool wxBitmapRefData::Create(CGImageRef image
, double scale
) 
 304         m_width 
= CGImageGetWidth(image
); 
 305         m_height 
= CGImageGetHeight(image
); 
 308         m_scaleFactor 
= scale
; 
 310         m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 311         size_t size 
= m_bytesPerRow 
* m_height 
; 
 312         void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 315             memset( data 
, 0 , size 
) ; 
 316             m_memBuf
.UngetWriteBuf( size 
) ; 
 317             CGImageAlphaInfo alpha 
= CGImageGetAlphaInfo(image
); 
 318             if ( alpha 
== kCGImageAlphaNone 
|| alpha 
== kCGImageAlphaNoneSkipFirst 
|| alpha 
== kCGImageAlphaNoneSkipLast 
) 
 320                 m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 325                 m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst 
); 
 327             CGRect rect 
= CGRectMake(0,0,m_width
,m_height
); 
 328             CGContextDrawImage(m_hBitmap
, rect
, image
); 
 330             wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 331             CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 332             CGContextScaleCTM( m_hBitmap
, 1*m_scaleFactor
, -1*m_scaleFactor 
); 
 335     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 341 bool wxBitmapRefData::Create(CGContextRef context
) 
 343     if ( context 
!= NULL 
&& CGBitmapContextGetData(context
) ) 
 346         m_bytesPerRow 
= CGBitmapContextGetBytesPerRow(context
); 
 347         m_width 
= CGBitmapContextGetWidth(context
); 
 348         m_height 
= CGBitmapContextGetHeight(context
); 
 349         m_depth 
= CGBitmapContextGetBitsPerPixel(context
) ; 
 351         // our own contexts conform to this, always. 
 352         wxASSERT( m_depth 
== 32 ); 
 354         // determine content scale 
 355         CGRect userrect 
= CGRectMake(0, 0, 10, 10); 
 357         devicerect 
= CGContextConvertRectToDeviceSpace(context
, userrect
); 
 358         m_scaleFactor 
= devicerect
.size
.height 
/ userrect
.size
.height
; 
 360         CGImageAlphaInfo alpha 
= CGBitmapContextGetAlphaInfo(context
); 
 362         if ( alpha 
== kCGImageAlphaNone 
|| alpha 
== kCGImageAlphaNoneSkipFirst 
|| alpha 
== kCGImageAlphaNoneSkipLast 
) 
 371     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 376 bool wxBitmapRefData::Create( int w 
, int h 
, int d 
) 
 378     m_width 
= wxMax(1, w
); 
 379     m_height 
= wxMax(1, h
); 
 383     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* 4 ) ; 
 384     size_t size 
= m_bytesPerRow 
* m_height 
; 
 385     void* data 
= m_memBuf
.GetWriteBuf( size 
) ; 
 388         memset( data 
, 0 , size 
) ; 
 389         m_memBuf
.UngetWriteBuf( size 
) ; 
 391         m_hBitmap 
= CGBitmapContextCreate((char*) data
, m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst 
); 
 392         wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 393         CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 394         CGContextScaleCTM( m_hBitmap
, 1*m_scaleFactor
, -1*m_scaleFactor 
); 
 396     m_ok 
= ( m_hBitmap 
!= NULL 
) ; 
 401 bool wxBitmapRefData::Create( int w 
, int h 
, int d
, double logicalScale 
) 
 403     m_scaleFactor 
= logicalScale
; 
 404     return Create(w
*logicalScale
,h
*logicalScale
,d
); 
 407 void wxBitmapRefData::UseAlpha( bool use 
) 
 409     if ( m_hasAlpha 
== use 
) 
 414     CGContextRelease( m_hBitmap 
); 
 415     m_hBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, wxMacGetGenericRGBColorSpace(), m_hasAlpha 
? kCGImageAlphaPremultipliedFirst 
: kCGImageAlphaNoneSkipFirst 
); 
 416     wxASSERT_MSG( m_hBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
 417     CGContextTranslateCTM( m_hBitmap
, 0,  m_height 
); 
 418     CGContextScaleCTM( m_hBitmap
, 1*m_scaleFactor
, -1*m_scaleFactor 
); 
 421 void *wxBitmapRefData::GetRawAccess() const 
 423     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
 424     return m_memBuf
.GetData() ; 
 427 void *wxBitmapRefData::BeginRawAccess() 
 429     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ) ; 
 430     wxASSERT( m_rawAccessCount 
== 0 ) ; 
 431 #ifndef __WXOSX_IPHONE__ 
 432     wxASSERT_MSG( m_iconRef 
== NULL 
, 
 433                  wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; 
 437     // we must destroy an existing cached image, as 
 438     // the bitmap data may change now 
 441         CGImageRelease( m_cgImageRef 
) ; 
 442         m_cgImageRef 
= NULL 
; 
 445     return m_memBuf
.GetData() ; 
 448 void wxBitmapRefData::EndRawAccess() 
 450     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
 451     wxASSERT( m_rawAccessCount 
== 1 ) ; 
 456 bool wxBitmapRefData::HasNativeSize() 
 459     int h 
= GetHeight() ; 
 460     int sz 
= wxMax( w 
, h 
) ; 
 462     return ( sz 
== 128 || sz 
== 48 || sz 
== 32 || sz 
== 16 ); 
 465 #ifndef __WXOSX_IPHONE__ 
 466 IconRef 
wxBitmapRefData::GetIconRef() 
 468     if ( m_iconRef 
== NULL 
) 
 470         // Create Icon Family Handle 
 472         IconFamilyHandle iconFamily 
= (IconFamilyHandle
) NewHandle( 0 ); 
 475         int h 
= GetHeight() ; 
 476         int sz 
= wxMax( w 
, h 
) ; 
 478         OSType dataType 
= 0 ; 
 479         OSType maskType 
= 0 ; 
 481         // since we don't have PICT conversion available, use 
 482         // the next larger standard icon size 
 496         else if ( sz 
<= 1024) 
 501 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 
 503                 dataType 
= kIconServices1024PixelDataARGB
; 
 507                 dataType 
= kIconServices512PixelDataARGB
; 
 511                 dataType 
= kIconServices256PixelDataARGB
; 
 515                 dataType 
= kIconServices128PixelDataARGB 
; 
 519                 dataType 
= kIconServices48PixelDataARGB 
; 
 523                 dataType 
= kIconServices32PixelDataARGB 
; 
 527                 dataType 
= kIconServices16PixelDataARGB 
; 
 538                 size_t datasize 
= sz 
* sz 
* 4 ; 
 539                 Handle data 
= NewHandle( datasize 
) ; 
 541                 unsigned char* ptr 
= (unsigned char*) *data 
; 
 542                 memset( ptr
, 0, datasize 
); 
 543                 bool hasAlpha 
= HasAlpha() ; 
 544                 wxMask 
*mask 
= m_bitmapMask 
; 
 545                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 546                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 548                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 550                     unsigned char * source 
= sourcePtr
; 
 551                     unsigned char * masksource 
= masksourcePtr
; 
 552                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 553                     unsigned char a
, r
, g
, b
; 
 555                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 564                             a 
= 0xFF - *masksource
++ ; 
 566                         else if ( !hasAlpha 
) 
 570 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 571                             // this must be non-premultiplied data 
 572                             if ( a 
!= 0xFF && a
!= 0 ) 
 589                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
); 
 592                     wxFAIL_MSG("Error when adding bitmap"); 
 595                 DisposeHandle( data 
); 
 599                 // setup the header properly 
 602                 Handle maskdata 
= NULL 
; 
 603                 unsigned char * maskptr 
= NULL 
; 
 604                 unsigned char * ptr 
= NULL 
; 
 605                 size_t datasize
, masksize 
; 
 607                 datasize 
= sz 
* sz 
* 4 ; 
 608                 data 
= NewHandle( datasize 
) ; 
 610                 ptr 
= (unsigned char*) *data 
; 
 611                 memset( ptr 
, 0, datasize 
) ; 
 614                 maskdata 
= NewHandle( masksize 
) ; 
 616                 maskptr 
= (unsigned char*) *maskdata 
; 
 617                 memset( maskptr 
, 0 , masksize 
) ; 
 619                 bool hasAlpha 
= HasAlpha() ; 
 620                 wxMask 
*mask 
= m_bitmapMask 
; 
 621                 unsigned char * sourcePtr 
= (unsigned char*) GetRawAccess() ; 
 622                 unsigned char * masksourcePtr 
= mask 
? (unsigned char*) mask
->GetRawAccess() : NULL 
; 
 624                 for ( int y 
= 0 ; y 
< h 
; ++y
, sourcePtr 
+= m_bytesPerRow 
, masksourcePtr 
+= mask 
? mask
->GetBytesPerRow() : 0 ) 
 626                     unsigned char * source 
= sourcePtr
; 
 627                     unsigned char * masksource 
= masksourcePtr
; 
 628                     unsigned char * dest 
= ptr 
+ y 
* sz 
* 4 ; 
 629                     unsigned char * maskdest 
= maskptr 
+ y 
* sz 
; 
 630                     unsigned char a
, r
, g
, b
; 
 632                     for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 645                             *maskdest
++ = 0xFF - *masksource
++ ; 
 653                 OSStatus err 
= SetIconFamilyData( iconFamily
, dataType 
, data 
) ; 
 654                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding bitmap") ) ; 
 656                 err 
= SetIconFamilyData( iconFamily
, maskType 
, maskdata 
) ; 
 657                 wxASSERT_MSG( err 
== noErr 
, wxT("Error when adding mask") ) ; 
 660                 HUnlock( maskdata 
) ; 
 661                 DisposeHandle( data 
) ; 
 662                 DisposeHandle( maskdata 
) ; 
 665         // transform into IconRef 
 667         // cleaner version existing from 10.3 upwards 
 668         HLock((Handle
) iconFamily
); 
 669         OSStatus err 
= GetIconRefFromIconFamilyPtr( *iconFamily
, GetHandleSize((Handle
) iconFamily
), &m_iconRef 
); 
 670         HUnlock((Handle
) iconFamily
); 
 671         DisposeHandle( (Handle
) iconFamily 
) ; 
 673         wxCHECK_MSG( err 
== noErr
, NULL
, wxT("Error when constructing icon ref") ); 
 681 CGImageRef 
wxBitmapRefData::CreateCGImage() const 
 684     wxASSERT( m_rawAccessCount 
>= 0 ) ; 
 686     if ( m_rawAccessCount 
> 0 || m_cgImageRef 
== NULL 
) 
 688         if ( m_depth 
!= 1 && m_bitmapMask 
== NULL 
) 
 691             // in order for this code to work properly, wxMask would have to invert black and white 
 692             // in the native bitmap 
 695                 CGImageRef tempImage 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 696                 CGImageRef tempMask 
= CGBitmapContextCreateImage((CGContextRef
) m_bitmapMask
->GetHBITMAP() ); 
 697                 image 
= CGImageCreateWithMask( tempImage
, tempMask 
); 
 698                 CGImageRelease(tempMask
); 
 699                 CGImageRelease(tempImage
); 
 703                 image 
= CGBitmapContextCreateImage( m_hBitmap 
); 
 707             size_t imageSize 
= m_height 
* m_bytesPerRow 
; 
 708             void * dataBuffer 
= m_memBuf
.GetData() ; 
 711             CGImageAlphaInfo alphaInfo 
= kCGImageAlphaNoneSkipFirst 
; 
 712             wxMemoryBuffer membuf
; 
 716                 alphaInfo 
= kCGImageAlphaFirst 
; 
 717                 unsigned char *destalphastart 
= (unsigned char*) membuf
.GetWriteBuf( imageSize 
) ; 
 718                 memcpy( destalphastart 
, dataBuffer 
, imageSize 
) ; 
 719                 unsigned char *sourcemaskstart 
= (unsigned char *) m_bitmapMask
->GetRawAccess() ; 
 720                 int maskrowbytes 
= m_bitmapMask
->GetBytesPerRow() ; 
 721                 for ( int y 
= 0 ; y 
< h 
; ++y 
, destalphastart 
+= m_bytesPerRow
, sourcemaskstart 
+= maskrowbytes
) 
 723                     unsigned char *sourcemask 
= sourcemaskstart 
; 
 724                     unsigned char *destalpha 
= destalphastart 
; 
 725                     for ( int x 
= 0 ; x 
< w 
; ++x 
, sourcemask 
+= kMaskBytesPerPixel 
, destalpha 
+= 4 ) 
 727                         *destalpha 
= 0xFF - *sourcemask 
; 
 730                 membuf
.UngetWriteBuf( imageSize 
); 
 736 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 737                     alphaInfo 
= kCGImageAlphaPremultipliedFirst 
; 
 739                     alphaInfo 
= kCGImageAlphaFirst 
; 
 746             CGDataProviderRef dataProvider 
= NULL 
; 
 749                 // TODO CHECK ALIGNMENT 
 750                 wxMemoryBuffer maskBuf
; 
 751                 unsigned char * maskBufData 
= (unsigned char*) maskBuf
.GetWriteBuf( m_width 
* m_height 
); 
 752                 unsigned char * bufData 
= (unsigned char *) membuf
.GetData() ; 
 753                 // copy one color component 
 755                 for( int y 
= 0 ; y 
< m_height 
; bufData
+= m_bytesPerRow
, ++y 
) 
 757                     unsigned char *bufDataIter 
= bufData
+3; 
 758                     for ( int x 
= 0 ; x 
< m_width 
; bufDataIter 
+= 4, ++x
, ++i 
) 
 760                         maskBufData
[i
] = *bufDataIter
; 
 763                 maskBuf
.UngetWriteBuf( m_width 
* m_height 
); 
 766                     wxMacCGDataProviderCreateWithMemoryBuffer( maskBuf 
); 
 768                 image 
= ::CGImageMaskCreate( w
, h
, 8, 8, m_width 
, dataProvider
, NULL
, false ); 
 772                 CGColorSpaceRef colorSpace 
= wxMacGetGenericRGBColorSpace(); 
 773                 dataProvider 
= wxMacCGDataProviderCreateWithMemoryBuffer( membuf 
); 
 776                                     w
, h
, 8 , 32 , m_bytesPerRow 
, colorSpace
, alphaInfo 
, 
 777                                     dataProvider
, NULL 
, false , kCGRenderingIntentDefault 
); 
 779             CGDataProviderRelease( dataProvider
); 
 784         image 
= m_cgImageRef 
; 
 785         CGImageRetain( image 
) ; 
 788     if ( m_rawAccessCount 
== 0 && m_cgImageRef 
== NULL
) 
 790         // we keep it for later use 
 791         m_cgImageRef 
= image 
; 
 792         CGImageRetain( image 
) ; 
 798 CGContextRef 
wxBitmapRefData::GetBitmapContext() const 
 803 void wxBitmapRefData::Free() 
 805     wxASSERT_MSG( m_rawAccessCount 
== 0 , wxT("Bitmap still selected when destroyed") ) ; 
 809         CGImageRelease( m_cgImageRef 
) ; 
 810         m_cgImageRef 
= NULL 
; 
 812 #ifndef __WXOSX_IPHONE__ 
 815         ReleaseIconRef( m_iconRef 
) ; 
 821         CGContextRelease(m_hBitmap
); 
 825     wxDELETE(m_bitmapMask
); 
 828 wxBitmapRefData::~wxBitmapRefData() 
 835 // ---------------------------------------------------------------------------- 
 837 // ---------------------------------------------------------------------------- 
 839 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 841     bool created 
= false ; 
 842     int w 
= icon
.GetWidth() ; 
 843     int h 
= icon
.GetHeight() ; 
 846 #ifdef __WXOSX_CARBON__ 
 847     if ( w 
== h 
&& ( w 
== 16 || w 
== 32 || w 
== 48 || w 
== 128 ) ) 
 849         IconFamilyHandle iconFamily 
= NULL 
; 
 850         Handle imagehandle 
= NewHandle( 0 ) ; 
 851         Handle maskhandle 
= NewHandle( 0 ) ; 
 855         IconSelectorValue selector 
= 0 ; 
 860                 dataType 
= kThumbnail32BitData 
; 
 861                 maskType 
= kThumbnail8BitMask 
; 
 862                 selector 
= kSelectorAllAvailableData 
; 
 866                 dataType 
= kHuge32BitData 
; 
 867                 maskType 
= kHuge8BitMask 
; 
 868                 selector 
= kSelectorHuge32Bit 
| kSelectorHuge8BitMask 
; 
 872                 dataType 
= kLarge32BitData 
; 
 873                 maskType 
= kLarge8BitMask 
; 
 874                 selector 
= kSelectorLarge32Bit 
| kSelectorLarge8BitMask 
; 
 878                 dataType 
= kSmall32BitData 
; 
 879                 maskType 
= kSmall8BitMask 
; 
 880                 selector 
= kSelectorSmall32Bit 
| kSelectorSmall8BitMask 
; 
 887         OSStatus err 
= IconRefToIconFamily( MAC_WXHICON(icon
.GetHICON()) , selector 
, &iconFamily 
) ; 
 889         err 
= GetIconFamilyData( iconFamily 
, dataType 
, imagehandle 
) ; 
 890         err 
= GetIconFamilyData( iconFamily 
, maskType 
, maskhandle 
) ; 
 891         size_t imagehandlesize 
= GetHandleSize( imagehandle 
) ; 
 892         size_t maskhandlesize 
= GetHandleSize( maskhandle 
) ; 
 894         if ( imagehandlesize 
!= 0 && maskhandlesize 
!= 0 ) 
 896             wxASSERT( GetHandleSize( imagehandle 
) == w 
* 4 * h 
) ; 
 897             wxASSERT( GetHandleSize( maskhandle 
) == w 
* h 
) ; 
 901             unsigned char *source 
= (unsigned char *) *imagehandle 
; 
 902             unsigned char *sourcemask 
= (unsigned char *) *maskhandle 
; 
 903             unsigned char* destination 
= (unsigned char*) BeginRawAccess() ; 
 905             for ( int y 
= 0 ; y 
< h 
; ++y 
) 
 907                 for ( int x 
= 0 ; x 
< w 
; ++x 
) 
 909                     unsigned char a 
= *sourcemask
++; 
 912 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
 913                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 914                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 915                     *destination
++ = ( (*source
++) * a 
+ 127 ) / 255; 
 917                     *destination
++ = *source
++ ; 
 918                     *destination
++ = *source
++ ; 
 919                     *destination
++ = *source
++ ; 
 925             DisposeHandle( imagehandle 
) ; 
 926             DisposeHandle( maskhandle 
) ; 
 930         DisposeHandle( (Handle
) iconFamily 
) ; 
 936         dc
.SelectObject( *this ) ; 
 937         dc
.DrawIcon( icon 
, 0 , 0 ) ; 
 938         dc
.SelectObject( wxNullBitmap 
) ; 
 944 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 946     wxBitmapRefData
* bitmapRefData
; 
 948     m_refData 
= bitmapRefData 
= new wxBitmapRefData( the_width 
, the_height 
, no_bits 
) ; 
 950     if (bitmapRefData
->IsOk()) 
 954             int linesize 
= the_width 
/ 8; 
 958             unsigned char* linestart 
= (unsigned char*) bits 
; 
 959             unsigned char* destptr 
= (unsigned char*) BeginRawAccess() ; 
 961             for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize
, destptr 
+= M_BITMAPDATA
->GetBytesPerRow() ) 
 963                 unsigned char* destination 
= destptr
; 
 964                 int index
, bit
, mask
; 
 966                 for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 972                     if ( linestart
[index
] & mask 
) 
 974                         *destination
++ = 0xFF ; 
 981                         *destination
++ = 0xFF ; 
 982                         *destination
++ = 0xFF ; 
 983                         *destination
++ = 0xFF ; 
 984                         *destination
++ = 0xFF ; 
 993             wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 995     } /* bitmapRefData->IsOk() */ 
 998 wxBitmap::wxBitmap(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1000     (void) Create(data
, type
, width
, height
, depth
); 
1003 wxBitmap::wxBitmap(int width
, int height
, const wxDC
& dc
) 
1005     (void)Create(width
, height
, dc
); 
1008 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
) 
1010     LoadFile(filename
, type
); 
1013 wxBitmap::wxBitmap(CGImageRef image
, double scale
) 
1015     (void) Create(image
,scale
); 
1018 wxGDIRefData
* wxBitmap::CreateGDIRefData() const 
1020     return new wxBitmapRefData
; 
1023 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
1025     return new wxBitmapRefData(*static_cast<const wxBitmapRefData 
*>(data
)); 
1028 void * wxBitmap::GetRawAccess() const 
1030     wxCHECK_MSG( IsOk() , NULL 
, wxT("invalid bitmap") ) ; 
1032     return M_BITMAPDATA
->GetRawAccess() ; 
1035 void * wxBitmap::BeginRawAccess() 
1037     wxCHECK_MSG( IsOk() , NULL 
, wxT("invalid bitmap") ) ; 
1039     return M_BITMAPDATA
->BeginRawAccess() ; 
1042 void wxBitmap::EndRawAccess() 
1044     wxCHECK_RET( IsOk() , wxT("invalid bitmap") ) ; 
1046     M_BITMAPDATA
->EndRawAccess() ; 
1049 CGImageRef 
wxBitmap::CreateCGImage() const 
1051     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
1053     return M_BITMAPDATA
->CreateCGImage() ; 
1056 #ifndef  __WXOSX_IPHONE__ 
1057 IconRef 
wxBitmap::GetIconRef() const 
1059     wxCHECK_MSG( IsOk(), NULL 
, wxT("invalid bitmap") ) ; 
1061     return M_BITMAPDATA
->GetIconRef() ; 
1064 IconRef 
wxBitmap::CreateIconRef() const 
1066     IconRef icon 
= GetIconRef(); 
1067     verify_noerr( AcquireIconRef(icon
) ); 
1074 wxBitmap::wxBitmap(WX_NSImage image
) 
1076     (void)Create(image
); 
1079 bool wxBitmap::Create(WX_NSImage image
) 
1081     return Create(wxOSXCreateBitmapContextFromNSImage(image
)); 
1084 wxBitmap::wxBitmap(CGContextRef bitmapcontext
) 
1086     (void)Create(bitmapcontext
); 
1089 bool wxBitmap::Create(CGContextRef bitmapcontext
) 
1093     m_refData 
= new wxBitmapRefData( bitmapcontext 
); 
1095     return M_BITMAPDATA
->IsOk() ; 
1098 WX_NSImage 
wxBitmap::GetNSImage() const 
1100     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1101     return wxOSXGetNSImageFromCGImage( cgimage
, GetScaleFactor() ); 
1106 #if wxOSX_USE_IPHONE 
1108 WX_UIImage 
wxBitmap::GetUIImage() const 
1110     wxCFRef
< CGImageRef 
> cgimage(CreateCGImage()); 
1111     return wxOSXGetUIImageFromCGImage( cgimage 
); 
1115 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
1117     wxCHECK_MSG( IsOk() && 
1118                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
1119                 (rect
.x
+rect
.width 
<= GetWidth()) && 
1120                 (rect
.y
+rect
.height 
<= GetHeight()), 
1121                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
1124     double scale 
= GetScaleFactor(); 
1125     ret
.CreateScaled( rect
.width
, rect
.height
, GetDepth(), scale 
); 
1126     wxASSERT_MSG( ret
.IsOk(), wxT("GetSubBitmap error") ); 
1128     int destwidth 
= rect
.width
*scale 
; 
1129     int destheight 
= rect
.height
*scale 
; 
1132         unsigned char *sourcedata 
= (unsigned char*) GetRawAccess() ; 
1133         unsigned char *destdata 
= (unsigned char*) ret
.BeginRawAccess() ; 
1134         wxASSERT((sourcedata 
!= NULL
) && (destdata 
!= NULL
)); 
1136         if ( (sourcedata 
!= NULL
) && (destdata 
!= NULL
) ) 
1138             int sourcelinesize 
= GetBitmapData()->GetBytesPerRow() ; 
1139             int destlinesize 
= ret
.GetBitmapData()->GetBytesPerRow() ; 
1140             unsigned char *source 
= sourcedata 
+ int(rect
.x 
* scale 
* 4 + rect
.y 
*scale 
* sourcelinesize
) ; 
1141             unsigned char *dest 
= destdata 
; 
1143             for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1145                 memcpy( dest 
, source 
, destlinesize 
) ; 
1148         ret
.EndRawAccess() ; 
1152     if ( M_BITMAPDATA
->m_bitmapMask 
) 
1154         wxMemoryBuffer maskbuf 
; 
1155         int rowBytes 
= GetBestBytesPerRow( destwidth 
* kMaskBytesPerPixel 
); 
1156         size_t maskbufsize 
= rowBytes 
* destheight 
; 
1158         int sourcelinesize 
= M_BITMAPDATA
->m_bitmapMask
->GetBytesPerRow() ; 
1159         int destlinesize 
= rowBytes 
; 
1161         unsigned char *source 
= (unsigned char *) M_BITMAPDATA
->m_bitmapMask
->GetRawAccess() ; 
1162         unsigned char *destdata 
= (unsigned char * ) maskbuf
.GetWriteBuf( maskbufsize 
) ; 
1163         wxASSERT( (source 
!= NULL
) && (destdata 
!= NULL
) ) ; 
1165         if ( (source 
!= NULL
) && (destdata 
!= NULL
) ) 
1167             source 
+= rect
.x 
* kMaskBytesPerPixel 
+ rect
.y 
* sourcelinesize 
; 
1168             unsigned char *dest 
= destdata 
; 
1170             for (int yy 
= 0; yy 
< destheight
; ++yy
, source 
+= sourcelinesize 
, dest 
+= destlinesize
) 
1172                 memcpy( dest 
, source 
, destlinesize 
) ; 
1175             maskbuf
.UngetWriteBuf( maskbufsize 
) ; 
1177         ret
.SetMask( new wxMask( maskbuf 
, destwidth 
, destheight 
, rowBytes 
) ) ; 
1179     else if ( HasAlpha() ) 
1185 bool wxBitmap::Create(int w
, int h
, int d
) 
1190         d 
= wxDisplayDepth() ; 
1192     m_refData 
= new wxBitmapRefData( w 
, h 
, d 
); 
1194     return M_BITMAPDATA
->IsOk() ; 
1197 bool wxBitmap::Create(int w
, int h
, const wxDC
& dc
) 
1199     double factor 
= dc
.GetContentScaleFactor(); 
1200     return CreateScaled(w
,h
,wxBITMAP_SCREEN_DEPTH
, factor
); 
1203 bool wxBitmap::CreateScaled(int w
, int h
, int d
, double logicalScale
) 
1208         d 
= wxDisplayDepth() ; 
1210     m_refData 
= new wxBitmapRefData( w 
, h 
, d
, logicalScale 
); 
1212     return M_BITMAPDATA
->IsOk() ; 
1215 bool wxBitmap::Create(CGImageRef image
, double scale
) 
1219     m_refData 
= new wxBitmapRefData( image
, scale 
); 
1221     return M_BITMAPDATA
->IsOk() ; 
1224 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
1228     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1232         m_refData 
= new wxBitmapRefData
; 
1234         return handler
->LoadFile(this, filename
, type
, -1, -1); 
1240         wxString fname 
= filename
; 
1242         if  ( type 
== wxBITMAP_TYPE_PNG 
) 
1244             if ( wxOSXGetMainScreenContentScaleFactor() > 1.9 ) 
1246                 wxFileName 
fn(filename
); 
1248                 fn
.SetName(fn
.GetName()+"@2x"); 
1252                     fname 
= fn
.GetFullPath(); 
1258         wxImage 
loadimage(fname
, type
); 
1259         if (loadimage
.IsOk()) 
1261             *this = wxBitmap(loadimage
,-1,scale
); 
1268     wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1273 bool wxBitmap::Create(const void* data
, wxBitmapType type
, int width
, int height
, int depth
) 
1277     m_refData 
= new wxBitmapRefData
; 
1279     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1281     if ( handler 
== NULL 
) 
1283         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1288     return handler
->Create(this, data
, type
, width
, height
, depth
); 
1293 wxBitmap::wxBitmap(const wxImage
& image
, int depth
, double scale
) 
1295     wxCHECK_RET( image
.IsOk(), wxT("invalid image") ); 
1297     // width and height of the device-dependent bitmap 
1298     int width 
= image
.GetWidth(); 
1299     int height 
= image
.GetHeight(); 
1301     wxBitmapRefData
* bitmapRefData
; 
1303     m_refData 
= bitmapRefData 
= new wxBitmapRefData( width
/scale
, height
/scale
, depth
, scale
) ; 
1305     if ( bitmapRefData
->IsOk()) 
1309         bool hasAlpha 
= false ; 
1311         if ( image
.HasMask() ) 
1313             // takes precedence, don't mix with alpha info 
1317             hasAlpha 
= image
.HasAlpha() ; 
1323         unsigned char* destinationstart 
= (unsigned char*) BeginRawAccess() ; 
1324         register unsigned char* data 
= image
.GetData(); 
1325         if ( destinationstart 
!= NULL 
&& data 
!= NULL 
) 
1327             const unsigned char *alpha 
= hasAlpha 
? image
.GetAlpha() : NULL 
; 
1328             for (int y 
= 0; y 
< height
; destinationstart 
+= M_BITMAPDATA
->GetBytesPerRow(), y
++) 
1330                 unsigned char * destination 
= destinationstart
; 
1331                 for (int x 
= 0; x 
< width
; x
++) 
1335                         const unsigned char a 
= *alpha
++; 
1336                         *destination
++ = a 
; 
1338     #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1339                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1340                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1341                         *destination
++ = ((*data
++) * a 
+ 127) / 255 ; 
1343                         *destination
++ = *data
++ ; 
1344                         *destination
++ = *data
++ ; 
1345                         *destination
++ = *data
++ ; 
1350                         *destination
++ = 0xFF ; 
1351                         *destination
++ = *data
++ ; 
1352                         *destination
++ = *data
++ ; 
1353                         *destination
++ = *data
++ ; 
1360         if ( image
.HasMask() ) 
1361             SetMask( new wxMask( *this , wxColour( image
.GetMaskRed() , image
.GetMaskGreen() , image
.GetMaskBlue() ) ) ) ; 
1362     } /* bitmapRefData->IsOk() */ 
1365 wxImage 
wxBitmap::ConvertToImage() const 
1369     wxCHECK_MSG( IsOk(), wxNullImage
, wxT("invalid bitmap") ); 
1371     // create an wxImage object 
1372     int width 
= GetWidth(); 
1373     int height 
= GetHeight(); 
1374     image
.Create( width
, height 
); 
1376     unsigned char *data 
= image
.GetData(); 
1377     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
1379     unsigned char* sourcestart 
= (unsigned char*) GetRawAccess() ; 
1381     bool hasAlpha 
= false ; 
1382     bool hasMask 
= false ; 
1383     int maskBytesPerRow 
= 0 ; 
1384     unsigned char *alpha 
= NULL 
; 
1385     unsigned char *mask 
= NULL 
; 
1393         mask 
= (unsigned char*) GetMask()->GetRawAccess() ; 
1394         maskBytesPerRow 
= GetMask()->GetBytesPerRow() ; 
1400         alpha 
= image
.GetAlpha() ; 
1405     // The following masking algorithm is the same as well in msw/gtk: 
1406     // the colour used as transparent one in wxImage and the one it is 
1407     // replaced with when it actually occurs in the bitmap 
1408     static const int MASK_RED 
= 1; 
1409     static const int MASK_GREEN 
= 2; 
1410     static const int MASK_BLUE 
= 3; 
1411     static const int MASK_BLUE_REPLACEMENT 
= 2; 
1413     for (int yy 
= 0; yy 
< height
; yy
++ , sourcestart 
+= M_BITMAPDATA
->GetBytesPerRow() , mask 
+= maskBytesPerRow 
) 
1415         unsigned char * maskp 
= mask 
; 
1416         unsigned char * source 
= sourcestart
; 
1417         unsigned char a
, r
, g
, b
; 
1420         for (int xx 
= 0; xx 
< width
; xx
++) 
1422             color 
= *((long*) source
) ; 
1423 #ifdef WORDS_BIGENDIAN 
1424             a 
= ((color
&0xFF000000) >> 24) ; 
1425             r 
= ((color
&0x00FF0000) >> 16) ; 
1426             g 
= ((color
&0x0000FF00) >> 8) ; 
1427             b 
= (color
&0x000000FF); 
1429             b 
= ((color
&0xFF000000) >> 24) ; 
1430             g 
= ((color
&0x00FF0000) >> 16) ; 
1431             r 
= ((color
&0x0000FF00) >> 8) ; 
1432             a 
= (color
&0x000000FF); 
1436                 if ( *maskp
++ == 0xFF ) 
1442                 else if ( r 
== MASK_RED 
&& g 
== MASK_GREEN 
&& b 
== MASK_BLUE 
) 
1443                     b 
= MASK_BLUE_REPLACEMENT 
; 
1445             else if ( hasAlpha 
) 
1448 #if wxOSX_USE_PREMULTIPLIED_ALPHA 
1449                 // this must be non-premultiplied data 
1450                 if ( a 
!= 0xFF && a
!= 0 ) 
1460             data
[index 
+ 1] = g 
; 
1461             data
[index 
+ 2] = b 
; 
1469         image
.SetMaskColour( MASK_RED
, MASK_GREEN
, MASK_BLUE 
); 
1474 #endif //wxUSE_IMAGE 
1476 bool wxBitmap::SaveFile( const wxString
& filename
, 
1477     wxBitmapType type
, const wxPalette 
*palette 
) const 
1479     bool success 
= false; 
1480     wxBitmapHandler 
*handler 
= FindHandler(type
); 
1484         success 
= handler
->SaveFile(this, filename
, type
, palette
); 
1489         wxImage image 
= ConvertToImage(); 
1490         success 
= image
.SaveFile(filename
, type
); 
1492         wxLogWarning(wxT("no bitmap handler for type %d defined."), type
); 
1499 int wxBitmap::GetHeight() const 
1501    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1503    return M_BITMAPDATA
->GetHeight(); 
1506 int wxBitmap::GetWidth() const 
1508    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1510    return M_BITMAPDATA
->GetWidth() ; 
1513 double wxBitmap::GetScaleFactor() const 
1515     wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1517     return M_BITMAPDATA
->GetScaleFactor() ; 
1520 int wxBitmap::GetDepth() const 
1522    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
1524    return M_BITMAPDATA
->GetDepth(); 
1527 wxMask 
*wxBitmap::GetMask() const 
1529    wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ); 
1531    return M_BITMAPDATA
->m_bitmapMask
; 
1534 bool wxBitmap::HasAlpha() const 
1536    wxCHECK_MSG( IsOk(), false , wxT("invalid bitmap") ); 
1538    return M_BITMAPDATA
->HasAlpha() ; 
1541 void wxBitmap::SetWidth(int w
) 
1544     M_BITMAPDATA
->SetWidth(w
); 
1547 void wxBitmap::SetHeight(int h
) 
1550     M_BITMAPDATA
->SetHeight(h
); 
1553 void wxBitmap::SetDepth(int d
) 
1556     M_BITMAPDATA
->SetDepth(d
); 
1559 void wxBitmap::SetOk(bool isOk
) 
1562     M_BITMAPDATA
->SetOk(isOk
); 
1566 wxPalette 
*wxBitmap::GetPalette() const 
1568    wxCHECK_MSG( IsOk(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
1570    return &M_BITMAPDATA
->m_bitmapPalette
; 
1573 void wxBitmap::SetPalette(const wxPalette
& palette
) 
1576     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
1578 #endif // wxUSE_PALETTE 
1580 void wxBitmap::SetMask(wxMask 
*mask
) 
1583     // Remove existing mask if there is one. 
1584     delete M_BITMAPDATA
->m_bitmapMask
; 
1586     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
1589 WXHBITMAP 
wxBitmap::GetHBITMAP(WXHBITMAP
* mask
) const 
1593     return WXHBITMAP(M_BITMAPDATA
->GetBitmapContext()); 
1596 // ---------------------------------------------------------------------------- 
1598 // ---------------------------------------------------------------------------- 
1605 wxMask::wxMask(const wxMask 
&tocopy
) : wxObject() 
1609     m_bytesPerRow 
= tocopy
.m_bytesPerRow
; 
1610     m_width 
= tocopy
.m_width
; 
1611     m_height 
= tocopy
.m_height
; 
1613     size_t size 
= m_bytesPerRow 
* m_height
; 
1614     unsigned char* dest 
= (unsigned char*)m_memBuf
.GetWriteBuf( size 
); 
1615     unsigned char* source 
= (unsigned char*)tocopy
.m_memBuf
.GetData(); 
1616     memcpy( dest
, source
, size 
); 
1617     m_memBuf
.UngetWriteBuf( size 
) ; 
1621 // Construct a mask from a bitmap and a colour indicating 
1622 // the transparent area 
1623 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
1626     Create( bitmap
, colour 
); 
1629 // Construct a mask from a mono bitmap (copies the bitmap). 
1630 wxMask::wxMask( const wxBitmap
& bitmap 
) 
1636 // Construct a mask from a mono bitmap (copies the bitmap). 
1638 wxMask::wxMask( const wxMemoryBuffer
& data
, int width 
, int height 
, int bytesPerRow 
) 
1641     Create( data
, width 
, height 
, bytesPerRow 
); 
1648         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1649         m_maskBitmap 
= NULL 
; 
1655     m_width 
= m_height 
= m_bytesPerRow 
= 0 ; 
1656     m_maskBitmap 
= NULL 
; 
1659 void *wxMask::GetRawAccess() const 
1661     return m_memBuf
.GetData() ; 
1664 // The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed 
1665 // bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well 
1667 void wxMask::RealizeNative() 
1671         CGContextRelease( (CGContextRef
) m_maskBitmap 
); 
1672        m_maskBitmap 
= NULL 
; 
1675     CGColorSpaceRef colorspace 
= CGColorSpaceCreateDeviceGray(); 
1676     // from MouseTracking sample : 
1677     // Ironically, due to a bug in CGImageCreateWithMask, you cannot use 
1678     // CGColorSpaceCreateWithName(kCGColorSpaceGenericGray) at this point! 
1680     m_maskBitmap 
= CGBitmapContextCreate((char*) m_memBuf
.GetData(), m_width
, m_height
, 8, m_bytesPerRow
, colorspace
, 
1681         kCGImageAlphaNone 
); 
1682     CGColorSpaceRelease( colorspace 
); 
1683     wxASSERT_MSG( m_maskBitmap 
, wxT("Unable to create CGBitmapContext context") ) ; 
1686 // Create a mask from a mono bitmap (copies the bitmap). 
1688 bool wxMask::Create(const wxMemoryBuffer
& data
,int width 
, int height 
, int bytesPerRow
) 
1693     m_bytesPerRow 
= bytesPerRow 
; 
1695     wxASSERT( data
.GetDataLen() == (size_t)(height 
* bytesPerRow
) ) ; 
1702 // Create a mask from a mono bitmap (copies the bitmap). 
1703 bool wxMask::Create(const wxBitmap
& bitmap
) 
1705     m_width 
= bitmap
.GetWidth() ; 
1706     m_height 
= bitmap
.GetHeight() ; 
1707     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1709     size_t size 
= m_bytesPerRow 
* m_height 
; 
1710     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1711     wxASSERT( destdatabase 
!= NULL 
) ; 
1715         memset( destdatabase 
, 0 , size 
) ; 
1716         unsigned char * srcdata 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1718         for ( int y 
= 0 ; y 
< m_height 
; ++y 
, destdatabase 
+= m_bytesPerRow 
) 
1720             unsigned char *destdata 
= destdatabase 
; 
1721             unsigned char r
, g
, b
; 
1723             for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1730                 if ( ( r 
+ g 
+ b 
) > 0x10 ) 
1731                     *destdata
++ = 0xFF ; 
1733                     *destdata
++ = 0x00 ; 
1738     m_memBuf
.UngetWriteBuf( size 
) ; 
1744 // Create a mask from a bitmap and a colour indicating 
1745 // the transparent area 
1746 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1748     m_width 
= bitmap
.GetWidth() ; 
1749     m_height 
= bitmap
.GetHeight() ; 
1750     m_bytesPerRow 
= GetBestBytesPerRow( m_width 
* kMaskBytesPerPixel 
) ; 
1752     size_t size 
= m_bytesPerRow 
* m_height 
; 
1753     unsigned char * destdatabase 
= (unsigned char*) m_memBuf
.GetWriteBuf( size 
) ; 
1754     wxASSERT( destdatabase 
!= NULL 
) ; 
1755     if ( destdatabase 
!= NULL
) 
1757         memset( destdatabase 
, 0 , size 
) ; 
1758         unsigned char * srcdatabase 
= (unsigned char*) bitmap
.GetRawAccess() ; 
1759         size_t sourceBytesRow 
= bitmap
.GetBitmapData()->GetBytesPerRow(); 
1761         for ( int y 
= 0 ; y 
< m_height 
; ++y 
, srcdatabase
+= sourceBytesRow
, destdatabase 
+= m_bytesPerRow
) 
1763             unsigned char *srcdata 
= srcdatabase 
; 
1764             unsigned char *destdata 
= destdatabase 
; 
1765             unsigned char r
, g
, b
; 
1767             for ( int x 
= 0 ; x 
< m_width 
; ++x 
) 
1774                 if ( colour 
== wxColour( r 
, g 
, b 
) ) 
1775                     *destdata
++ = 0xFF ; 
1777                     *destdata
++ = 0x00 ; 
1781     m_memBuf
.UngetWriteBuf( size 
) ; 
1787 wxBitmap 
wxMask::GetBitmap() const 
1789     wxBitmap 
bitmap(m_width
, m_height
, 1); 
1790     unsigned char* dst 
= static_cast<unsigned char*>(bitmap
.BeginRawAccess()); 
1791     const int dst_stride 
= bitmap
.GetBitmapData()->GetBytesPerRow(); 
1792     const unsigned char* src 
= static_cast<unsigned char*>(GetRawAccess()); 
1793     for (int j 
= 0; j 
< m_height
; j
++, src 
+= m_bytesPerRow
, dst 
+= dst_stride
) 
1795         unsigned char* d 
= dst
; 
1796         for (int i 
= 0; i 
< m_width
; i
++) 
1798             const unsigned char byte 
= src
[i
]; 
1805     bitmap
.EndRawAccess(); 
1809 WXHBITMAP 
wxMask::GetHBITMAP() const 
1811     return m_maskBitmap 
; 
1814 // ---------------------------------------------------------------------------- 
1815 // Standard Handlers 
1816 // ---------------------------------------------------------------------------- 
1818 class WXDLLEXPORT wxBundleResourceHandler
: public wxBitmapHandler
 
1820     DECLARE_ABSTRACT_CLASS(wxBundleResourceHandler
) 
1823     inline wxBundleResourceHandler() 
1827     virtual bool LoadFile(wxBitmap 
*bitmap
, 
1828                           const wxString
& name
, 
1834 IMPLEMENT_ABSTRACT_CLASS(wxBundleResourceHandler
, wxBitmapHandler
); 
1836 class WXDLLEXPORT wxPNGResourceHandler
: public wxBundleResourceHandler
 
1838     DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler
) 
1841     inline wxPNGResourceHandler() 
1843         SetName(wxT("PNG resource")); 
1844         SetExtension("PNG"); 
1845         SetType(wxBITMAP_TYPE_PNG_RESOURCE
); 
1849 IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler
, wxBundleResourceHandler
) 
1851 class WXDLLEXPORT wxJPEGResourceHandler
: public wxBundleResourceHandler
 
1853     DECLARE_DYNAMIC_CLASS(wxJPEGResourceHandler
) 
1856     inline wxJPEGResourceHandler() 
1858         SetName(wxT("JPEG resource")); 
1859         SetExtension("JPEG"); 
1860         SetType(wxBITMAP_TYPE_JPEG_RESOURCE
); 
1864 IMPLEMENT_DYNAMIC_CLASS(wxJPEGResourceHandler
, wxBundleResourceHandler
) 
1866 bool wxBundleResourceHandler::LoadFile(wxBitmap 
*bitmap
, 
1867                                      const wxString
& name
, 
1868                                      wxBitmapType 
WXUNUSED(type
), 
1869                                      int WXUNUSED(desiredWidth
), 
1870                                      int WXUNUSED(desiredHeight
)) 
1872     wxString ext 
= GetExtension().Lower(); 
1873     wxCFStringRef 
resname(name
); 
1874     wxCFStringRef 
resname2x(name
+"@2x"); 
1875     wxCFStringRef 
restype(ext
); 
1878     wxCFRef
<CFURLRef
> imageURL
; 
1880     if ( wxOSXGetMainScreenContentScaleFactor() > 1.9 ) 
1882         imageURL
.reset(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname2x
, restype
, NULL
)); 
1886     if ( imageURL
.get() == NULL 
) 
1888         imageURL
.reset(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname
, restype
, NULL
)); 
1892     if ( imageURL
.get() != NULL 
) 
1894         // Create the data provider object 
1895         wxCFRef
<CGDataProviderRef
> provider(CGDataProviderCreateWithURL (imageURL
) ); 
1896         CGImageRef image 
= NULL
; 
1898         if ( ext 
== "jpeg" ) 
1899             image 
= CGImageCreateWithJPEGDataProvider (provider
, NULL
, true, 
1900                                                    kCGRenderingIntentDefault
); 
1901         else if ( ext 
== "png" ) 
1902             image 
= CGImageCreateWithPNGDataProvider (provider
, NULL
, true, 
1903                                                        kCGRenderingIntentDefault
); 
1904         if ( image 
!= NULL 
) 
1906             bitmap
->Create(image
,scale
); 
1907             CGImageRelease(image
); 
1915 wxBitmap 
wxBitmapHelpers::NewFromPNGData(const void* data
, size_t size
) 
1917     wxCFRef
<CGDataProviderRef
> 
1918         provider(CGDataProviderCreateWithData(NULL
, data
, size
, NULL
) ); 
1920         image(CGImageCreateWithPNGDataProvider(provider
, NULL
, true, 
1921                                                 kCGRenderingIntentDefault
)); 
1923     return wxBitmap(image
); 
1926 void wxBitmap::InitStandardHandlers() 
1928 #if wxOSX_USE_COCOA_OR_CARBON 
1929     AddHandler( new wxICONResourceHandler 
) ; 
1931     AddHandler( new wxPNGResourceHandler 
); 
1932     AddHandler( new wxJPEGResourceHandler 
); 
1935 // ---------------------------------------------------------------------------- 
1936 // raw bitmap access support 
1937 // ---------------------------------------------------------------------------- 
1939 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int WXUNUSED(bpp
)) 
1942         // no bitmap, no data (raw or otherwise) 
1945     data
.m_width 
= GetWidth() ; 
1946     data
.m_height 
= GetHeight() ; 
1947     data
.m_stride 
= GetBitmapData()->GetBytesPerRow() ; 
1949     return BeginRawAccess() ; 
1952 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(dataBase
)) 
1957 void wxBitmap::UseAlpha() 
1959     // remember that we are using alpha channel: 
1960     // we'll need to create a proper mask in UngetRawData() 
1961     M_BITMAPDATA
->UseAlpha( true );