1 ///////////////////////////////////////////////////////////////////////////// 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "bitmap.h" 
  18 #include "wx/bitmap.h" 
  22 #include "wx/xpmdecod.h" 
  24 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  25 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  26 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject 
)  
  29     #include <ApplicationServices/ApplicationServices.h> 
  31     #include <PictUtils.h> 
  34 #include "wx/mac/uma.h" 
  36 CTabHandle 
wxMacCreateColorTable( int numColors 
) 
  38     CTabHandle newColors
; /* Handle to the new color table */ 
  40     /* Allocate memory for the color table */ 
  41     newColors 
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) + 
  42     sizeof (ColorSpec
) * (numColors 
- 1) ); 
  45         /* Initialize the fields */ 
  46         (**newColors
).ctSeed 
= GetCTSeed(); 
  47         (**newColors
).ctFlags 
= 0; 
  48         (**newColors
).ctSize 
= numColors 
- 1; 
  49         /* Initialize the table of colors */ 
  54 void wxMacDestroyColorTable( CTabHandle colors 
)  
  56     DisposeHandle( (Handle
) colors 
) ; 
  59 void wxMacSetColorTableEntry( CTabHandle newColors 
, int index 
, int red 
, int green 
,  int blue 
) 
  61     (**newColors
).ctTable
[index
].value 
= index
; 
  62     (**newColors
).ctTable
[index
].rgb
.red 
= red 
; // someRedValue; 
  63     (**newColors
).ctTable
[index
].rgb
.green 
= green 
; // someGreenValue; 
  64     (**newColors
).ctTable
[index
].rgb
.blue 
= blue 
; // someBlueValue; 
  67 GWorldPtr 
wxMacCreateGWorld( int width 
, int height 
, int depth 
) 
  71     Rect rect 
= { 0 , 0 , height 
, width 
} ; 
  75         depth 
= wxDisplayDepth() ;      
  78     err 
= NewGWorld( &port 
, depth 
, &rect 
, NULL 
, NULL 
, 0 ) ; 
  86 void wxMacDestroyGWorld( GWorldPtr gw 
) 
  92 #define kDefaultRes 0x00480000 /* Default resolution is 72 DPI; Fixed type */ 
  94 OSErr 
SetupCIconHandlePixMap( CIconHandle icon 
, short depth 
, Rect  
*bounds 
, CTabHandle colors 
) 
  96     CTabHandle newColors
;       /* Color table used for the off-screen PixMap */ 
  97     Ptr        offBaseAddr
;     /* Pointer to the off-screen pixel image */ 
  98     OSErr      error
;           /* Returns error code */ 
  99     short      bytesPerRow
;     /* Number of bytes per row in the PixMap */ 
 106     bytesPerRow 
= ((depth 
* (bounds
->right 
- bounds
->left
) + 31) / 32) * 4; 
 108    /* Clone the clut if indexed color; allocate a dummy clut if direct color*/ 
 112         error 
= HandToHand((Handle 
*) &newColors
); 
 116         newColors 
= (CTabHandle
) NewHandle(sizeof(ColorTable
) - 
 122         /* Allocate pixel image; long integer multiplication avoids overflow */ 
 123         (**icon
).iconData 
= NewHandle((unsigned long) bytesPerRow 
* (bounds
->bottom 
- 
 125         if ((**icon
).iconData 
!= nil
) 
 127             /* Initialize fields common to indexed and direct PixMaps */ 
 128             (**icon
).iconPMap
.baseAddr 
= 0;  /* Point to image */ 
 129             (**icon
).iconPMap
.rowBytes 
= bytesPerRow 
| /* MSB set for PixMap */ 
 131             (**icon
).iconPMap
.bounds 
= *bounds
;        /* Use given bounds */ 
 132             (**icon
).iconPMap
.pmVersion 
= 0;           /* No special stuff */ 
 133             (**icon
).iconPMap
.packType 
= 0;            /* Default PICT pack */ 
 134             (**icon
).iconPMap
.packSize 
= 0;            /* Always zero in mem */ 
 135             (**icon
).iconPMap
.hRes 
= kDefaultRes
;      /* 72 DPI default res */ 
 136             (**icon
).iconPMap
.vRes 
= kDefaultRes
;      /* 72 DPI default res */ 
 137             (**icon
).iconPMap
.pixelSize 
= depth
;       /* Set # bits/pixel */ 
 139             /* Initialize fields specific to indexed and direct PixMaps */ 
 142                 /* PixMap is indexed */ 
 143                 (**icon
).iconPMap
.pixelType 
= 0;       /* Indicates indexed */ 
 144                 (**icon
).iconPMap
.cmpCount 
= 1;        /* Have 1 component */ 
 145                 (**icon
).iconPMap
.cmpSize 
= depth
;     /* Component size=depth */ 
 146                 (**icon
).iconPMap
.pmTable 
= newColors
; /* Handle to CLUT */ 
 150                 /* PixMap is direct */ 
 151                 (**icon
).iconPMap
.pixelType 
= RGBDirect
; /* Indicates direct */ 
 152                 (**icon
).iconPMap
.cmpCount 
= 3;          /* Have 3 components */ 
 154                     (**icon
).iconPMap
.cmpSize 
= 5;       /* 5 bits/component */ 
 156                     (**icon
).iconPMap
.cmpSize 
= 8;       /* 8 bits/component */ 
 157                 (**newColors
).ctSeed 
= 3 * (**icon
).iconPMap
.cmpSize
; 
 158                 (**newColors
).ctFlags 
= 0; 
 159                 (**newColors
).ctSize 
= 0; 
 160                 (**icon
).iconPMap
.pmTable 
= newColors
; 
 169     /* If no errors occured, return a handle to the new off-screen PixMap */ 
 172         if (newColors 
!= nil
) 
 173             DisposeCTable(newColors
); 
 176     /* Return the error code */ 
 180 CIconHandle 
wxMacCreateCIcon(GWorldPtr image 
, GWorldPtr mask 
, short dstDepth 
, short iconSize  
) 
 185     GetGWorld(&saveWorld
,&saveHandle
);      // save Graphics env state 
 186     SetGWorld(image
,nil
); 
 188     Rect frame 
= { 0 , 0 , iconSize 
, iconSize 
} ; 
 189     Rect imageBounds 
= frame 
; 
 190     GetPortBounds( image 
, &imageBounds 
) ; 
 192     int bwSize 
= iconSize 
/ 8 * iconSize 
; 
 193     CIconHandle icon 
= (CIconHandle
) NewHandleClear( sizeof ( CIcon 
) + 2 * bwSize
) ; 
 194     HLock((Handle
)icon
) ; 
 195     SetupCIconHandlePixMap( icon 
, dstDepth 
, &frame
,GetCTable(dstDepth
)) ; 
 196     HLock( (**icon
).iconData 
) ; 
 197     (**icon
).iconPMap
.baseAddr 
= *(**icon
).iconData 
; 
 199     LockPixels(GetGWorldPixMap(image
)); 
 201     CopyBits(GetPortBitMapForCopyBits(image
), 
 202                 (BitMapPtr
)&((**icon
).iconPMap
), 
 205                 srcCopy 
| ditherCopy
, nil
); 
 208     UnlockPixels(GetGWorldPixMap(image
)); 
 209     HUnlock( (**icon
).iconData 
) ; 
 211     (**icon
).iconMask
.rowBytes 
= iconSize 
/ 8 ; 
 212     (**icon
).iconMask
.bounds 
= frame 
; 
 214     (**icon
).iconBMap
.rowBytes 
= iconSize 
/ 8 ; 
 215     (**icon
).iconBMap
.bounds 
= frame 
; 
 216     (**icon
).iconMask
.baseAddr 
= (char*) &(**icon
).iconMaskData 
; 
 217     (**icon
).iconBMap
.baseAddr 
= (char*) &(**icon
).iconMaskData 
+ bwSize 
; 
 222         GetPortBounds( image 
, &r 
) ; 
 223       LockPixels(GetGWorldPixMap(mask
) ) ; 
 224       CopyBits(GetPortBitMapForCopyBits(mask
) , 
 225           &(**icon
).iconBMap 
, &r 
, &r
, srcCopy 
, nil 
) ; 
 226       CopyBits(GetPortBitMapForCopyBits(mask
) , 
 227           &(**icon
).iconMask 
, &r 
, &r
, srcCopy 
, nil 
) ; 
 228       UnlockPixels(GetGWorldPixMap( mask 
) ) ; 
 233         GetPortBounds( image 
, &r 
) ; 
 234         LockPixels(GetGWorldPixMap(image
)); 
 235       CopyBits(GetPortBitMapForCopyBits(image
) , 
 236           &(**icon
).iconBMap 
, &r 
, &r
, srcCopy 
, nil 
) ; 
 237       CopyBits(GetPortBitMapForCopyBits(image
) , 
 238           &(**icon
).iconMask 
, &r 
, &r
, srcCopy 
, nil 
) ; 
 239         UnlockPixels(GetGWorldPixMap(image
)); 
 242     (**icon
).iconMask
.baseAddr 
= NULL 
; 
 243     (**icon
).iconBMap
.baseAddr 
= NULL 
; 
 244     (**icon
).iconPMap
.baseAddr 
= NULL 
; 
 245     HUnlock((Handle
)icon
) ; 
 246     SetGWorld(saveWorld
,saveHandle
); 
 251 PicHandle 
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
) 
 258   RGBColor       white 
= { 0xffff ,0xffff , 0xffff } ; 
 259   RGBColor       black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 261   GetGWorld( &origPort 
, &origDev 
) ; 
 263   RgnHandle clipRgn 
= NULL 
; 
 268     LockPixels( GetGWorldPixMap( mask 
) ) ; 
 269     BitMapToRegion( clipRgn 
, (BitMap
*) *GetGWorldPixMap( mask 
) ) ; 
 270     UnlockPixels( GetGWorldPixMap( mask 
) ) ; 
 273   SetGWorld( wp 
, NULL 
) ; 
 276     GetRegionBounds( clipRgn 
, &portRect 
) ;    
 278         GetPortBounds( wp 
, &portRect 
) ; 
 279   pict 
= OpenPicture(&portRect
);    
 282     RGBForeColor( &black 
) ; 
 283     RGBBackColor( &white 
) ; 
 288     LockPixels( GetGWorldPixMap( wp 
) ) ; 
 289     CopyBits(GetPortBitMapForCopyBits(wp
),           
 290             GetPortBitMapForCopyBits(wp
),        
 294     UnlockPixels( GetGWorldPixMap( wp 
) ) ; 
 297   SetGWorld( origPort 
, origDev 
) ; 
 299         DisposeRgn( clipRgn 
) ; 
 303 void wxMacCreateBitmapButton( ControlButtonContentInfo
*info 
, const wxBitmap
& bitmap 
, int forceType 
)  
 305     memset( info 
, 0 , sizeof(ControlButtonContentInfo
) ) ; 
 308         wxBitmapRefData 
* bmap 
= (wxBitmapRefData
*) ( bitmap
.GetRefData()) ; 
 312         if ( bmap
->m_bitmapType 
== kMacBitmapTypePict 
) 
 314             info
->contentType 
= kControlContentPictHandle 
; 
 315             info
->u
.picture 
= MAC_WXHMETAFILE(bmap
->m_hPict
) ; 
 317         else if ( bmap
->m_bitmapType 
== kMacBitmapTypeGrafWorld 
) 
 319             if ( (forceType 
== kControlContentCIconHandle 
|| ( bmap
->m_width 
== bmap
->m_height 
&& forceType 
!= kControlContentPictHandle 
) ) && ((bmap
->m_width 
& 0x3) == 0) ) 
 321                 info
->contentType 
= kControlContentCIconHandle 
; 
 322                 if ( bitmap
.GetMask() ) 
 324                     info
->u
.cIconHandle 
= wxMacCreateCIcon( MAC_WXHBITMAP(bmap
->m_hBitmap
) , MAC_WXHBITMAP(bitmap
.GetMask()->GetMaskBitmap()) , 
 325                                                            8 , bmap
->m_width 
) ; 
 329                     info
->u
.cIconHandle 
= wxMacCreateCIcon( MAC_WXHBITMAP(bmap
->m_hBitmap
) , NULL 
, 
 330                                                            8 , bmap
->m_width 
) ; 
 335                 info
->contentType 
= kControlContentPictHandle 
; 
 336                 if ( bitmap
.GetMask() ) 
 338                                     info
->u
.picture 
= wxMacCreatePict( MAC_WXHBITMAP(bmap
->m_hBitmap
) , MAC_WXHBITMAP(bitmap
.GetMask()->GetMaskBitmap() ) ) ; 
 342                                     info
->u
.picture 
= wxMacCreatePict( MAC_WXHBITMAP(bmap
->m_hBitmap
) , NULL 
) ; 
 346                 else if ( bmap
->m_bitmapType 
== kMacBitmapTypeIcon 
) 
 348                 info
->contentType 
= kControlContentCIconHandle 
; 
 349                 info
->u
.cIconHandle 
= MAC_WXHICON(bmap
->m_hIcon
) ; 
 354 wxBitmapRefData::wxBitmapRefData() 
 366     m_bitmapType 
= kMacBitmapTypeUnknownType 
; 
 369 // TODO move this to a public function of Bitmap Ref 
 370 static void DisposeBitmapRefData(wxBitmapRefData 
*data
) 
 372     switch (data
->m_bitmapType
) 
 374         case kMacBitmapTypePict 
: 
 378                     KillPicture( MAC_WXHMETAFILE( data
->m_hPict 
) ) ; 
 379                     data
->m_hPict 
= NULL 
; 
 383         case kMacBitmapTypeGrafWorld 
: 
 385                 if ( data
->m_hBitmap 
) 
 387                     wxMacDestroyGWorld( MAC_WXHBITMAP(data
->m_hBitmap
) ) ; 
 388                     data
->m_hBitmap 
= NULL 
; 
 392         case kMacBitmapTypeIcon 
: 
 395                 DisposeCIcon( MAC_WXHICON(data
->m_hIcon
) ) ; 
 396                 data
->m_hIcon 
= NULL 
; 
 404   if (data
->m_bitmapMask
) 
 406     delete data
->m_bitmapMask
; 
 407     data
->m_bitmapMask 
= NULL
; 
 411 wxBitmapRefData::~wxBitmapRefData() 
 413   DisposeBitmapRefData( this ) ; 
 416 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 427 wxBitmap::~wxBitmap() 
 431 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 433     m_refData 
= new wxBitmapRefData
; 
 435     M_BITMAPDATA
->m_width 
= the_width 
; 
 436     M_BITMAPDATA
->m_height 
= the_height 
; 
 437     M_BITMAPDATA
->m_depth 
= no_bits 
; 
 438     M_BITMAPDATA
->m_numColors 
= 0; 
 441         M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 442         MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
) = wxMacCreateGWorld( the_width 
, the_height 
, no_bits 
) ; 
 443         M_BITMAPDATA
->m_ok 
= (MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
) != NULL 
) ; 
 446         GDHandle    origDevice 
; 
 448         GetGWorld( &origPort 
, &origDevice 
) ; 
 449         SetGWorld( MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
) , NULL 
) ; 
 450         LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
) ) ) ; 
 452         // bits is a char array 
 454         unsigned char* linestart 
= (unsigned char*) bits 
; 
 455         int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 456         if ( the_width 
% (sizeof(unsigned char) * 8) ) { 
 457             linesize 
+= sizeof(unsigned char); 
 460         RGBColor colors
[2] = {  
 461             { 0xFFFF , 0xFFFF , 0xFFFF } , 
 465         for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize 
) 
 467             for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 471                 int mask 
= 1 << bit 
; 
 472                 if ( linestart
[index
] & mask 
) 
 474                     SetCPixel( x 
, y 
, &colors
[1] ) ; 
 478                     SetCPixel( x 
, y 
, &colors
[0] ) ; 
 482         UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
) ) ) ; 
 484         SetGWorld( origPort 
, origDevice 
) ; 
 488         wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 492 wxBitmap::wxBitmap(int w
, int h
, int d
) 
 494     (void)Create(w
, h
, d
); 
 497 wxBitmap::wxBitmap(void *data
, wxBitmapType type
, int width
, int height
, int depth
) 
 499     (void) Create(data
, type
, width
, height
, depth
); 
 502 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
) 
 504     LoadFile(filename
, type
); 
 507 bool wxBitmap::CreateFromXpm(const char **bits
) 
 509     wxCHECK_MSG( bits 
!= NULL
, FALSE
, wxT("invalid bitmap data") ) 
 510     wxXPMDecoder decoder
; 
 511     wxImage img 
= decoder
.ReadData(bits
); 
 512     wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") )     
 513     *this = wxBitmap(img
);    
 517 wxBitmap::wxBitmap(const char **bits
) 
 519     (void) CreateFromXpm(bits
); 
 522 wxBitmap::wxBitmap(char **bits
) 
 524     (void) CreateFromXpm((const char **)bits
); 
 527 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
 530                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 531                 (rect
.x
+rect
.width 
<= GetWidth()) && 
 532                 (rect
.y
+rect
.height 
<= GetHeight()), 
 533                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 536    wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
 537    wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 542    GetGWorld( &origPort
, &origDevice 
); 
 544    // Update the subbitmaps reference data 
 545    wxBitmapRefData 
*ref 
= (wxBitmapRefData 
*)ret
.GetRefData(); 
 547    ref
->m_numColors     
= M_BITMAPDATA
->m_numColors
; 
 548    ref
->m_bitmapPalette 
= M_BITMAPDATA
->m_bitmapPalette
; 
 549    ref
->m_bitmapType    
= M_BITMAPDATA
->m_bitmapType
; 
 551    // Copy sub region of this bitmap 
 552    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) 
 554        printf("GetSubBitmap:  Copy a region of a Pict structure - TODO\n"); 
 556    else if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypeGrafWorld
) 
 561            GWorldPtr submask
, mask
; 
 564            mask 
= (GWorldPtr
) GetMask()->GetMaskBitmap(); 
 565            submask 
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1); 
 566            LockPixels(GetGWorldPixMap(mask
)); 
 567            LockPixels(GetGWorldPixMap(submask
)); 
 569            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 571                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 573                    SetGWorld(mask
, NULL
); 
 574                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 575                    SetGWorld(submask
, NULL
); 
 576                    SetCPixel(xx
,yy
, &color
); 
 579            UnlockPixels(GetGWorldPixMap(mask
)); 
 580            UnlockPixels(GetGWorldPixMap(submask
)); 
 581            ref
->m_bitmapMask 
= new wxMask
; 
 582            ref
->m_bitmapMask
->SetMaskBitmap(submask
); 
 588            GWorldPtr subbitmap
, bitmap
; 
 591            bitmap 
= (GWorldPtr
) GetHBITMAP(); 
 592            subbitmap 
= (GWorldPtr
) ref
->m_hBitmap 
; 
 593            LockPixels(GetGWorldPixMap(bitmap
)); 
 594            LockPixels(GetGWorldPixMap(subbitmap
)); 
 596            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 598                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 600                    SetGWorld(bitmap
, NULL
); 
 601                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 602                    SetGWorld(subbitmap
, NULL
); 
 603                    SetCPixel(xx
, yy
, &color
); 
 606            UnlockPixels(GetGWorldPixMap(bitmap
)); 
 607            UnlockPixels(GetGWorldPixMap(subbitmap
)); 
 610    SetGWorld( origPort
, origDevice 
); 
 615 bool wxBitmap::Create(int w
, int h
, int d
) 
 619     m_refData 
= new wxBitmapRefData
; 
 621     M_BITMAPDATA
->m_width 
= w
; 
 622     M_BITMAPDATA
->m_height 
= h
; 
 623     M_BITMAPDATA
->m_depth 
= d
; 
 625     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 626     M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( w 
, h 
, d 
) ; 
 627     M_BITMAPDATA
->m_ok 
= ( M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 628     return M_BITMAPDATA
->m_ok
; 
 631 int wxBitmap::GetBitmapType() const 
 633    wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") ); 
 635    return M_BITMAPDATA
->m_bitmapType
; 
 638 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
) 
 640     DisposeBitmapRefData( M_BITMAPDATA 
) ; 
 642     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 643     M_BITMAPDATA
->m_hBitmap 
= bmp 
; 
 644       M_BITMAPDATA
->m_ok 
= ( M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 647 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
 651     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 655         m_refData 
= new wxBitmapRefData
; 
 657         return handler
->LoadFile(this, filename
, type
, -1, -1); 
 661         wxImage 
loadimage(filename
, type
); 
 662         if (loadimage
.Ok()) { 
 667     wxLogWarning("no bitmap handler for type %d defined.", type
); 
 671 bool wxBitmap::Create(void *data
, wxBitmapType type
, int width
, int height
, int depth
) 
 675     m_refData 
= new wxBitmapRefData
; 
 677     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 679     if ( handler 
== NULL 
) { 
 680         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 685     return handler
->Create(this, data
, type
, width
, height
, depth
); 
 688 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
 690     wxCHECK_RET( image
.Ok(), wxT("invalid image") ) 
 691     wxCHECK_RET( depth 
== -1, wxT("invalid bitmap depth") ) 
 693     m_refData 
= new wxBitmapRefData(); 
 695     // width and height of the device-dependent bitmap 
 696     int width 
= image
.GetWidth(); 
 697     int height 
= image
.GetHeight(); 
 701     Create( width 
, height 
, 32 ) ; 
 704     GDHandle origDevice 
; 
 706     PixMapHandle pixMap 
= GetGWorldPixMap((GWorldPtr
)GetHBITMAP()) ; 
 707     LockPixels( pixMap 
); 
 709     GetGWorld( &origPort 
, &origDevice 
) ; 
 710     SetGWorld( (GWorldPtr
) GetHBITMAP() , NULL 
) ; 
 713     register unsigned char* data 
= image
.GetData(); 
 714     char* destinationBase 
= GetPixBaseAddr( pixMap 
); 
 715     register unsigned char* destination 
= (unsigned char*) destinationBase 
; 
 716     for (int y 
= 0; y 
< height
; y
++) 
 718         for (int x 
= 0; x 
< width
; x
++) 
 721             *destination
++ = *data
++ ;               
 722             *destination
++ = *data
++ ;               
 723             *destination
++ = *data
++ ;               
 725         destinationBase 
+= ((**pixMap
).rowBytes 
& 0x7fff);   
 726         destination 
= (unsigned char*) destinationBase 
;     
 728     if ( image
.HasMask() ) 
 730       data 
= image
.GetData();  
 732       wxColour 
maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue()); 
 733       RGBColor white 
= { 0xffff, 0xffff, 0xffff }; 
 734       RGBColor black 
= { 0     , 0     , 0      }; 
 735       wxBitmap maskBitmap 
; 
 737       maskBitmap
.Create( width
, height
, 1); 
 738       LockPixels( GetGWorldPixMap( (GWorldPtr
) maskBitmap
.GetHBITMAP()) ); 
 739       SetGWorld( (GWorldPtr
) maskBitmap
.GetHBITMAP(), NULL
); 
 741       for (int y 
= 0; y 
< height
; y
++) 
 743           for (int x 
= 0; x 
< width
; x
++) 
 745               if ( data
[0] == image
.GetMaskRed() && data
[1] == image
.GetMaskGreen() && data
[2] == image
.GetMaskBlue() ) 
 747                 SetCPixel(x
,y
, &white
); 
 750                       SetCPixel(x
,y
, &black
); 
 755       SetGWorld( (GWorldPtr
) GetHBITMAP(), NULL
); 
 756       SetMask(new wxMask( maskBitmap 
)); 
 757       UnlockPixels( GetGWorldPixMap( (GWorldPtr
) maskBitmap
.GetHBITMAP()) ); 
 760     UnlockPixels( GetGWorldPixMap( (GWorldPtr
) GetHBITMAP()) ); 
 761     SetGWorld( origPort
, origDevice 
); 
 764 wxImage 
wxBitmap::ConvertToImage() const 
 768     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 770     // create an wxImage object 
 771     int width 
= GetWidth(); 
 772     int height 
= GetHeight(); 
 773     image
.Create( width
, height 
); 
 775     unsigned char *data 
= image
.GetData(); 
 777     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
 781     RgnHandle maskRgn 
= NULL 
; 
 782     GWorldPtr tempPort 
= NULL 
; 
 785     // background color set to RGB(16,16,16) in consistent with wxGTK 
 786     unsigned char mask_r
=16, mask_g
=16, mask_b
=16; 
 788     wxMask  
*mask 
= GetMask(); 
 790     GetGWorld( &origPort
, &origDevice 
); 
 791     if ( GetBitmapType() != kMacBitmapTypeGrafWorld 
) 
 793         tempPort 
= wxMacCreateGWorld( width 
, height 
, -1) ; 
 797         tempPort 
=  (GWorldPtr
) GetHBITMAP() ; 
 799         LockPixels(GetGWorldPixMap(tempPort
)); 
 800         SetGWorld( tempPort
, NULL
); 
 801         if ( GetBitmapType() == kMacBitmapTypePict 
|| GetBitmapType() == kMacBitmapTypeIcon 
) 
 803         Rect bitmaprect 
= { 0 , 0 , height
, width 
}; 
 804         if ( GetBitmapType() == kMacBitmapTypeIcon 
) 
 806                 ::PlotCIconHandle( &bitmaprect 
, atNone 
, ttNone 
, MAC_WXHICON(GetHICON()) ) ; 
 808                 BitMapToRegion( maskRgn 
, &(**(MAC_WXHICON(GetHICON()))).iconMask 
) ;  
 811                 ::DrawPicture( (PicHandle
) GetPict(), &bitmaprect 
) ; 
 813     // Copy data into image 
 815     for (int yy 
= 0; yy 
< height
; yy
++) 
 817         for (int xx 
= 0; xx 
< width
; xx
++) 
 819             GetCPixel(xx
,yy
, &color
); 
 820             r 
= ((color
.red 
) >> 8); 
 821             g 
= ((color
.green 
) >> 8); 
 822             b 
= ((color
.blue 
) >> 8); 
 831                 if ( !PtInRgn( pt 
, maskRgn 
) ) 
 833                     data
[index    
] = mask_r
; 
 834                     data
[index 
+ 1] = mask_g
; 
 835                     data
[index 
+ 2] = mask_b
; 
 842                         if (mask
->PointMasked(xx
,yy
)) 
 844                             data
[index    
] = mask_r
; 
 845                             data
[index 
+ 1] = mask_g
; 
 846                             data
[index 
+ 2] = mask_b
; 
 853     if (mask 
|| maskRgn 
) 
 855         image
.SetMaskColour( mask_r
, mask_g
, mask_b 
); 
 856         image
.SetMask( true ); 
 860     UnlockPixels(GetGWorldPixMap( tempPort 
)); 
 861     SetGWorld(origPort
, origDevice
); 
 862     if ( GetBitmapType() != kMacBitmapTypeGrafWorld 
) 
 864         wxMacDestroyGWorld( tempPort 
) ; 
 868         DisposeRgn( maskRgn 
) ; 
 875 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, 
 876                         const wxPalette 
*palette
) const 
 878     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 882         return handler
->SaveFile(this, filename
, type
, palette
); 
 886         wxImage image 
= ConvertToImage(); 
 888         return image
.SaveFile(filename
, type
); 
 891     wxLogWarning("no bitmap handler for type %d defined.", type
); 
 895 bool wxBitmap::Ok() const 
 897    return (M_BITMAPDATA 
&& M_BITMAPDATA
->m_ok
); 
 900 int wxBitmap::GetHeight() const 
 902    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 904    return M_BITMAPDATA
->m_height
; 
 907 int wxBitmap::GetWidth() const 
 909    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 911    return M_BITMAPDATA
->m_width
; 
 914 int wxBitmap::GetDepth() const 
 916    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 918    return M_BITMAPDATA
->m_depth
; 
 921 int wxBitmap::GetQuality() const 
 923    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 925    return M_BITMAPDATA
->m_quality
; 
 928 wxMask 
*wxBitmap::GetMask() const 
 930    wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 932    return M_BITMAPDATA
->m_bitmapMask
; 
 935 void wxBitmap::SetWidth(int w
) 
 938         m_refData 
= new wxBitmapRefData
; 
 940     M_BITMAPDATA
->m_width 
= w
; 
 943 void wxBitmap::SetHeight(int h
) 
 946         m_refData 
= new wxBitmapRefData
; 
 948     M_BITMAPDATA
->m_height 
= h
; 
 951 void wxBitmap::SetDepth(int d
) 
 954         m_refData 
= new wxBitmapRefData
; 
 956     M_BITMAPDATA
->m_depth 
= d
; 
 959 void wxBitmap::SetQuality(int q
) 
 962         m_refData 
= new wxBitmapRefData
; 
 964     M_BITMAPDATA
->m_quality 
= q
; 
 967 void wxBitmap::SetOk(bool isOk
) 
 970         m_refData 
= new wxBitmapRefData
; 
 972     M_BITMAPDATA
->m_ok 
= isOk
; 
 975 wxPalette 
*wxBitmap::GetPalette() const 
 977    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
 979    return &M_BITMAPDATA
->m_bitmapPalette
; 
 982 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 985         m_refData 
= new wxBitmapRefData
; 
 987     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
 990 void wxBitmap::SetMask(wxMask 
*mask
) 
 993         m_refData 
= new wxBitmapRefData
; 
 995     // Remove existing mask if there is one. 
 996     if (M_BITMAPDATA
->m_bitmapMask
) 
 997         delete M_BITMAPDATA
->m_bitmapMask
; 
 999     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
1002 WXHBITMAP 
wxBitmap::GetHBITMAP() const 
1004    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
1006    return MAC_WXHBITMAP(M_BITMAPDATA
->m_hBitmap
); 
1009 WXHMETAFILE 
wxBitmap::GetPict() const 
1011    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
1013    PicHandle picture
;       // This is the returned picture 
1015    // If bitmap already in Pict format return pointer 
1016    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) { 
1017        return M_BITMAPDATA
->m_hPict
; 
1019    else if(M_BITMAPDATA
->m_bitmapType 
!= kMacBitmapTypeGrafWorld
) { 
1024    RGBColor  gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
1025    RGBColor  white 
= { 0xffff ,0xffff , 0xffff } ; 
1026    RGBColor  black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
1032    GetPortBounds(  (GWorldPtr
) GetHBITMAP() , &portRect 
) ; 
1033    int width 
= portRect
.right 
- portRect
.left 
; 
1034    int height 
= portRect
.bottom 
- portRect
.top 
; 
1036    LockPixels( GetGWorldPixMap(  (GWorldPtr
) GetHBITMAP() ) ) ; 
1037    GetGWorld( &origPort 
, &origDev 
) ; 
1041    SetGWorld(  (GWorldPtr
) GetHBITMAP() , NULL 
) ; 
1043    picture 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
1051        RGBColor trans 
= white
; 
1053        RGBBackColor( &gray 
); 
1054        EraseRect( &portRect 
); 
1055        RGBColor trans 
= gray
; 
1057        RGBForeColor( &black 
) ; 
1058        RGBBackColor( &white 
) ; 
1059        PenMode(transparent
); 
1061        for ( int y 
= 0 ; y 
< height 
; ++y 
) 
1063            for( int x 
= 0 ; x 
< width 
; ++x 
) 
1065                if ( !mask
->PointMasked(x
,y
) ) 
1069                    GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
1070                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
1073                    // With transparency this sets a blank pixel 
1074                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &trans
); 
1081        RGBBackColor( &gray 
) ; 
1082        EraseRect(&portRect
); 
1083        RGBForeColor( &black 
) ; 
1084        RGBBackColor( &white 
) ; 
1086        CopyBits(GetPortBitMapForCopyBits( (GWorldPtr
) GetHBITMAP()),  
1087                 // src PixMap - we copy image over itself - 
1088                 GetPortBitMapForCopyBits( (GWorldPtr
) GetHBITMAP()), 
1089                 //  dst PixMap - no drawing occurs 
1090                 &portRect
,    // srcRect - it will be recorded and compressed - 
1091                 &portRect
,    // dstRect - into the picture that is open - 
1092                 srcCopy
,NULL
); // copyMode and no clip region 
1094    ClosePicture();                  // We are done recording the picture 
1095    UnlockPixels( GetGWorldPixMap(  (GWorldPtr
) GetHBITMAP() ) ) ; 
1096    SetGWorld( origPort 
, origDev 
) ; 
1098    return picture
;                  // return our groovy pict handle 
1106     : m_maskBitmap(NULL
) 
1110 // Construct a mask from a bitmap and a colour indicating 
1111 // the transparent area 
1112 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1113     : m_maskBitmap(NULL
) 
1115     Create(bitmap
, colour
); 
1118 // Construct a mask from a bitmap and a palette index indicating 
1119 // the transparent area 
1120 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
1121     : m_maskBitmap(NULL
) 
1123     Create(bitmap
, paletteIndex
); 
1126 // Construct a mask from a mono bitmap (copies the bitmap). 
1127 wxMask::wxMask(const wxBitmap
& bitmap
) 
1128     : m_maskBitmap(NULL
) 
1137         wxMacDestroyGWorld(  (GWorldPtr
) m_maskBitmap 
) ; 
1138         m_maskBitmap 
= NULL 
; 
1142 // Create a mask from a mono bitmap (copies the bitmap). 
1143 bool wxMask::Create(const wxBitmap
& bitmap
) 
1147        wxMacDestroyGWorld(  (GWorldPtr
) m_maskBitmap 
) ; 
1148        m_maskBitmap 
= NULL 
; 
1150    wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
1151                 wxT("Cannot create mask from this bitmap type (TODO)")); 
1152    // other types would require a temporary bitmap. not yet implemented 
1154    wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap")); 
1156    wxCHECK_MSG(bitmap
.GetDepth() == 1, false, 
1157                wxT("Cannot create mask from colour bitmap")); 
1159    m_maskBitmap 
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1); 
1160    Rect rect 
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() }; 
1162    LockPixels( GetGWorldPixMap( (GWorldPtr
) m_maskBitmap
) ); 
1163    LockPixels( GetGWorldPixMap( (GWorldPtr
) bitmap
.GetHBITMAP()) ); 
1164    CopyBits(GetPortBitMapForCopyBits( (GWorldPtr
) bitmap
.GetHBITMAP()), 
1165             GetPortBitMapForCopyBits( (GWorldPtr
) m_maskBitmap
), 
1166             &rect
, &rect
, srcCopy
, 0); 
1167    UnlockPixels( GetGWorldPixMap( (GWorldPtr
) m_maskBitmap
) ); 
1168    UnlockPixels( GetGWorldPixMap( (GWorldPtr
) bitmap
.GetHBITMAP()) ); 
1173 // Create a mask from a bitmap and a palette index indicating 
1174 // the transparent area 
1175 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
1178     wxCHECK_MSG( 0, false, wxT("wxMask::Create not yet implemented")); 
1182 // Create a mask from a bitmap and a colour indicating 
1183 // the transparent area 
1184 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1188         wxMacDestroyGWorld(  (GWorldPtr
) m_maskBitmap 
) ; 
1189         m_maskBitmap 
= NULL 
; 
1191     wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
1192                  wxT("Cannot create mask from this bitmap type (TODO)")); 
1193     // other types would require a temporary bitmap. not yet implemented  
1195     wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap")); 
1197     m_maskBitmap 
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );  
1198     LockPixels( GetGWorldPixMap(  (GWorldPtr
) m_maskBitmap 
) ); 
1199     LockPixels( GetGWorldPixMap(  (GWorldPtr
) bitmap
.GetHBITMAP() ) ); 
1200     RGBColor maskColor 
= MAC_WXCOLORREF(colour
.GetPixel()); 
1202     // this is not very efficient, but I can't think 
1203     // of a better way of doing it 
1205     GDHandle    origDevice 
; 
1207     RGBColor  colors
[2] = { 
1208         { 0xFFFF, 0xFFFF, 0xFFFF }, 
1211     GetGWorld( &origPort 
, &origDevice 
) ; 
1212     for (int w 
= 0; w 
< bitmap
.GetWidth(); w
++) 
1214         for (int h 
= 0; h 
< bitmap
.GetHeight(); h
++) 
1216             SetGWorld(  (GWorldPtr
) bitmap
.GetHBITMAP(), NULL 
) ; 
1217             GetCPixel( w 
, h 
, &col 
) ; 
1218             SetGWorld(  (GWorldPtr
) m_maskBitmap 
, NULL 
) ; 
1219             if (col
.red 
== maskColor
.red 
&& col
.green 
== maskColor
.green 
&& col
.blue 
== maskColor
.blue
) 
1221                 SetCPixel( w 
, h 
, &colors
[0] ) ; 
1225                 SetCPixel( w 
, h 
, &colors
[1] ) ; 
1229     UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap 
) ) ; 
1230     UnlockPixels( GetGWorldPixMap(  (GWorldPtr
) bitmap
.GetHBITMAP() ) ) ; 
1231     SetGWorld( origPort 
, origDevice 
) ; 
1236 bool wxMask::PointMasked(int x
, int y
) 
1239    GDHandle  origDevice
; 
1243    GetGWorld( &origPort
, &origDevice
); 
1245    //Set port to mask and see if it masked (1) or not ( 0 ) 
1246    SetGWorld( (GWorldPtr
) m_maskBitmap
, NULL
); 
1247    LockPixels(GetGWorldPixMap( (GWorldPtr
) m_maskBitmap
)); 
1248    GetCPixel(x
,y
, &color
); 
1249    masked 
= !(color
.red 
== 0 && color
.green 
== 0 && color
.blue 
== 0); 
1250    UnlockPixels(GetGWorldPixMap( (GWorldPtr
) m_maskBitmap
)); 
1252    SetGWorld( origPort
, origDevice
); 
1261 wxBitmapHandler::~wxBitmapHandler() 
1265 bool wxBitmapHandler::Create(wxBitmap 
*bitmap
, void *data
, long type
, int width
, int height
, int depth
) 
1270 bool wxBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1271         int desiredWidth
, int desiredHeight
) 
1276 bool wxBitmapHandler::SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1285 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1287     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1289     inline wxPICTResourceHandler() 
1291         m_name 
= "Macintosh Pict resource"; 
1293         m_type 
= wxBITMAP_TYPE_PICT_RESOURCE
; 
1296     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1297           int desiredWidth
, int desiredHeight
); 
1299 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1301 bool  wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1302           int desiredWidth
, int desiredHeight
) 
1307     c2pstrcpy( (StringPtr
) theName 
, name 
) ; 
1309     strcpy( (char *) theName 
, name 
) ; 
1310     c2pstr( (char *)theName 
) ; 
1313     PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1318         GetPictInfo( thePict 
, &theInfo 
, 0 , 0 , systemMethod 
, 0 ) ; 
1319         DetachResource( (Handle
) thePict 
) ; 
1320         M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypePict 
; 
1321         M_BITMAPHANDLERDATA
->m_hPict 
= thePict 
; 
1322         M_BITMAPHANDLERDATA
->m_width 
=  theInfo
.sourceRect
.right 
- theInfo
.sourceRect
.left 
; 
1323         M_BITMAPHANDLERDATA
->m_height 
= theInfo
.sourceRect
.bottom 
- theInfo
.sourceRect
.top 
; 
1325         M_BITMAPHANDLERDATA
->m_depth 
= theInfo
.depth 
; 
1326         M_BITMAPHANDLERDATA
->m_ok 
= true ; 
1327         M_BITMAPHANDLERDATA
->m_numColors 
= theInfo
.uniqueColors 
; 
1328 //      M_BITMAPHANDLERDATA->m_bitmapPalette; 
1329 //      M_BITMAPHANDLERDATA->m_quality; 
1335 void wxBitmap::InitStandardHandlers() 
1337     AddHandler(new wxPICTResourceHandler
) ; 
1338     AddHandler(new wxICONResourceHandler
) ;