1 ///////////////////////////////////////////////////////////////////////////// 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "bitmap.h" 
  19 #include "wx/palette.h" 
  20 #include "wx/bitmap.h" 
  24 #include "wx/xpmdecod.h" 
  28 #ifdef OBSOLETE_XPM_DATA_HANDLER 
  33 #if !USE_SHARED_LIBRARIES 
  34 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  35 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  39     #include <ApplicationServices/ApplicationServices.h> 
  41     #include <PictUtils.h> 
  44 #include "wx/mac/uma.h" 
  46 CTabHandle 
wxMacCreateColorTable( int numColors 
) 
  48         CTabHandle newColors
; /* Handle to the new color table */ 
  50         /* Allocate memory for the color table */ 
  51         newColors 
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) + 
  52         sizeof (ColorSpec
) * (numColors 
- 1) ); 
  55                 /* Initialize the fields */ 
  56                 (**newColors
).ctSeed 
= GetCTSeed(); 
  57                 (**newColors
).ctFlags 
= 0; 
  58                 (**newColors
).ctSize 
= numColors 
- 1; 
  59                 /* Initialize the table of colors */ 
  64 void wxMacDestroyColorTable( CTabHandle colors 
)  
  66         DisposeHandle( (Handle
) colors 
) ; 
  69 void wxMacSetColorTableEntry( CTabHandle newColors 
, int index 
, int red 
, int green 
,  int blue 
) 
  71         (**newColors
).ctTable
[index
].value 
= index
; 
  72         (**newColors
).ctTable
[index
].rgb
.red 
= 0 ;// someRedValue; 
  73         (**newColors
).ctTable
[index
].rgb
.green 
= 0 ; // someGreenValue; 
  74         (**newColors
).ctTable
[index
].rgb
.blue 
= 0 ; // someBlueValue; 
  77 GWorldPtr 
wxMacCreateGWorld( int width 
, int height 
, int depth 
) 
  81         Rect rect 
= { 0 , 0 , height 
, width 
} ; 
  85                 depth 
= wxDisplayDepth() ;      
  88         err 
= NewGWorld( &port 
, depth 
, &rect 
, NULL 
, NULL 
, 0 ) ; 
  96 void wxMacDestroyGWorld( GWorldPtr gw 
) 
 102 PicHandle 
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
) 
 107    PicHandle      pict
;          // this is the Picture we give back 
 109    RGBColor    gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 110    RGBColor    white 
= { 0xffff ,0xffff , 0xffff } ; 
 111    RGBColor    black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 113    unsigned char *maskimage 
= NULL 
; 
 115    GetPortBounds( wp 
, &portRect 
) ; 
 116    int width 
= portRect
.right 
- portRect
.left 
; 
 117    int height 
= portRect
.bottom 
- portRect
.top 
; 
 119    LockPixels( GetGWorldPixMap( wp 
) ) ; 
 120    GetGWorld( &origPort 
, &origDev 
) ; 
 124       maskimage 
= (unsigned char*) malloc( width 
* height 
) ; 
 125       SetGWorld( mask 
, NULL 
) ; 
 126       LockPixels( GetGWorldPixMap( mask 
) ) ; 
 127       for ( int y 
= 0 ; y 
< height 
; y
++ ) 
 129          for( int x 
= 0 ; x 
< width 
; x
++ ) 
 133             GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 134             maskimage
[y
*width 
+ x
] = ( col
.red 
== 0 ) ; // for monochrome masks 
 137       UnlockPixels( GetGWorldPixMap( mask 
) ) ; 
 140    SetGWorld( wp 
, NULL 
) ; 
 142    pict 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 148       RGBForeColor( &black 
) ; 
 149       RGBBackColor( &white 
) ; 
 150       PenMode(transparent
); 
 152       for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 154          for( int x 
= 0 ; x 
< width 
; ++x 
) 
 156             if ( maskimage
[y
*width 
+ x
] ) 
 160                GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 161                SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 164                 // With transparency set this sets a blank pixel not a white one 
 165                 SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &white
); 
 174       RGBBackColor( &gray 
) ; 
 175       EraseRect(&portRect
); 
 176       RGBForeColor( &black 
) ; 
 177       RGBBackColor( &white 
) ; 
 179       CopyBits(GetPortBitMapForCopyBits(wp
), /* src PixMap - we copy image over 
 181                GetPortBitMapForCopyBits(wp
), //  dst PixMap - no drawing occurs 
 182                &portRect
,    // srcRect - it will be recorded and compressed - 
 183                &portRect
,    // dstRect - into the picture that is open - 
 184                srcCopy
,NULL
); // copyMode and no clip region 
 186    ClosePicture();                  // We are done recording the picture 
 187    UnlockPixels( GetGWorldPixMap( wp 
) ) ; 
 188    SetGWorld( origPort 
, origDev 
) ; 
 190    return pict
;                  // return our groovy pict handle 
 193 wxBitmapRefData::wxBitmapRefData() 
 205     m_bitmapType 
= kMacBitmapTypeUnknownType 
; 
 208 wxBitmapRefData::~wxBitmapRefData() 
 210         switch (m_bitmapType
) 
 212                 case kMacBitmapTypePict 
: 
 216                                         KillPicture( m_hPict 
) ; 
 221                 case kMacBitmapTypeGrafWorld 
: 
 225                                         wxMacDestroyGWorld( m_hBitmap 
) ; 
 230                 case kMacBitmapTypeIcon 
: 
 233                         DisposeCIcon( m_hIcon 
) ; 
 249 wxList 
wxBitmap::sm_handlers
; 
 255     if ( wxTheBitmapList 
) 
 256         wxTheBitmapList
->AddBitmap(this); 
 259 wxBitmap::~wxBitmap() 
 262         wxTheBitmapList
->DeleteObject(this); 
 265 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 267     m_refData 
= new wxBitmapRefData
; 
 269     M_BITMAPDATA
->m_width 
= the_width 
; 
 270     M_BITMAPDATA
->m_height 
= the_height 
; 
 271     M_BITMAPDATA
->m_depth 
= no_bits 
; 
 272     M_BITMAPDATA
->m_numColors 
= 0; 
 275         M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 276         M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( the_width 
, the_height 
, no_bits 
) ; 
 277         M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 280         GDHandle        origDevice 
; 
 282         GetGWorld( &origPort 
, &origDevice 
) ; 
 283         SetGWorld( M_BITMAPDATA
->m_hBitmap 
, NULL 
) ; 
 284         LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 286         // bits is a char array 
 288         unsigned char* linestart 
= (unsigned char*) bits 
; 
 289         int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 290         if ( the_width 
% (sizeof(unsigned char) * 8) ) { 
 291             linesize 
+= sizeof(unsigned char); 
 294         RGBColor colors
[2] = {  
 295             { 0xFFFF , 0xFFFF , 0xFFFF } , 
 299         for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize 
) 
 301             for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 305                 int mask 
= 1 << bit 
; 
 306                 if ( linestart
[index
] & mask 
) 
 308                     SetCPixel( x 
, y 
, &colors
[1] ) ; 
 312                     SetCPixel( x 
, y 
, &colors
[0] ) ; 
 316         UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 318         SetGWorld( origPort 
, origDevice 
) ; 
 322         wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 325     if ( wxTheBitmapList 
) { 
 326         wxTheBitmapList
->AddBitmap(this); 
 330 wxBitmap::wxBitmap(int w
, int h
, int d
) 
 332     (void)Create(w
, h
, d
); 
 334     if ( wxTheBitmapList 
) 
 335         wxTheBitmapList
->AddBitmap(this); 
 338 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
) 
 340     (void) Create(data
, type
, width
, height
, depth
); 
 342     if ( wxTheBitmapList 
) 
 343         wxTheBitmapList
->AddBitmap(this); 
 346 wxBitmap::wxBitmap(const wxString
& filename
, long type
) 
 348     LoadFile(filename
, (int)type
); 
 350     if ( wxTheBitmapList 
) 
 351         wxTheBitmapList
->AddBitmap(this); 
 354 bool wxBitmap::CreateFromXpm(const char **bits
) 
 356     wxCHECK_MSG( bits 
!= NULL
, FALSE
, wxT("invalid bitmap data") ) 
 357     wxXPMDecoder decoder
; 
 358     wxImage img 
= decoder
.ReadData(bits
); 
 359     wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") )     
 360     *this = wxBitmap(img
);    
 361     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 365 wxBitmap::wxBitmap(const char **bits
) 
 367 #ifdef OBSOLETE_XPM_DATA_HANDLER 
 368     (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 370     (void) CreateFromXpm(bits
); 
 374 wxBitmap::wxBitmap(char **bits
) 
 376 #ifdef OBSOLETE_XPM_DATA_HANDLER 
 377     (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 379     (void) CreateFromXpm((const char **)bits
); 
 383 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
 386                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 387                 (rect
.x
+rect
.width 
<= GetWidth()) && 
 388                 (rect
.y
+rect
.height 
<= GetHeight()), 
 389                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 392    wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
 393    wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 398    GetGWorld( &origPort
, &origDevice 
); 
 400    // Update the subbitmaps reference data 
 401    wxBitmapRefData 
*ref 
= (wxBitmapRefData 
*)ret
.GetRefData(); 
 403    ref
->m_numColors     
= M_BITMAPDATA
->m_numColors
; 
 404    ref
->m_bitmapPalette 
= M_BITMAPDATA
->m_bitmapPalette
; 
 405    ref
->m_bitmapType    
= M_BITMAPDATA
->m_bitmapType
; 
 407    // Copy sub region of this bitmap 
 408    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) 
 410        printf("GetSubBitmap:  Copy a region of a Pict structure - TODO\n"); 
 412    else if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypeGrafWorld
) 
 417            WXHBITMAP submask
, mask
; 
 420            mask 
= GetMask()->GetMaskBitmap(); 
 421            submask 
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1); 
 422            LockPixels(GetGWorldPixMap(mask
)); 
 423            LockPixels(GetGWorldPixMap(submask
)); 
 425            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 427                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 429                    SetGWorld(mask
, NULL
); 
 430                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 431                    SetGWorld(submask
, NULL
); 
 432                    SetCPixel(xx
,yy
, &color
); 
 435            UnlockPixels(GetGWorldPixMap(mask
)); 
 436            UnlockPixels(GetGWorldPixMap(submask
)); 
 437            ref
->m_bitmapMask 
= new wxMask
; 
 438            ref
->m_bitmapMask
->SetMaskBitmap(submask
); 
 444            WXHBITMAP subbitmap
, bitmap
; 
 447            bitmap 
= GetHBITMAP(); 
 448            subbitmap 
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth()); 
 449            LockPixels(GetGWorldPixMap(bitmap
)); 
 450            LockPixels(GetGWorldPixMap(subbitmap
)); 
 452            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 454                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 456                    SetGWorld(bitmap
, NULL
); 
 457                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 458                    SetGWorld(subbitmap
, NULL
); 
 459                    SetCPixel(xx
, yy
, &color
); 
 462            UnlockPixels(GetGWorldPixMap(bitmap
)); 
 463            UnlockPixels(GetGWorldPixMap(subbitmap
)); 
 464            ret
.SetHBITMAP(subbitmap
); 
 467    SetGWorld( origPort
, origDevice 
); 
 472 bool wxBitmap::Create(int w
, int h
, int d
) 
 476     m_refData 
= new wxBitmapRefData
; 
 478     M_BITMAPDATA
->m_width 
= w
; 
 479     M_BITMAPDATA
->m_height 
= h
; 
 480     M_BITMAPDATA
->m_depth 
= d
; 
 482     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 483     M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( w 
, h 
, d 
) ; 
 484                 M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 485     return M_BITMAPDATA
->m_ok
; 
 488 int wxBitmap::GetBitmapType() const 
 490    wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") ); 
 492    return M_BITMAPDATA
->m_bitmapType
; 
 495 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
) 
 497     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 498     M_BITMAPDATA
->m_hBitmap 
= bmp 
; 
 499         M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 502 bool wxBitmap::LoadFile(const wxString
& filename
, long type
) 
 506     m_refData 
= new wxBitmapRefData
; 
 508     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 510     if ( handler 
== NULL 
) { 
 511         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 516     return handler
->LoadFile(this, filename
, type
, -1, -1); 
 519 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
) 
 523     m_refData 
= new wxBitmapRefData
; 
 525     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 527     if ( handler 
== NULL 
) { 
 528         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 533     return handler
->Create(this, data
, type
, width
, height
, depth
); 
 536 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
 538     wxCHECK_RET( image
.Ok(), wxT("invalid image") ) 
 539     wxCHECK_RET( depth 
== -1, wxT("invalid bitmap depth") ) 
 541     m_refData 
= new wxBitmapRefData(); 
 543     if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this); 
 545     // width and height of the device-dependent bitmap 
 546     int width 
= image
.GetWidth(); 
 547     int height 
= image
.GetHeight(); 
 551     Create( width 
, height 
, wxDisplayDepth() ) ; 
 552     wxBitmap 
maskBitmap( width
, height
, 1); 
 555     GDHandle origDevice 
; 
 557     LockPixels( GetGWorldPixMap(GetHBITMAP()) ); 
 558     LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) ); 
 560     GetGWorld( &origPort 
, &origDevice 
) ; 
 561     SetGWorld( GetHBITMAP() , NULL 
) ; 
 564     wxColour rgb
, maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue()); 
 566     RGBColor white 
= { 0xffff, 0xffff, 0xffff }; 
 567     RGBColor black 
= { 0     , 0     , 0      }; 
 569     register unsigned char* data 
= image
.GetData(); 
 572     for (int y 
= 0; y 
< height
; y
++) 
 574         for (int x 
= 0; x 
< width
; x
++) 
 576             rgb
.Set(data
[index
++], data
[index
++], data
[index
++]); 
 577             color 
= rgb
.GetPixel(); 
 578             SetCPixel( x 
, y 
, &color 
) ; 
 581                 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
); 
 582                 if (rgb 
== maskcolor
) { 
 583                     SetCPixel(x
,y
, &white
); 
 586                     SetCPixel(x
,y
, &black
); 
 588                 SetGWorld(GetHBITMAP(), NULL
); 
 594     if ( image
.HasMask() ) { 
 595 //        SetMask(new wxMask( maskBitmap )); 
 598     UnlockPixels( GetGWorldPixMap(GetHBITMAP()) ); 
 599     UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) ); 
 600     SetGWorld( origPort
, origDevice 
); 
 603 wxImage 
wxBitmap::ConvertToImage() const 
 607     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 609     // create an wxImage object 
 610     int width 
= GetWidth(); 
 611     int height 
= GetHeight(); 
 612     image
.Create( width
, height 
); 
 614     unsigned char *data 
= image
.GetData(); 
 616     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
 622     // background color set to RGB(16,16,16) in consistent with wxGTK 
 623     unsigned char mask_r
=16, mask_g
=16, mask_b
=16; 
 625     wxMask  
*mask 
= GetMask(); 
 627     GetGWorld( &origPort
, &origDevice 
); 
 628     LockPixels(GetGWorldPixMap(GetHBITMAP())); 
 629     SetGWorld( GetHBITMAP(), NULL
); 
 631     // Copy data into image 
 633     for (int yy 
= 0; yy 
< height
; yy
++) 
 635         for (int xx 
= 0; xx 
< width
; xx
++) 
 637             GetCPixel(xx
,yy
, &color
); 
 638             r 
= ((color
.red 
) >> 8); 
 639             g 
= ((color
.green 
) >> 8); 
 640             b 
= ((color
.blue 
) >> 8); 
 646                 if (mask
->PointMasked(xx
,yy
)) 
 648                     data
[index    
] = mask_r
; 
 649                     data
[index 
+ 1] = mask_g
; 
 650                     data
[index 
+ 2] = mask_b
; 
 658         image
.SetMaskColour( mask_r
, mask_g
, mask_b 
); 
 659         image
.SetMask( true ); 
 663     UnlockPixels(GetGWorldPixMap(GetHBITMAP())); 
 664     SetGWorld(origPort
, origDevice
); 
 670 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette 
*palette
) 
 672     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 674     if ( handler 
== NULL 
) { 
 675         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 680   return handler
->SaveFile(this, filename
, type
, palette
); 
 683 bool wxBitmap::Ok() const 
 685    return (M_BITMAPDATA 
&& M_BITMAPDATA
->m_ok
); 
 688 int wxBitmap::GetHeight() const 
 690    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 692    return M_BITMAPDATA
->m_height
; 
 695 int wxBitmap::GetWidth() const 
 697    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 699    return M_BITMAPDATA
->m_width
; 
 702 int wxBitmap::GetDepth() const 
 704    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 706    return M_BITMAPDATA
->m_depth
; 
 709 int wxBitmap::GetQuality() const 
 711    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 713    return M_BITMAPDATA
->m_quality
; 
 716 wxMask 
*wxBitmap::GetMask() const 
 718    wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 720    return M_BITMAPDATA
->m_bitmapMask
; 
 723 void wxBitmap::SetWidth(int w
) 
 726         m_refData 
= new wxBitmapRefData
; 
 728     M_BITMAPDATA
->m_width 
= w
; 
 731 void wxBitmap::SetHeight(int h
) 
 734         m_refData 
= new wxBitmapRefData
; 
 736     M_BITMAPDATA
->m_height 
= h
; 
 739 void wxBitmap::SetDepth(int d
) 
 742         m_refData 
= new wxBitmapRefData
; 
 744     M_BITMAPDATA
->m_depth 
= d
; 
 747 void wxBitmap::SetQuality(int q
) 
 750         m_refData 
= new wxBitmapRefData
; 
 752     M_BITMAPDATA
->m_quality 
= q
; 
 755 void wxBitmap::SetOk(bool isOk
) 
 758         m_refData 
= new wxBitmapRefData
; 
 760     M_BITMAPDATA
->m_ok 
= isOk
; 
 763 wxPalette 
*wxBitmap::GetPalette() const 
 765    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
 767    return &M_BITMAPDATA
->m_bitmapPalette
; 
 770 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 773         m_refData 
= new wxBitmapRefData
; 
 775     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
 778 void wxBitmap::SetMask(wxMask 
*mask
) 
 781         m_refData 
= new wxBitmapRefData
; 
 783     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
 786 WXHBITMAP 
wxBitmap::GetHBITMAP() const 
 788    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 790    return M_BITMAPDATA
->m_hBitmap
; 
 793 PicHandle 
wxBitmap::GetPict() const 
 795    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 797    PicHandle picture
;       // This is the returned picture 
 799    // If bitmap already in Pict format return pointer 
 800    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) { 
 801        return M_BITMAPDATA
->m_hPict
; 
 803    else if(M_BITMAPDATA
->m_bitmapType 
!= kMacBitmapTypeGrafWorld
) { 
 808    RGBColor  gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 809    RGBColor  white 
= { 0xffff ,0xffff , 0xffff } ; 
 810    RGBColor  black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 816    GetPortBounds( GetHBITMAP() , &portRect 
) ; 
 817    int width 
= portRect
.right 
- portRect
.left 
; 
 818    int height 
= portRect
.bottom 
- portRect
.top 
; 
 820    LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 821    GetGWorld( &origPort 
, &origDev 
) ; 
 825    SetGWorld( GetHBITMAP() , NULL 
) ; 
 827    picture 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 835        RGBColor trans 
= white
; 
 837        RGBBackColor( &gray 
); 
 838        EraseRect( &portRect 
); 
 839        RGBColor trans 
= gray
; 
 841        RGBForeColor( &black 
) ; 
 842        RGBBackColor( &white 
) ; 
 843        PenMode(transparent
); 
 845        for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 847            for( int x 
= 0 ; x 
< width 
; ++x 
) 
 849                if ( !mask
->PointMasked(x
,y
) ) 
 853                    GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 854                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 857                    // With transparency this sets a blank pixel 
 858                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &trans
); 
 865        RGBBackColor( &gray 
) ; 
 866        EraseRect(&portRect
); 
 867        RGBForeColor( &black 
) ; 
 868        RGBBackColor( &white 
) ; 
 870        CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),  
 871                 // src PixMap - we copy image over itself - 
 872                 GetPortBitMapForCopyBits(GetHBITMAP()), 
 873                 //  dst PixMap - no drawing occurs 
 874                 &portRect
,    // srcRect - it will be recorded and compressed - 
 875                 &portRect
,    // dstRect - into the picture that is open - 
 876                 srcCopy
,NULL
); // copyMode and no clip region 
 878    ClosePicture();                  // We are done recording the picture 
 879    UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 880    SetGWorld( origPort 
, origDev 
) ; 
 882    return picture
;                  // return our groovy pict handle 
 885 void wxBitmap::AddHandler(wxBitmapHandler 
*handler
) 
 887     sm_handlers
.Append(handler
); 
 890 void wxBitmap::InsertHandler(wxBitmapHandler 
*handler
) 
 892     sm_handlers
.Insert(handler
); 
 895 bool wxBitmap::RemoveHandler(const wxString
& name
) 
 897     wxBitmapHandler 
*handler 
= FindHandler(name
); 
 900         sm_handlers
.DeleteObject(handler
); 
 907 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& name
) 
 909     wxNode 
*node 
= sm_handlers
.First(); 
 912         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 913         if ( handler
->GetName() == name 
) 
 920 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
) 
 922     wxNode 
*node 
= sm_handlers
.First(); 
 925         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 926         if ( handler
->GetExtension() == extension 
&& 
 927                     (bitmapType 
== -1 || handler
->GetType() == bitmapType
) ) 
 934 wxBitmapHandler 
*wxBitmap::FindHandler(long bitmapType
) 
 936     wxNode 
*node 
= sm_handlers
.First(); 
 939         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 940         if (handler
->GetType() == bitmapType
) 
 956 // Construct a mask from a bitmap and a colour indicating 
 957 // the transparent area 
 958 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 961     Create(bitmap
, colour
); 
 964 // Construct a mask from a bitmap and a palette index indicating 
 965 // the transparent area 
 966 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
 969     Create(bitmap
, paletteIndex
); 
 972 // Construct a mask from a mono bitmap (copies the bitmap). 
 973 wxMask::wxMask(const wxBitmap
& bitmap
) 
 983                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
 984                 m_maskBitmap 
= NULL 
; 
 988 // Create a mask from a mono bitmap (copies the bitmap). 
 989 bool wxMask::Create(const wxBitmap
& bitmap
) 
 993        wxMacDestroyGWorld( m_maskBitmap 
) ; 
 994        m_maskBitmap 
= NULL 
; 
 996    wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
 997                 wxT("Cannot create mask from this bitmap type (TODO)")); 
 998    // other types would require a temporary bitmap. not yet implemented 
1000    wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap")); 
1002    wxCHECK_MSG(bitmap
.GetDepth() == 1, false, 
1003                wxT("Cannot create mask from colour bitmap")); 
1005    m_maskBitmap 
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1); 
1006    Rect rect 
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() }; 
1008    LockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
1009    LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
1010    CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()), 
1011             GetPortBitMapForCopyBits(m_maskBitmap
), 
1012             &rect
, &rect
, srcCopy
, 0); 
1013    UnlockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
1014    UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
1019 // Create a mask from a bitmap and a palette index indicating 
1020 // the transparent area 
1021 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
1024     wxCHECK_MSG( 0, false, wxT("Not implemented")); 
1028 // Create a mask from a bitmap and a colour indicating 
1029 // the transparent area 
1030 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1034                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
1035                 m_maskBitmap 
= NULL 
; 
1037         wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
1038                  wxT("Cannot create mask from this bitmap type (TODO)")); 
1039         // other types would require a temporary bitmap. not yet implemented  
1041     wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap")); 
1043         m_maskBitmap 
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );  
1044         LockPixels( GetGWorldPixMap( m_maskBitmap 
) ); 
1045         LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ); 
1046         RGBColor maskColor 
= colour
.GetPixel(); 
1048     // this is not very efficient, but I can't think 
1049     // of a better way of doing it 
1051         GDHandle        origDevice 
; 
1053     RGBColor  colors
[2] = { 
1054         { 0xFFFF, 0xFFFF, 0xFFFF }, 
1057         GetGWorld( &origPort 
, &origDevice 
) ; 
1058         for (int w 
= 0; w 
< bitmap
.GetWidth(); w
++) 
1060         for (int h 
= 0; h 
< bitmap
.GetHeight(); h
++) 
1062                         SetGWorld( bitmap
.GetHBITMAP(), NULL 
) ; 
1063                         GetCPixel( w 
, h 
, &col 
) ; 
1064                         SetGWorld( m_maskBitmap 
, NULL 
) ; 
1065             if (col
.red 
== maskColor
.red 
&& col
.green 
== maskColor
.green 
&& col
.blue 
== maskColor
.blue
) 
1067                                 SetCPixel( w 
, h 
, &colors
[0] ) ; 
1071                                 SetCPixel( w 
, h 
, &colors
[1] ) ; 
1075         UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap 
) ) ; 
1076         UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ; 
1077         SetGWorld( origPort 
, origDevice 
) ; 
1082 bool wxMask::PointMasked(int x
, int y
) 
1085    GDHandle  origDevice
; 
1089    GetGWorld( &origPort
, &origDevice
); 
1091    //Set port to mask and see if it masked (1) or not ( 0 ) 
1092    SetGWorld(m_maskBitmap
, NULL
); 
1093    LockPixels(GetGWorldPixMap(m_maskBitmap
)); 
1094    GetCPixel(x
,y
, &color
); 
1095    masked 
= !(color
.red 
== 0 && color
.green 
== 0 && color
.blue 
== 0); 
1096    UnlockPixels(GetGWorldPixMap(m_maskBitmap
)); 
1098    SetGWorld( origPort
, origDevice
); 
1107 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
1109 bool wxBitmapHandler::Create(wxBitmap 
*bitmap
, void *data
, long type
, int width
, int height
, int depth
) 
1114 bool wxBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long type
, 
1115         int desiredWidth
, int desiredHeight
) 
1120 bool wxBitmapHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1129 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1131     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1133     inline wxPICTResourceHandler() 
1135         m_name 
= "Macintosh Pict resource"; 
1137         m_type 
= wxBITMAP_TYPE_PICT_RESOURCE
; 
1140     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1141           int desiredWidth
, int desiredHeight
); 
1143 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1145 bool  wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1146           int desiredWidth
, int desiredHeight
) 
1151         c2pstrcpy( (StringPtr
) theName 
, name 
) ; 
1153         strcpy( (char *) theName 
, name 
) ; 
1154         c2pstr( (char *)theName 
) ; 
1157         PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1162                 GetPictInfo( thePict 
, &theInfo 
, 0 , 0 , systemMethod 
, 0 ) ; 
1163                 DetachResource( (Handle
) thePict 
) ; 
1164                 M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypePict 
; 
1165                 M_BITMAPHANDLERDATA
->m_hPict 
= thePict 
; 
1166                 M_BITMAPHANDLERDATA
->m_width 
=  theInfo
.sourceRect
.right 
- theInfo
.sourceRect
.left 
; 
1167                 M_BITMAPHANDLERDATA
->m_height 
= theInfo
.sourceRect
.bottom 
- theInfo
.sourceRect
.top 
; 
1169                 M_BITMAPHANDLERDATA
->m_depth 
= theInfo
.depth 
; 
1170                 M_BITMAPHANDLERDATA
->m_ok 
= true ; 
1171                 M_BITMAPHANDLERDATA
->m_numColors 
= theInfo
.uniqueColors 
; 
1172 //              M_BITMAPHANDLERDATA->m_bitmapPalette; 
1173 //              M_BITMAPHANDLERDATA->m_quality; 
1179 /* TODO: bitmap handlers, a bit like this: 
1180 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler 
1182     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) 
1184     inline wxBMPResourceHandler() 
1186         m_name = "Windows bitmap resource"; 
1188         m_type = wxBITMAP_TYPE_BMP_RESOURCE; 
1191     virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, 
1192           int desiredWidth, int desiredHeight); 
1194 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) 
1197 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
 
1199   DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
) 
1201   inline wxXPMFileHandler(void) 
1203   m_name 
= "XPM bitmap file"; 
1204   m_extension 
= "xpm"; 
1205   m_type 
= wxBITMAP_TYPE_XPM
; 
1208   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1209     int desiredWidth 
= -1, int desiredHeight 
= -1); 
1210   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1212 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
) 
1214 bool wxXPMFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1215     int desiredWidth
, int desiredHeight
) 
1219     XpmAttributes xpmAttr
; 
1222     M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1223     dc 
= CreateCompatibleDC(NULL
); 
1226       xpmAttr
.valuemask 
= XpmReturnPixels
; 
1227       int errorStatus 
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage 
**) NULL
, &xpmAttr
); 
1229       if (errorStatus 
== XpmSuccess
) 
1231         M_BITMAPHANDLERDATA
->m_hBitmap 
= (WXHBITMAP
) ximage
->bitmap
; 
1234         GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
); 
1236         M_BITMAPHANDLERDATA
->m_width 
= (bm
.bmWidth
); 
1237         M_BITMAPHANDLERDATA
->m_height 
= (bm
.bmHeight
); 
1238         M_BITMAPHANDLERDATA
->m_depth 
= (bm
.bmPlanes 
* bm
.bmBitsPixel
); 
1239         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1240         XpmFreeAttributes(&xpmAttr
); 
1243         M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1248         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1257 bool wxXPMFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1262       Visual 
*visual 
= NULL
; 
1265       dc 
= CreateCompatibleDC(NULL
); 
1268         if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
)) 
1271     ximage
.width 
= M_BITMAPHANDLERDATA
->m_width
;  
1272      ximage
.height 
= M_BITMAPHANDLERDATA
->m_height
; 
1273     ximage
.depth 
= M_BITMAPHANDLERDATA
->m_depth
;  
1274      ximage
.bitmap 
= (void *)M_BITMAPHANDLERDATA
->m_hBitmap
; 
1275     int errorStatus 
= XpmWriteFileFromImage(&dc
, WXSTRINGCAST name
, 
1276               &ximage
, (XImage 
*) NULL
, (XpmAttributes 
*) NULL
); 
1281     if (errorStatus 
== XpmSuccess
) 
1285         } else return FALSE
; 
1286       } else return FALSE
; 
1292 #ifdef OBSOLETE_XPM_DATA_HANDLER 
1293 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
 
1295   DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
) 
1297   inline wxXPMDataHandler(void) 
1299   m_name 
= "XPM bitmap data"; 
1300   m_extension 
= "xpm"; 
1301   m_type 
= wxBITMAP_TYPE_XPM_DATA
; 
1304   virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth 
= 1); 
1306 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
) 
1308 bool wxXPMDataHandler::Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
) 
1310     XImage 
*            ximage 
= NULL 
; 
1311     XImage 
*            xshapeimage 
= NULL 
; 
1313     XpmAttributes       xpmAttr
; 
1315     xpmAttr
.valuemask 
= XpmReturnInfos
; // get infos back 
1316     ErrorStatus 
= XpmCreateImageFromData( GetMainDevice() , (char **)data
, 
1317          &ximage
, &xshapeimage
, &xpmAttr
); 
1319     if (ErrorStatus 
== XpmSuccess
) 
1321         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1322         M_BITMAPHANDLERDATA
->m_numColors 
= 0; 
1323         M_BITMAPHANDLERDATA
->m_hBitmap 
= ximage
->gworldptr 
; 
1325         M_BITMAPHANDLERDATA
->m_width 
= ximage
->width
; 
1326         M_BITMAPHANDLERDATA
->m_height 
= ximage
->height
; 
1327         M_BITMAPHANDLERDATA
->m_depth 
= ximage
->depth
; 
1328         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1329         XpmFreeAttributes(&xpmAttr
); 
1330         M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1331         ximage
->gworldptr 
= NULL 
; 
1332         XImageFree(ximage
); // releases the malloc, but does not detroy 
1334         M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
1335         if ( xshapeimage 
!= NULL 
) 
1337                 wxMask
* m 
= new wxMask() ; 
1338                 m
->SetMaskBitmap( xshapeimage
->gworldptr 
) ; 
1339                 M_BITMAPHANDLERDATA
->m_bitmapMask 
= m 
; 
1345       M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1352 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
 
1354     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
) 
1356     inline wxBMPResourceHandler() 
1358         m_name 
= "Windows bitmap resource"; 
1360         m_type 
= wxBITMAP_TYPE_BMP_RESOURCE
; 
1363     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1364           int desiredWidth
, int desiredHeight
); 
1367 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
) 
1369 bool wxBMPResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1370     int desiredWidth
, int desiredHeight
) 
1372     // TODO: load colourmap. 
1373   // it's probably not found 
1374   wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str()); 
1379 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
 
1381   DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
) 
1383   inline wxBMPFileHandler(void) 
1385   m_name 
= "Windows bitmap file"; 
1386   m_extension 
= "bmp"; 
1387   m_type 
= wxBITMAP_TYPE_BMP
; 
1390   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1391       int desiredWidth
, int desiredHeight
); 
1392   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1395 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
) 
1397 bool wxBMPFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1398     int desiredWidth
, int desiredHeight
) 
1400 #if USE_IMAGE_LOADING_IN_MSW 
1401     wxPalette 
*palette 
= NULL
; 
1402     bool success 
= FALSE
; 
1403     success 
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0); 
1404     if (!success 
&& palette
) 
1410       M_BITMAPHANDLERDATA
->m_bitmapPalette 
= *palette
; 
1417 bool wxBMPFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*pal
) 
1419 #if USE_IMAGE_LOADING_IN_MSW 
1420     wxPalette 
*actualPalette 
= (wxPalette 
*)pal
; 
1421     if (!actualPalette 
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull())) 
1422       actualPalette 
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
); 
1423     return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0); 
1430 void wxBitmap::CleanUpHandlers() 
1432     wxNode 
*node 
= sm_handlers
.First(); 
1435         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
1436         wxNode 
*next 
= node
->Next(); 
1443 void wxBitmap::InitStandardHandlers() 
1445     AddHandler(new wxPICTResourceHandler
) ; 
1446     AddHandler(new wxICONResourceHandler
) ; 
1447     AddHandler(new wxXPMFileHandler
); 
1448 #ifdef OBSOLETE_XPM_DATA_HANDLER 
1449     AddHandler(new wxXPMDataHandler
); 
1451     AddHandler(new wxBMPResourceHandler
); 
1452     AddHandler(new wxBMPFileHandler
);