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" 
  34 #if !USE_SHARED_LIBRARIES 
  35 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  36 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  40     #include <ApplicationServices/ApplicationServices.h> 
  42     #include <PictUtils.h> 
  45 #include "wx/mac/uma.h" 
  47 CTabHandle 
wxMacCreateColorTable( int numColors 
) 
  49         CTabHandle newColors
; /* Handle to the new color table */ 
  51         /* Allocate memory for the color table */ 
  52         newColors 
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) + 
  53         sizeof (ColorSpec
) * (numColors 
- 1) ); 
  56                 /* Initialize the fields */ 
  57                 (**newColors
).ctSeed 
= GetCTSeed(); 
  58                 (**newColors
).ctFlags 
= 0; 
  59                 (**newColors
).ctSize 
= numColors 
- 1; 
  60                 /* Initialize the table of colors */ 
  65 void wxMacDestroyColorTable( CTabHandle colors 
)  
  67         DisposeHandle( (Handle
) colors 
) ; 
  70 void wxMacSetColorTableEntry( CTabHandle newColors 
, int index 
, int red 
, int green 
,  int blue 
) 
  72         (**newColors
).ctTable
[index
].value 
= index
; 
  73         (**newColors
).ctTable
[index
].rgb
.red 
= 0 ;// someRedValue; 
  74         (**newColors
).ctTable
[index
].rgb
.green 
= 0 ; // someGreenValue; 
  75         (**newColors
).ctTable
[index
].rgb
.blue 
= 0 ; // someBlueValue; 
  78 GWorldPtr 
wxMacCreateGWorld( int width 
, int height 
, int depth 
) 
  82         Rect rect 
= { 0 , 0 , height 
, width 
} ; 
  86                 depth 
= wxDisplayDepth() ;      
  89         err 
= NewGWorld( &port 
, depth 
, &rect 
, NULL 
, NULL 
, 0 ) ; 
  97 void wxMacDestroyGWorld( GWorldPtr gw 
) 
 100                 DisposeGWorld( gw 
) ; 
 103 PicHandle 
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
) 
 108    PicHandle      pict
;          // this is the Picture we give back 
 110    RGBColor    gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 111    RGBColor    white 
= { 0xffff ,0xffff , 0xffff } ; 
 112    RGBColor    black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 114    unsigned char *maskimage 
= NULL 
; 
 116    GetPortBounds( wp 
, &portRect 
) ; 
 117    int width 
= portRect
.right 
- portRect
.left 
; 
 118    int height 
= portRect
.bottom 
- portRect
.top 
; 
 120    LockPixels( GetGWorldPixMap( wp 
) ) ; 
 121    GetGWorld( &origPort 
, &origDev 
) ; 
 125       maskimage 
= (unsigned char*) malloc( width 
* height 
) ; 
 126       SetGWorld( mask 
, NULL 
) ; 
 127       LockPixels( GetGWorldPixMap( mask 
) ) ; 
 128       for ( int y 
= 0 ; y 
< height 
; y
++ ) 
 130          for( int x 
= 0 ; x 
< width 
; x
++ ) 
 134             GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 135             maskimage
[y
*width 
+ x
] = ( col
.red 
== 0 ) ; // for monochrome masks 
 138       UnlockPixels( GetGWorldPixMap( mask 
) ) ; 
 141    SetGWorld( wp 
, NULL 
) ; 
 143    pict 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 149       RGBForeColor( &black 
) ; 
 150       RGBBackColor( &white 
) ; 
 151       PenMode(transparent
); 
 153       for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 155          for( int x 
= 0 ; x 
< width 
; ++x 
) 
 157             if ( maskimage
[y
*width 
+ x
] ) 
 161                GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 162                SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 165                 // With transparency set this sets a blank pixel not a white one 
 166                 SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &white
); 
 175       RGBBackColor( &gray 
) ; 
 176       EraseRect(&portRect
); 
 177       RGBForeColor( &black 
) ; 
 178       RGBBackColor( &white 
) ; 
 180       CopyBits(GetPortBitMapForCopyBits(wp
), /* src PixMap - we copy image over 
 182                GetPortBitMapForCopyBits(wp
), //  dst PixMap - no drawing occurs 
 183                &portRect
,    // srcRect - it will be recorded and compressed - 
 184                &portRect
,    // dstRect - into the picture that is open - 
 185                srcCopy
,NULL
); // copyMode and no clip region 
 187    ClosePicture();                  // We are done recording the picture 
 188    UnlockPixels( GetGWorldPixMap( wp 
) ) ; 
 189    SetGWorld( origPort 
, origDev 
) ; 
 191    return pict
;                  // return our groovy pict handle 
 194 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 
) ; 
 242 wxList 
wxBitmap::sm_handlers
; 
 248     if ( wxTheBitmapList 
) 
 249         wxTheBitmapList
->AddBitmap(this); 
 252 wxBitmap::~wxBitmap() 
 255         wxTheBitmapList
->DeleteObject(this); 
 258 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 260     m_refData 
= new wxBitmapRefData
; 
 262     M_BITMAPDATA
->m_width 
= the_width 
; 
 263     M_BITMAPDATA
->m_height 
= the_height 
; 
 264     M_BITMAPDATA
->m_depth 
= no_bits 
; 
 265     M_BITMAPDATA
->m_numColors 
= 0; 
 268         M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 269         M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( the_width 
, the_height 
, no_bits 
) ; 
 270         M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 273         GDHandle        origDevice 
; 
 275         GetGWorld( &origPort 
, &origDevice 
) ; 
 276         SetGWorld( M_BITMAPDATA
->m_hBitmap 
, NULL 
) ; 
 277         LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 279         // bits is a char array 
 281         unsigned char* linestart 
= (unsigned char*) bits 
; 
 282         int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 283         if ( the_width 
% (sizeof(unsigned char) * 8) ) { 
 284             linesize 
+= sizeof(unsigned char); 
 287         RGBColor colors
[2] = {  
 288             { 0xFFFF , 0xFFFF , 0xFFFF } , 
 292         for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize 
) 
 294             for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 298                 int mask 
= 1 << bit 
; 
 299                 if ( linestart
[index
] & mask 
) 
 301                     SetCPixel( x 
, y 
, &colors
[1] ) ; 
 305                     SetCPixel( x 
, y 
, &colors
[0] ) ; 
 310         UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 312         SetGWorld( origPort 
, origDevice 
) ; 
 316         wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 319     if ( wxTheBitmapList 
) { 
 320         wxTheBitmapList
->AddBitmap(this); 
 324 wxBitmap::wxBitmap(int w
, int h
, int d
) 
 326     (void)Create(w
, h
, d
); 
 328     if ( wxTheBitmapList 
) 
 329         wxTheBitmapList
->AddBitmap(this); 
 332 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
) 
 334     (void) Create(data
, type
, width
, height
, depth
); 
 336     if ( wxTheBitmapList 
) 
 337         wxTheBitmapList
->AddBitmap(this); 
 340 wxBitmap::wxBitmap(const wxString
& filename
, long type
) 
 342     LoadFile(filename
, (int)type
); 
 344     if ( wxTheBitmapList 
) 
 345         wxTheBitmapList
->AddBitmap(this); 
 348 wxBitmap::wxBitmap(const char **data
) 
 350     (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 353 wxBitmap::wxBitmap(char **data
) 
 355     (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 358 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
 361                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 362                 (rect
.x
+rect
.width 
<= GetWidth()) && 
 363                 (rect
.y
+rect
.height 
<= GetHeight()), 
 364                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 367    wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
 368    wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 373    GetGWorld( &origPort
, &origDevice 
); 
 375    // Update the subbitmaps reference data 
 376    wxBitmapRefData 
*ref 
= (wxBitmapRefData 
*)ret
.GetRefData(); 
 378    ref
->m_numColors     
= M_BITMAPDATA
->m_numColors
; 
 379    ref
->m_bitmapPalette 
= M_BITMAPDATA
->m_bitmapPalette
; 
 380    ref
->m_bitmapType    
= M_BITMAPDATA
->m_bitmapType
; 
 382    // Copy sub region of this bitmap 
 383    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) 
 385        printf("GetSubBitmap:  Copy a region of a Pict structure - TODO\n"); 
 387    else if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypeGrafWorld
) 
 392            WXHBITMAP submask
, mask
; 
 395            mask 
= GetMask()->GetMaskBitmap(); 
 396            submask 
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1); 
 397            LockPixels(GetGWorldPixMap(mask
)); 
 398            LockPixels(GetGWorldPixMap(submask
)); 
 400            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 402                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 404                    SetGWorld(mask
, NULL
); 
 405                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 406                    SetGWorld(submask
, NULL
); 
 407                    SetCPixel(xx
,yy
, &color
); 
 410            UnlockPixels(GetGWorldPixMap(mask
)); 
 411            UnlockPixels(GetGWorldPixMap(submask
)); 
 412            ref
->m_bitmapMask 
= new wxMask
; 
 413            ref
->m_bitmapMask
->SetMaskBitmap(submask
); 
 419            WXHBITMAP subbitmap
, bitmap
; 
 422            bitmap 
= GetHBITMAP(); 
 423            subbitmap 
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth()); 
 424            LockPixels(GetGWorldPixMap(bitmap
)); 
 425            LockPixels(GetGWorldPixMap(subbitmap
)); 
 427            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 429                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 431                    SetGWorld(bitmap
, NULL
); 
 432                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 433                    SetGWorld(subbitmap
, NULL
); 
 434                    SetCPixel(xx
, yy
, &color
); 
 437            UnlockPixels(GetGWorldPixMap(bitmap
)); 
 438            UnlockPixels(GetGWorldPixMap(subbitmap
)); 
 439            ret
.SetHBITMAP(subbitmap
); 
 442    SetGWorld( origPort
, origDevice 
); 
 447 bool wxBitmap::Create(int w
, int h
, int d
) 
 451     m_refData 
= new wxBitmapRefData
; 
 453     M_BITMAPDATA
->m_width 
= w
; 
 454     M_BITMAPDATA
->m_height 
= h
; 
 455     M_BITMAPDATA
->m_depth 
= d
; 
 457     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 458     M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( w 
, h 
, d 
) ; 
 459                 M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 460     return M_BITMAPDATA
->m_ok
; 
 463 int wxBitmap::GetBitmapType() const 
 465    wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") ); 
 467    return M_BITMAPDATA
->m_bitmapType
; 
 470 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
) 
 472     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 473     M_BITMAPDATA
->m_hBitmap 
= bmp 
; 
 474                 M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 477 bool wxBitmap::LoadFile(const wxString
& filename
, long type
) 
 481     m_refData 
= new wxBitmapRefData
; 
 483     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 485     if ( handler 
== NULL 
) { 
 486         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 491     return handler
->LoadFile(this, filename
, type
, -1, -1); 
 494 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
) 
 498     m_refData 
= new wxBitmapRefData
; 
 500     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 502     if ( handler 
== NULL 
) { 
 503         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 508     return handler
->Create(this, data
, type
, width
, height
, depth
); 
 511 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
 513     wxCHECK_RET( image
.Ok(), wxT("invalid image") ) 
 514     wxCHECK_RET( depth 
== -1, wxT("invalid bitmap depth") ) 
 516     m_refData 
= new wxBitmapRefData(); 
 518     if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this); 
 520     // width and height of the device-dependent bitmap 
 521     int width 
= image
.GetWidth(); 
 522     int height 
= image
.GetHeight(); 
 526     Create( width 
, height 
, wxDisplayDepth() ) ; 
 527     wxBitmap 
maskBitmap( width
, height
, 1); 
 530     GDHandle origDevice 
; 
 532     LockPixels( GetGWorldPixMap(GetHBITMAP()) ); 
 533     LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) ); 
 535     GetGWorld( &origPort 
, &origDevice 
) ; 
 536     SetGWorld( GetHBITMAP() , NULL 
) ; 
 539     wxColour rgb
, maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue()); 
 541     RGBColor white 
= { 0xffff, 0xffff, 0xffff }; 
 542     RGBColor black 
= { 0     , 0     , 0      }; 
 544     register unsigned char* data 
= image
.GetData(); 
 547     for (int y 
= 0; y 
< height
; y
++) 
 549         for (int x 
= 0; x 
< width
; x
++) 
 551             rgb
.Set(data
[index
++], data
[index
++], data
[index
++]); 
 552             color 
= rgb
.GetPixel(); 
 553             SetCPixel( x 
, y 
, &color 
) ; 
 556                 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
); 
 557                 if (rgb 
== maskcolor
) { 
 558                     SetCPixel(x
,y
, &white
); 
 561                     SetCPixel(x
,y
, &black
); 
 563                 SetGWorld(GetHBITMAP(), NULL
); 
 569     if ( image
.HasMask() ) { 
 570         wxMask 
*mask 
= new wxMask( maskBitmap 
); 
 573     UnlockPixels( GetGWorldPixMap(GetHBITMAP()) ); 
 574     UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) ); 
 575     SetGWorld( origPort
, origDevice 
); 
 578 wxImage 
wxBitmap::ConvertToImage() const 
 582     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 584     // create an wxImage object 
 585     int width 
= GetWidth(); 
 586     int height 
= GetHeight(); 
 587     image
.Create( width
, height 
); 
 589     unsigned char *data 
= image
.GetData(); 
 591     wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") ); 
 597     // background color set to RGB(16,16,16) in consistent with wxGTK 
 598     unsigned char mask_r
=16, mask_g
=16, mask_b
=16; 
 600     wxMask  
*mask 
= GetMask(); 
 602     GetGWorld( &origPort
, &origDevice 
); 
 603     LockPixels(GetGWorldPixMap(GetHBITMAP())); 
 604     SetGWorld( GetHBITMAP(), NULL
); 
 606     // Copy data into image 
 608     for (int yy 
= 0; yy 
< height
; yy
++) 
 610         for (int xx 
= 0; xx 
< width
; xx
++) 
 612             GetCPixel(xx
,yy
, &color
); 
 613             r 
= ((color
.red 
) >> 8); 
 614             g 
= ((color
.green 
) >> 8); 
 615             b 
= ((color
.blue 
) >> 8); 
 621                 if (mask
->PointMasked(xx
,yy
)) 
 623                     data
[index    
] = mask_r
; 
 624                     data
[index 
+ 1] = mask_g
; 
 625                     data
[index 
+ 2] = mask_b
; 
 633         image
.SetMaskColour( mask_r
, mask_g
, mask_b 
); 
 634         image
.SetMask( true ); 
 638     UnlockPixels(GetGWorldPixMap(GetHBITMAP())); 
 639     SetGWorld(origPort
, origDevice
); 
 645 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette 
*palette
) 
 647     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 649     if ( handler 
== NULL 
) { 
 650         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 655   return handler
->SaveFile(this, filename
, type
, palette
); 
 658 bool wxBitmap::Ok() const 
 660    return (M_BITMAPDATA 
&& M_BITMAPDATA
->m_ok
); 
 663 int wxBitmap::GetHeight() const 
 665    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 667    return M_BITMAPDATA
->m_height
; 
 670 int wxBitmap::GetWidth() const 
 672    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 674    return M_BITMAPDATA
->m_width
; 
 677 int wxBitmap::GetDepth() const 
 679    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 681    return M_BITMAPDATA
->m_depth
; 
 684 int wxBitmap::GetQuality() const 
 686    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 688    return M_BITMAPDATA
->m_quality
; 
 691 wxMask 
*wxBitmap::GetMask() const 
 693    wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 695    return M_BITMAPDATA
->m_bitmapMask
; 
 698 void wxBitmap::SetWidth(int w
) 
 701         m_refData 
= new wxBitmapRefData
; 
 703     M_BITMAPDATA
->m_width 
= w
; 
 706 void wxBitmap::SetHeight(int h
) 
 709         m_refData 
= new wxBitmapRefData
; 
 711     M_BITMAPDATA
->m_height 
= h
; 
 714 void wxBitmap::SetDepth(int d
) 
 717         m_refData 
= new wxBitmapRefData
; 
 719     M_BITMAPDATA
->m_depth 
= d
; 
 722 void wxBitmap::SetQuality(int q
) 
 725         m_refData 
= new wxBitmapRefData
; 
 727     M_BITMAPDATA
->m_quality 
= q
; 
 730 void wxBitmap::SetOk(bool isOk
) 
 733         m_refData 
= new wxBitmapRefData
; 
 735     M_BITMAPDATA
->m_ok 
= isOk
; 
 738 wxPalette 
*wxBitmap::GetPalette() const 
 740    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
 742    return &M_BITMAPDATA
->m_bitmapPalette
; 
 745 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 748         m_refData 
= new wxBitmapRefData
; 
 750     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
 753 void wxBitmap::SetMask(wxMask 
*mask
) 
 756         m_refData 
= new wxBitmapRefData
; 
 758     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
 761 WXHBITMAP 
wxBitmap::GetHBITMAP() const 
 763    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 765    return M_BITMAPDATA
->m_hBitmap
; 
 768 PicHandle 
wxBitmap::GetPict() const 
 770    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 772    PicHandle picture
;       // This is the returned picture 
 774    // If bitmap already in Pict format return pointer 
 775    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) { 
 776        return M_BITMAPDATA
->m_hPict
; 
 778    else if(M_BITMAPDATA
->m_bitmapType 
!= kMacBitmapTypeGrafWorld
) { 
 783    RGBColor  gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 784    RGBColor  white 
= { 0xffff ,0xffff , 0xffff } ; 
 785    RGBColor  black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 791    GetPortBounds( GetHBITMAP() , &portRect 
) ; 
 792    int width 
= portRect
.right 
- portRect
.left 
; 
 793    int height 
= portRect
.bottom 
- portRect
.top 
; 
 795    LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 796    GetGWorld( &origPort 
, &origDev 
) ; 
 800    SetGWorld( GetHBITMAP() , NULL 
) ; 
 802    picture 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 810        RGBColor trans 
= white
; 
 812        RGBBackColor( &gray 
); 
 813        EraseRect( &portRect 
); 
 814        RGBColor trans 
= gray
; 
 816        RGBForeColor( &black 
) ; 
 817        RGBBackColor( &white 
) ; 
 818        PenMode(transparent
); 
 820        for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 822            for( int x 
= 0 ; x 
< width 
; ++x 
) 
 824                if ( !mask
->PointMasked(x
,y
) ) 
 828                    GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 829                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 832                    // With transparency this sets a blank pixel 
 833                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &trans
); 
 840        RGBBackColor( &gray 
) ; 
 841        EraseRect(&portRect
); 
 842        RGBForeColor( &black 
) ; 
 843        RGBBackColor( &white 
) ; 
 845        CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),  
 846                 // src PixMap - we copy image over itself - 
 847                 GetPortBitMapForCopyBits(GetHBITMAP()), 
 848                 //  dst PixMap - no drawing occurs 
 849                 &portRect
,    // srcRect - it will be recorded and compressed - 
 850                 &portRect
,    // dstRect - into the picture that is open - 
 851                 srcCopy
,NULL
); // copyMode and no clip region 
 853    ClosePicture();                  // We are done recording the picture 
 854    UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 855    SetGWorld( origPort 
, origDev 
) ; 
 857    return picture
;                  // return our groovy pict handle 
 860 void wxBitmap::AddHandler(wxBitmapHandler 
*handler
) 
 862     sm_handlers
.Append(handler
); 
 865 void wxBitmap::InsertHandler(wxBitmapHandler 
*handler
) 
 867     sm_handlers
.Insert(handler
); 
 870 bool wxBitmap::RemoveHandler(const wxString
& name
) 
 872     wxBitmapHandler 
*handler 
= FindHandler(name
); 
 875         sm_handlers
.DeleteObject(handler
); 
 882 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& name
) 
 884     wxNode 
*node 
= sm_handlers
.First(); 
 887         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 888         if ( handler
->GetName() == name 
) 
 895 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
) 
 897     wxNode 
*node 
= sm_handlers
.First(); 
 900         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 901         if ( handler
->GetExtension() == extension 
&& 
 902                     (bitmapType 
== -1 || handler
->GetType() == bitmapType
) ) 
 909 wxBitmapHandler 
*wxBitmap::FindHandler(long bitmapType
) 
 911     wxNode 
*node 
= sm_handlers
.First(); 
 914         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 915         if (handler
->GetType() == bitmapType
) 
 931 // Construct a mask from a bitmap and a colour indicating 
 932 // the transparent area 
 933 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 936     Create(bitmap
, colour
); 
 939 // Construct a mask from a bitmap and a palette index indicating 
 940 // the transparent area 
 941 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
 944     Create(bitmap
, paletteIndex
); 
 947 // Construct a mask from a mono bitmap (copies the bitmap). 
 948 wxMask::wxMask(const wxBitmap
& bitmap
) 
 958                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
 959                 m_maskBitmap 
= NULL 
; 
 963 // Create a mask from a mono bitmap (copies the bitmap). 
 964 bool wxMask::Create(const wxBitmap
& bitmap
) 
 968        wxMacDestroyGWorld( m_maskBitmap 
) ; 
 969        m_maskBitmap 
= NULL 
; 
 971    wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
 972                 wxT("Cannot create mask from this bitmap type (TODO)")); 
 973    // other types would require a temporary bitmap. not yet implemented 
 975    wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap")); 
 977    wxCHECK_MSG(bitmap
.GetDepth() == 1, false, 
 978                wxT("Cannot create mask from colour bitmap")); 
 980    m_maskBitmap 
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1); 
 981    Rect rect 
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() }; 
 983    LockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
 984    LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
 985    CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()), 
 986             GetPortBitMapForCopyBits(m_maskBitmap
), 
 987             &rect
, &rect
, srcCopy
, 0); 
 988    UnlockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
 989    UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
 994 // Create a mask from a bitmap and a palette index indicating 
 995 // the transparent area 
 996 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
 999     wxCHECK_MSG( 0, false, wxT("Not implemented")); 
1003 // Create a mask from a bitmap and a colour indicating 
1004 // the transparent area 
1005 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
1009                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
1010                 m_maskBitmap 
= NULL 
; 
1012         wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
1013                  wxT("Cannot create mask from this bitmap type (TODO)")); 
1014         // other types would require a temporary bitmap. not yet implemented  
1016     wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap")); 
1018         m_maskBitmap 
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );  
1019         LockPixels( GetGWorldPixMap( m_maskBitmap 
) ); 
1020         LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ); 
1021         RGBColor maskColor 
= colour
.GetPixel(); 
1023     // this is not very efficient, but I can't think 
1024     // of a better way of doing it 
1026         GDHandle        origDevice 
; 
1028     RGBColor  colors
[2] = { 
1029         { 0xFFFF, 0xFFFF, 0xFFFF }, 
1032         GetGWorld( &origPort 
, &origDevice 
) ; 
1033         for (int w 
= 0; w 
< bitmap
.GetWidth(); w
++) 
1035         for (int h 
= 0; h 
< bitmap
.GetHeight(); h
++) 
1037                         SetGWorld( bitmap
.GetHBITMAP(), NULL 
) ; 
1038                         GetCPixel( w 
, h 
, &col 
) ; 
1039                         SetGWorld( m_maskBitmap 
, NULL 
) ; 
1040             if (col
.red 
== maskColor
.red 
&& col
.green 
== maskColor
.green 
&& col
.blue 
== maskColor
.blue
) 
1042                                 SetCPixel( w 
, h 
, &colors
[0] ) ; 
1046                                 SetCPixel( w 
, h 
, &colors
[1] ) ; 
1050         UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap 
) ) ; 
1051         UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ; 
1052         SetGWorld( origPort 
, origDevice 
) ; 
1057 bool wxMask::PointMasked(int x
, int y
) 
1060    GDHandle  origDevice
; 
1064    GetGWorld( &origPort
, &origDevice
); 
1066    //Set port to mask and see if it masked (1) or not ( 0 ) 
1067    SetGWorld(m_maskBitmap
, NULL
); 
1068    LockPixels(GetGWorldPixMap(m_maskBitmap
)); 
1069    GetCPixel(x
,y
, &color
); 
1070    masked 
= !(color
.red 
== 0 && color
.green 
== 0 && color
.blue 
== 0); 
1071    UnlockPixels(GetGWorldPixMap(m_maskBitmap
)); 
1073    SetGWorld( origPort
, origDevice
); 
1082 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
1084 bool wxBitmapHandler::Create(wxBitmap 
*bitmap
, void *data
, long type
, int width
, int height
, int depth
) 
1089 bool wxBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long type
, 
1090         int desiredWidth
, int desiredHeight
) 
1095 bool wxBitmapHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1104 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
1106     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
1108     inline wxPICTResourceHandler() 
1110         m_name 
= "Macintosh Pict resource"; 
1112         m_type 
= wxBITMAP_TYPE_PICT_RESOURCE
; 
1115     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1116           int desiredWidth
, int desiredHeight
); 
1118 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
1120 bool  wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1121           int desiredWidth
, int desiredHeight
) 
1126         c2pstrcpy( (StringPtr
) theName 
, name 
) ; 
1128         strcpy( (char *) theName 
, name 
) ; 
1129         c2pstr( (char *)theName 
) ; 
1132         PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1137                 GetPictInfo( thePict 
, &theInfo 
, 0 , 0 , systemMethod 
, 0 ) ; 
1138                 DetachResource( (Handle
) thePict 
) ; 
1139                 M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypePict 
; 
1140                 M_BITMAPHANDLERDATA
->m_hPict 
= thePict 
; 
1141                 M_BITMAPHANDLERDATA
->m_width 
=  theInfo
.sourceRect
.right 
- theInfo
.sourceRect
.left 
; 
1142                 M_BITMAPHANDLERDATA
->m_height 
= theInfo
.sourceRect
.bottom 
- theInfo
.sourceRect
.top 
; 
1144                 M_BITMAPHANDLERDATA
->m_depth 
= theInfo
.depth 
; 
1145                 M_BITMAPHANDLERDATA
->m_ok 
= true ; 
1146                 M_BITMAPHANDLERDATA
->m_numColors 
= theInfo
.uniqueColors 
; 
1147 //              M_BITMAPHANDLERDATA->m_bitmapPalette; 
1148 //              M_BITMAPHANDLERDATA->m_quality; 
1154 /* TODO: bitmap handlers, a bit like this: 
1155 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler 
1157     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) 
1159     inline wxBMPResourceHandler() 
1161         m_name = "Windows bitmap resource"; 
1163         m_type = wxBITMAP_TYPE_BMP_RESOURCE; 
1166     virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, 
1167           int desiredWidth, int desiredHeight); 
1169 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) 
1172 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
 
1174   DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
) 
1176   inline wxXPMFileHandler(void) 
1178   m_name 
= "XPM bitmap file"; 
1179   m_extension 
= "xpm"; 
1180   m_type 
= wxBITMAP_TYPE_XPM
; 
1183   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1184     int desiredWidth 
= -1, int desiredHeight 
= -1); 
1185   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1187 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
) 
1189 bool wxXPMFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1190     int desiredWidth
, int desiredHeight
) 
1194     XpmAttributes xpmAttr
; 
1197     M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1198     dc 
= CreateCompatibleDC(NULL
); 
1201       xpmAttr
.valuemask 
= XpmReturnPixels
; 
1202       int errorStatus 
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage 
**) NULL
, &xpmAttr
); 
1204       if (errorStatus 
== XpmSuccess
) 
1206         M_BITMAPHANDLERDATA
->m_hBitmap 
= (WXHBITMAP
) ximage
->bitmap
; 
1209         GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
); 
1211         M_BITMAPHANDLERDATA
->m_width 
= (bm
.bmWidth
); 
1212         M_BITMAPHANDLERDATA
->m_height 
= (bm
.bmHeight
); 
1213         M_BITMAPHANDLERDATA
->m_depth 
= (bm
.bmPlanes 
* bm
.bmBitsPixel
); 
1214         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1215         XpmFreeAttributes(&xpmAttr
); 
1218         M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1223         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1232 bool wxXPMFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1237       Visual 
*visual 
= NULL
; 
1240       dc 
= CreateCompatibleDC(NULL
); 
1243         if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
)) 
1246     ximage
.width 
= M_BITMAPHANDLERDATA
->m_width
;  
1247      ximage
.height 
= M_BITMAPHANDLERDATA
->m_height
; 
1248     ximage
.depth 
= M_BITMAPHANDLERDATA
->m_depth
;  
1249      ximage
.bitmap 
= (void *)M_BITMAPHANDLERDATA
->m_hBitmap
; 
1250     int errorStatus 
= XpmWriteFileFromImage(&dc
, WXSTRINGCAST name
, 
1251               &ximage
, (XImage 
*) NULL
, (XpmAttributes 
*) NULL
); 
1256     if (errorStatus 
== XpmSuccess
) 
1260         } else return FALSE
; 
1261       } else return FALSE
; 
1268 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
 
1270   DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
) 
1272   inline wxXPMDataHandler(void) 
1274   m_name 
= "XPM bitmap data"; 
1275   m_extension 
= "xpm"; 
1276   m_type 
= wxBITMAP_TYPE_XPM_DATA
; 
1279   virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth 
= 1); 
1281 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
) 
1283 bool wxXPMDataHandler::Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
) 
1285         XImage 
*                ximage 
= NULL 
; 
1286         XImage 
*                xshapeimage 
= NULL 
; 
1288         XpmAttributes   xpmAttr
; 
1290     xpmAttr
.valuemask 
= XpmReturnInfos
; // get infos back 
1291     ErrorStatus 
= XpmCreateImageFromData( GetMainDevice() , (char **)data
, 
1292          &ximage
, &xshapeimage
, &xpmAttr
); 
1294     if (ErrorStatus 
== XpmSuccess
) 
1296                         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1297                         M_BITMAPHANDLERDATA
->m_numColors 
= 0; 
1298                         M_BITMAPHANDLERDATA
->m_hBitmap 
= ximage
->gworldptr 
; 
1300                         M_BITMAPHANDLERDATA
->m_width 
= ximage
->width
; 
1301                         M_BITMAPHANDLERDATA
->m_height 
= ximage
->height
; 
1302                         M_BITMAPHANDLERDATA
->m_depth 
= ximage
->depth
; 
1303                         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1304         XpmFreeAttributes(&xpmAttr
); 
1305             M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1306                         ximage
->gworldptr 
= NULL 
; 
1307                         XImageFree(ximage
); // releases the malloc, but does not detroy 
1309                         M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
1310                         if ( xshapeimage 
!= NULL 
) 
1312                                 wxMask
* m 
= new wxMask() ; 
1313                                 m
->SetMaskBitmap( xshapeimage
->gworldptr 
) ; 
1314                                 M_BITMAPHANDLERDATA
->m_bitmapMask 
= m 
; 
1320       M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1326 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
 
1328     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
) 
1330     inline wxBMPResourceHandler() 
1332         m_name 
= "Windows bitmap resource"; 
1334         m_type 
= wxBITMAP_TYPE_BMP_RESOURCE
; 
1337     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1338           int desiredWidth
, int desiredHeight
); 
1341 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
) 
1343 bool wxBMPResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1344     int desiredWidth
, int desiredHeight
) 
1346     // TODO: load colourmap. 
1347   // it's probably not found 
1348   wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str()); 
1353 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
 
1355   DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
) 
1357   inline wxBMPFileHandler(void) 
1359   m_name 
= "Windows bitmap file"; 
1360   m_extension 
= "bmp"; 
1361   m_type 
= wxBITMAP_TYPE_BMP
; 
1364   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1365       int desiredWidth
, int desiredHeight
); 
1366   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1369 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
) 
1371 bool wxBMPFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1372     int desiredWidth
, int desiredHeight
) 
1374 #if USE_IMAGE_LOADING_IN_MSW 
1375     wxPalette 
*palette 
= NULL
; 
1376     bool success 
= FALSE
; 
1377     success 
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0); 
1378     if (!success 
&& palette
) 
1384       M_BITMAPHANDLERDATA
->m_bitmapPalette 
= *palette
; 
1391 bool wxBMPFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*pal
) 
1393 #if USE_IMAGE_LOADING_IN_MSW 
1394     wxPalette 
*actualPalette 
= (wxPalette 
*)pal
; 
1395     if (!actualPalette 
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull())) 
1396       actualPalette 
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
); 
1397     return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0); 
1404 void wxBitmap::CleanUpHandlers() 
1406     wxNode 
*node 
= sm_handlers
.First(); 
1409         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
1410         wxNode 
*next 
= node
->Next(); 
1417 void wxBitmap::InitStandardHandlers() 
1419         AddHandler( new wxPICTResourceHandler 
) ; 
1420         AddHandler( new wxICONResourceHandler 
) ; 
1421         AddHandler(new wxXPMFileHandler
); 
1422         AddHandler(new wxXPMDataHandler
); 
1423         AddHandler(new wxBMPResourceHandler
); 
1424         AddHandler(new wxBMPFileHandler
);