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" 
  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 CTabHandle 
wxMacCreateColorTable( int numColors 
) 
  46         CTabHandle newColors
; /* Handle to the new color table */ 
  48         /* Allocate memory for the color table */ 
  49         newColors 
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) + 
  50         sizeof (ColorSpec
) * (numColors 
- 1) ); 
  53                 /* Initialize the fields */ 
  54                 (**newColors
).ctSeed 
= GetCTSeed(); 
  55                 (**newColors
).ctFlags 
= 0; 
  56                 (**newColors
).ctSize 
= numColors 
- 1; 
  57                 /* Initialize the table of colors */ 
  62 void wxMacDestroyColorTable( CTabHandle colors 
)  
  64         DisposeHandle( (Handle
) colors 
) ; 
  67 void wxMacSetColorTableEntry( CTabHandle newColors 
, int index 
, int red 
, int green 
,  int blue 
) 
  69         (**newColors
).ctTable
[index
].value 
= index
; 
  70         (**newColors
).ctTable
[index
].rgb
.red 
= 0 ;// someRedValue; 
  71         (**newColors
).ctTable
[index
].rgb
.green 
= 0 ; // someGreenValue; 
  72         (**newColors
).ctTable
[index
].rgb
.blue 
= 0 ; // someBlueValue; 
  75 GWorldPtr 
wxMacCreateGWorld( int width 
, int height 
, int depth 
) 
  79         Rect rect 
= { 0 , 0 , height 
, width 
} ; 
  83                 depth 
= wxDisplayDepth() ;      
  86         err 
= NewGWorld( &port 
, depth 
, &rect 
, NULL 
, NULL 
, 0 ) ; 
  94 void wxMacDestroyGWorld( GWorldPtr gw 
) 
 100 PicHandle 
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
) 
 105    PicHandle      pict
;          // this is the Picture we give back 
 107    RGBColor    gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 108    RGBColor    white 
= { 0xffff ,0xffff , 0xffff } ; 
 109    RGBColor    black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 111    unsigned char *maskimage 
= NULL 
; 
 113    GetPortBounds( wp 
, &portRect 
) ; 
 114    int width 
= portRect
.right 
- portRect
.left 
; 
 115    int height 
= portRect
.bottom 
- portRect
.top 
; 
 117    LockPixels( GetGWorldPixMap( wp 
) ) ; 
 118    GetGWorld( &origPort 
, &origDev 
) ; 
 122       maskimage 
= (unsigned char*) malloc( width 
* height 
) ; 
 123       SetGWorld( mask 
, NULL 
) ; 
 124       LockPixels( GetGWorldPixMap( mask 
) ) ; 
 125       for ( int y 
= 0 ; y 
< height 
; y
++ ) 
 127          for( int x 
= 0 ; x 
< width 
; x
++ ) 
 131             GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 132             maskimage
[y
*width 
+ x
] = ( col
.red 
== 0 ) ; // for monochrome masks 
 135       UnlockPixels( GetGWorldPixMap( mask 
) ) ; 
 138    SetGWorld( wp 
, NULL 
) ; 
 140    pict 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 146       RGBForeColor( &black 
) ; 
 147       RGBBackColor( &white 
) ; 
 148       PenMode(transparent
); 
 150       for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 152          for( int x 
= 0 ; x 
< width 
; ++x 
) 
 154             if ( maskimage
[y
*width 
+ x
] ) 
 158                GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 159                SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 162                 // With transparency set this sets a blank pixel not a white one 
 163                 SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &white
); 
 172       RGBBackColor( &gray 
) ; 
 173       EraseRect(&portRect
); 
 174       RGBForeColor( &black 
) ; 
 175       RGBBackColor( &white 
) ; 
 177       CopyBits(GetPortBitMapForCopyBits(wp
), /* src PixMap - we copy image over 
 179                GetPortBitMapForCopyBits(wp
), //  dst PixMap - no drawing occurs 
 180                &portRect
,    // srcRect - it will be recorded and compressed - 
 181                &portRect
,    // dstRect - into the picture that is open - 
 182                srcCopy
,NULL
); // copyMode and no clip region 
 184    ClosePicture();                  // We are done recording the picture 
 185    UnlockPixels( GetGWorldPixMap( wp 
) ) ; 
 186    SetGWorld( origPort 
, origDev 
) ; 
 188    return pict
;                  // return our groovy pict handle 
 191 wxBitmapRefData::wxBitmapRefData() 
 202                 m_bitmapType 
= kMacBitmapTypeUnknownType 
; 
 205 wxBitmapRefData::~wxBitmapRefData() 
 207         switch (m_bitmapType
) 
 209                 case kMacBitmapTypePict 
: 
 213                                         KillPicture( m_hPict 
) ; 
 218                 case kMacBitmapTypeGrafWorld 
: 
 222                                         wxMacDestroyGWorld( m_hBitmap 
) ; 
 239 wxList 
wxBitmap::sm_handlers
; 
 245     if ( wxTheBitmapList 
) 
 246         wxTheBitmapList
->AddBitmap(this); 
 249 wxBitmap::~wxBitmap() 
 252         wxTheBitmapList
->DeleteObject(this); 
 255 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
) 
 257     m_refData 
= new wxBitmapRefData
; 
 259     M_BITMAPDATA
->m_width 
= the_width 
; 
 260     M_BITMAPDATA
->m_height 
= the_height 
; 
 261     M_BITMAPDATA
->m_depth 
= no_bits 
; 
 262     M_BITMAPDATA
->m_numColors 
= 0; 
 265                 M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 266                 M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( the_width 
, the_height 
, no_bits 
) ; 
 267                         M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 270                         GDHandle        origDevice 
; 
 272                         GetGWorld( &origPort 
, &origDevice 
) ; 
 273                         SetGWorld( M_BITMAPDATA
->m_hBitmap 
, NULL 
) ; 
 274                         LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 277            // bits is a word aligned array?? Don't think so 
 278            // bits is a char array on MAC OS X however using the benefit of the 
 279            // doubt I replaced references to 16 with sizeof(unsigned char)*8 
 280            unsigned char* linestart 
= (unsigned char*) bits 
; 
 281            int linesize 
= ( the_width 
/ (sizeof(unsigned char) * 8)) ; 
 282            if ( the_width 
% (sizeof(unsigned char) * 8) ) { 
 283                linesize 
+= sizeof(unsigned char); 
 286                         // bits is a word aligned array 
 288                         unsigned char* linestart 
= (unsigned char*) bits 
; 
 289                         int linesize 
= ( the_width 
/ 16 ) * 2  ; 
 290                         if ( the_width 
% 16 ) 
 296                         RGBColor colors
[2] = {  
 297                                 { 0xFFFF , 0xFFFF , 0xFFFF } , 
 301                         for ( int y 
= 0 ; y 
< the_height 
; ++y 
, linestart 
+= linesize 
) 
 303                                 for ( int x 
= 0 ; x 
< the_width 
; ++x 
) 
 307                                         int mask 
= 1 << bit 
; 
 308                                         if ( linestart
[index
] & mask 
) 
 310                                                 SetCPixel( x 
, y 
, &colors
[1] ) ; 
 314                                                 SetCPixel( x 
, y 
, &colors
[0] ) ; 
 319                 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap 
) ) ; 
 321                 SetGWorld( origPort 
, origDevice 
) ; 
 325          wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); 
 328     if ( wxTheBitmapList 
) 
 329         wxTheBitmapList
->AddBitmap(this); 
 332 wxBitmap::wxBitmap(int w
, int h
, int d
) 
 334     (void)Create(w
, h
, d
); 
 336     if ( wxTheBitmapList 
) 
 337         wxTheBitmapList
->AddBitmap(this); 
 340 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
) 
 342     (void) Create(data
, type
, width
, height
, depth
); 
 344     if ( wxTheBitmapList 
) 
 345         wxTheBitmapList
->AddBitmap(this); 
 348 wxBitmap::wxBitmap(const wxString
& filename
, long type
) 
 350     LoadFile(filename
, (int)type
); 
 352     if ( wxTheBitmapList 
) 
 353         wxTheBitmapList
->AddBitmap(this); 
 356 wxBitmap::wxBitmap(const char **data
) 
 358     (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 361 wxBitmap::wxBitmap(char **data
) 
 363     (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0); 
 366 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect 
&rect
) const 
 369                 (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 370                 (rect
.x
+rect
.width 
<= GetWidth()) && 
 371                 (rect
.y
+rect
.height 
<= GetHeight()), 
 372                 wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 375    wxBitmap 
ret( rect
.width
, rect
.height
, GetDepth() ); 
 376    wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 381    GetGWorld( &origPort
, &origDevice 
); 
 383    // Update the subbitmaps reference data 
 384    wxBitmapRefData 
*ref 
= (wxBitmapRefData 
*)ret
.GetRefData(); 
 386    ref
->m_numColors     
= M_BITMAPDATA
->m_numColors
; 
 387    ref
->m_bitmapPalette 
= M_BITMAPDATA
->m_bitmapPalette
; 
 388    ref
->m_bitmapType    
= M_BITMAPDATA
->m_bitmapType
; 
 390    // Copy sub region of this bitmap 
 391    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) 
 393        printf("GetSubBitmap:  Copy a region of a Pict structure - TODO\n"); 
 395    else if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypeGrafWorld
) 
 400            WXHBITMAP submask
, mask
; 
 403            mask 
= GetMask()->GetMaskBitmap(); 
 404            submask 
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1); 
 405            LockPixels(GetGWorldPixMap(mask
)); 
 406            LockPixels(GetGWorldPixMap(submask
)); 
 408            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 410                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 412                    SetGWorld(mask
, NULL
); 
 413                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 414                    SetGWorld(submask
, NULL
); 
 415                    SetCPixel(xx
,yy
, &color
); 
 418            UnlockPixels(GetGWorldPixMap(mask
)); 
 419            UnlockPixels(GetGWorldPixMap(submask
)); 
 420            ref
->m_bitmapMask 
= new wxMask
; 
 421            ref
->m_bitmapMask
->SetMaskBitmap(submask
); 
 427            WXHBITMAP subbitmap
, bitmap
; 
 430            bitmap 
= GetHBITMAP(); 
 431            subbitmap 
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth()); 
 432            LockPixels(GetGWorldPixMap(bitmap
)); 
 433            LockPixels(GetGWorldPixMap(subbitmap
)); 
 435            for(int yy 
= 0; yy 
< rect
.height
; yy
++) 
 437                for(int xx 
= 0; xx 
< rect
.width
; xx
++) 
 439                    SetGWorld(bitmap
, NULL
); 
 440                    GetCPixel(rect
.x 
+ xx
, rect
.y 
+ yy
, &color
); 
 441                    SetGWorld(subbitmap
, NULL
); 
 442                    SetCPixel(xx
, yy
, &color
); 
 445            UnlockPixels(GetGWorldPixMap(bitmap
)); 
 446            UnlockPixels(GetGWorldPixMap(subbitmap
)); 
 447            ret
.SetHBITMAP(subbitmap
); 
 450    SetGWorld( origPort
, origDevice 
); 
 455 bool wxBitmap::Create(int w
, int h
, int d
) 
 459     m_refData 
= new wxBitmapRefData
; 
 461     M_BITMAPDATA
->m_width 
= w
; 
 462     M_BITMAPDATA
->m_height 
= h
; 
 463     M_BITMAPDATA
->m_depth 
= d
; 
 465     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 466     M_BITMAPDATA
->m_hBitmap 
= wxMacCreateGWorld( w 
, h 
, d 
) ; 
 467                 M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 468     return M_BITMAPDATA
->m_ok
; 
 471 int wxBitmap::GetBitmapType() const 
 473    wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") ); 
 475    return M_BITMAPDATA
->m_bitmapType
; 
 478 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
) 
 480     M_BITMAPDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
 481     M_BITMAPDATA
->m_hBitmap 
= bmp 
; 
 482                 M_BITMAPDATA
->m_ok 
= (M_BITMAPDATA
->m_hBitmap 
!= NULL 
) ; 
 485 bool wxBitmap::LoadFile(const wxString
& filename
, long type
) 
 489     m_refData 
= new wxBitmapRefData
; 
 491     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 493     if ( handler 
== NULL 
) { 
 494         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 499     return handler
->LoadFile(this, filename
, type
, -1, -1); 
 502 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
) 
 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
->Create(this, data
, type
, width
, height
, depth
); 
 519 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette 
*palette
) 
 521     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 523     if ( handler 
== NULL 
) { 
 524         wxLogWarning("no bitmap handler for type %d defined.", type
); 
 529   return handler
->SaveFile(this, filename
, type
, palette
); 
 532 bool wxBitmap::Ok() const 
 534    return (M_BITMAPDATA 
&& M_BITMAPDATA
->m_ok
); 
 537 int wxBitmap::GetHeight() const 
 539    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 541    return M_BITMAPDATA
->m_height
; 
 544 int wxBitmap::GetWidth() const 
 546    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 548    return M_BITMAPDATA
->m_width
; 
 551 int wxBitmap::GetDepth() const 
 553    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 555    return M_BITMAPDATA
->m_depth
; 
 558 int wxBitmap::GetQuality() const 
 560    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 562    return M_BITMAPDATA
->m_quality
; 
 565 wxMask 
*wxBitmap::GetMask() const 
 567    wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 569    return M_BITMAPDATA
->m_bitmapMask
; 
 572 void wxBitmap::SetWidth(int w
) 
 575         m_refData 
= new wxBitmapRefData
; 
 577     M_BITMAPDATA
->m_width 
= w
; 
 580 void wxBitmap::SetHeight(int h
) 
 583         m_refData 
= new wxBitmapRefData
; 
 585     M_BITMAPDATA
->m_height 
= h
; 
 588 void wxBitmap::SetDepth(int d
) 
 591         m_refData 
= new wxBitmapRefData
; 
 593     M_BITMAPDATA
->m_depth 
= d
; 
 596 void wxBitmap::SetQuality(int q
) 
 599         m_refData 
= new wxBitmapRefData
; 
 601     M_BITMAPDATA
->m_quality 
= q
; 
 604 void wxBitmap::SetOk(bool isOk
) 
 607         m_refData 
= new wxBitmapRefData
; 
 609     M_BITMAPDATA
->m_ok 
= isOk
; 
 612 wxPalette 
*wxBitmap::GetPalette() const 
 614    wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap  GetPalette()") ); 
 616    return &M_BITMAPDATA
->m_bitmapPalette
; 
 619 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 622         m_refData 
= new wxBitmapRefData
; 
 624     M_BITMAPDATA
->m_bitmapPalette 
= palette 
; 
 627 void wxBitmap::SetMask(wxMask 
*mask
) 
 630         m_refData 
= new wxBitmapRefData
; 
 632     M_BITMAPDATA
->m_bitmapMask 
= mask 
; 
 635 WXHBITMAP 
wxBitmap::GetHBITMAP() const 
 637    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 639    return M_BITMAPDATA
->m_hBitmap
; 
 642 PicHandle 
wxBitmap::GetPict() const 
 644    wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 646    PicHandle picture
;       // This is the returned picture 
 648    // If bitmap already in Pict format return pointer 
 649    if(M_BITMAPDATA
->m_bitmapType 
== kMacBitmapTypePict
) { 
 650        return M_BITMAPDATA
->m_hPict
; 
 652    else if(M_BITMAPDATA
->m_bitmapType 
!= kMacBitmapTypeGrafWorld
) { 
 657    RGBColor  gray 
= { 0xCCCC ,0xCCCC , 0xCCCC } ; 
 658    RGBColor  white 
= { 0xffff ,0xffff , 0xffff } ; 
 659    RGBColor  black 
= { 0x0000 ,0x0000 , 0x0000 } ; 
 665    GetPortBounds( GetHBITMAP() , &portRect 
) ; 
 666    int width 
= portRect
.right 
- portRect
.left 
; 
 667    int height 
= portRect
.bottom 
- portRect
.top 
; 
 669    LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 670    GetGWorld( &origPort 
, &origDev 
) ; 
 674    SetGWorld( GetHBITMAP() , NULL 
) ; 
 676    picture 
= OpenPicture(&portRect
);   // open a picture, this disables drawing 
 684        RGBColor trans 
= white
; 
 686        RGBBackColor( &gray 
); 
 687        EraseRect( &portRect 
); 
 688        RGBColor trans 
= gray
; 
 690        RGBForeColor( &black 
) ; 
 691        RGBBackColor( &white 
) ; 
 692        PenMode(transparent
); 
 694        for ( int y 
= 0 ; y 
< height 
; ++y 
) 
 696            for( int x 
= 0 ; x 
< width 
; ++x 
) 
 698                if ( !mask
->PointMasked(x
,y
) ) 
 702                    GetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 703                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &col 
) ; 
 706                    // With transparency this sets a blank pixel 
 707                    SetCPixel( x 
+ portRect
.left 
, y 
+ portRect
.top 
, &trans
); 
 714        RGBBackColor( &gray 
) ; 
 715        EraseRect(&portRect
); 
 716        RGBForeColor( &black 
) ; 
 717        RGBBackColor( &white 
) ; 
 719        CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),  
 720                 // src PixMap - we copy image over itself - 
 721                 GetPortBitMapForCopyBits(GetHBITMAP()), 
 722                 //  dst PixMap - no drawing occurs 
 723                 &portRect
,    // srcRect - it will be recorded and compressed - 
 724                 &portRect
,    // dstRect - into the picture that is open - 
 725                 srcCopy
,NULL
); // copyMode and no clip region 
 727    ClosePicture();                  // We are done recording the picture 
 728    UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; 
 729    SetGWorld( origPort 
, origDev 
) ; 
 731    return picture
;                  // return our groovy pict handle 
 734 void wxBitmap::AddHandler(wxBitmapHandler 
*handler
) 
 736     sm_handlers
.Append(handler
); 
 739 void wxBitmap::InsertHandler(wxBitmapHandler 
*handler
) 
 741     sm_handlers
.Insert(handler
); 
 744 bool wxBitmap::RemoveHandler(const wxString
& name
) 
 746     wxBitmapHandler 
*handler 
= FindHandler(name
); 
 749         sm_handlers
.DeleteObject(handler
); 
 756 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& name
) 
 758     wxNode 
*node 
= sm_handlers
.First(); 
 761         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 762         if ( handler
->GetName() == name 
) 
 769 wxBitmapHandler 
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
) 
 771     wxNode 
*node 
= sm_handlers
.First(); 
 774         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 775         if ( handler
->GetExtension() == extension 
&& 
 776                     (bitmapType 
== -1 || handler
->GetType() == bitmapType
) ) 
 783 wxBitmapHandler 
*wxBitmap::FindHandler(long bitmapType
) 
 785     wxNode 
*node 
= sm_handlers
.First(); 
 788         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
 789         if (handler
->GetType() == bitmapType
) 
 805 // Construct a mask from a bitmap and a colour indicating 
 806 // the transparent area 
 807 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 810     Create(bitmap
, colour
); 
 813 // Construct a mask from a bitmap and a palette index indicating 
 814 // the transparent area 
 815 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
 818     Create(bitmap
, paletteIndex
); 
 821 // Construct a mask from a mono bitmap (copies the bitmap). 
 822 wxMask::wxMask(const wxBitmap
& bitmap
) 
 832                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
 833                 m_maskBitmap 
= NULL 
; 
 837 // Create a mask from a mono bitmap (copies the bitmap). 
 838 bool wxMask::Create(const wxBitmap
& bitmap
) 
 842        wxMacDestroyGWorld( m_maskBitmap 
) ; 
 843        m_maskBitmap 
= NULL 
; 
 845    wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
 846                 wxT("Cannot create mask from this bitmap type (TODO)")); 
 847    // other types would require a temporary bitmap. not yet implemented 
 849    wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap")); 
 851    wxCHECK_MSG(bitmap
.GetDepth() == 1, false, 
 852                wxT("Cannot create mask from colour bitmap")); 
 854    m_maskBitmap 
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1); 
 855    Rect rect 
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() }; 
 857    LockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
 858    LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
 859    CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()), 
 860             GetPortBitMapForCopyBits(m_maskBitmap
), 
 861             &rect
, &rect
, srcCopy
, 0); 
 862    UnlockPixels( GetGWorldPixMap(m_maskBitmap
) ); 
 863    UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) ); 
 868 // Create a mask from a bitmap and a palette index indicating 
 869 // the transparent area 
 870 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
 873     wxCHECK_MSG( 0, false, wxT("Not implemented")); 
 877 // Create a mask from a bitmap and a colour indicating 
 878 // the transparent area 
 879 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 883                 wxMacDestroyGWorld( m_maskBitmap 
) ; 
 884                 m_maskBitmap 
= NULL 
; 
 886         wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false, 
 887                  wxT("Cannot create mask from this bitmap type (TODO)")); 
 888         // other types would require a temporary bitmap. not yet implemented  
 890     wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap")); 
 892         m_maskBitmap 
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );  
 893         LockPixels( GetGWorldPixMap( m_maskBitmap 
) ); 
 894         LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ); 
 895         RGBColor maskColor 
= colour
.GetPixel(); 
 897     // this is not very efficient, but I can't think 
 898     // of a better way of doing it 
 900         GDHandle        origDevice 
; 
 902     RGBColor  colors
[2] = { 
 903         { 0xFFFF, 0xFFFF, 0xFFFF }, 
 906         GetGWorld( &origPort 
, &origDevice 
) ; 
 907         for (int w 
= 0; w 
< bitmap
.GetWidth(); w
++) 
 909         for (int h 
= 0; h 
< bitmap
.GetHeight(); h
++) 
 911                         SetGWorld( bitmap
.GetHBITMAP(), NULL 
) ; 
 912                         GetCPixel( w 
, h 
, &col 
) ; 
 913                         SetGWorld( m_maskBitmap 
, NULL 
) ; 
 914             if (col
.red 
== maskColor
.red 
&& col
.green 
== maskColor
.green 
&& col
.blue 
== maskColor
.blue
) 
 916                                 SetCPixel( w 
, h 
, &colors
[0] ) ; 
 920                                 SetCPixel( w 
, h 
, &colors
[1] ) ; 
 924         UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap 
) ) ; 
 925         UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ; 
 926         SetGWorld( origPort 
, origDevice 
) ; 
 931 bool wxMask::PointMasked(int x
, int y
) 
 938    GetGWorld( &origPort
, &origDevice
); 
 940    //Set port to mask and see if it masked (1) or not ( 0 ) 
 941    SetGWorld(m_maskBitmap
, NULL
); 
 942    LockPixels(GetGWorldPixMap(m_maskBitmap
)); 
 943    GetCPixel(x
,y
, &color
); 
 944    masked 
= !(color
.red 
== 0 && color
.green 
== 0 && color
.blue 
== 0); 
 945    UnlockPixels(GetGWorldPixMap(m_maskBitmap
)); 
 947    SetGWorld( origPort
, origDevice
); 
 956 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
 958 bool wxBitmapHandler::Create(wxBitmap 
*bitmap
, void *data
, long type
, int width
, int height
, int depth
) 
 963 bool wxBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long type
, 
 964         int desiredWidth
, int desiredHeight
) 
 969 bool wxBitmapHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
 978 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
 
 980     DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
) 
 982     inline wxPICTResourceHandler() 
 984         m_name 
= "Macintosh Pict resource"; 
 986         m_type 
= wxBITMAP_TYPE_PICT_RESOURCE
; 
 989     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 990           int desiredWidth
, int desiredHeight
); 
 992 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
) 
 994 bool  wxPICTResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 995           int desiredWidth
, int desiredHeight
) 
1000         c2pstrcpy( (StringPtr
) theName 
, name 
) ; 
1002         strcpy( (char *) theName 
, name 
) ; 
1003         c2pstr( (char *)theName 
) ; 
1006         PicHandle thePict 
= (PicHandle 
) GetNamedResource( 'PICT' , theName 
) ; 
1011                 GetPictInfo( thePict 
, &theInfo 
, 0 , 0 , systemMethod 
, 0 ) ; 
1012                 DetachResource( (Handle
) thePict 
) ; 
1013                 M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypePict 
; 
1014                 M_BITMAPHANDLERDATA
->m_hPict 
= thePict 
; 
1015                 M_BITMAPHANDLERDATA
->m_width 
=  theInfo
.sourceRect
.right 
- theInfo
.sourceRect
.left 
; 
1016                 M_BITMAPHANDLERDATA
->m_height 
= theInfo
.sourceRect
.bottom 
- theInfo
.sourceRect
.top 
; 
1018                 M_BITMAPHANDLERDATA
->m_depth 
= theInfo
.depth 
; 
1019                 M_BITMAPHANDLERDATA
->m_ok 
= true ; 
1020                 M_BITMAPHANDLERDATA
->m_numColors 
= theInfo
.uniqueColors 
; 
1021 //              M_BITMAPHANDLERDATA->m_bitmapPalette; 
1022 //              M_BITMAPHANDLERDATA->m_quality; 
1028 /* TODO: bitmap handlers, a bit like this: 
1029 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler 
1031     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) 
1033     inline wxBMPResourceHandler() 
1035         m_name = "Windows bitmap resource"; 
1037         m_type = wxBITMAP_TYPE_BMP_RESOURCE; 
1040     virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, 
1041           int desiredWidth, int desiredHeight); 
1043 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) 
1046 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
 
1048   DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
) 
1050   inline wxXPMFileHandler(void) 
1052   m_name 
= "XPM bitmap file"; 
1053   m_extension 
= "xpm"; 
1054   m_type 
= wxBITMAP_TYPE_XPM
; 
1057   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1058     int desiredWidth 
= -1, int desiredHeight 
= -1); 
1059   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1061 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
) 
1063 bool wxXPMFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1064     int desiredWidth
, int desiredHeight
) 
1068     XpmAttributes xpmAttr
; 
1071     M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1072     dc 
= CreateCompatibleDC(NULL
); 
1075       xpmAttr
.valuemask 
= XpmReturnPixels
; 
1076       int errorStatus 
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage 
**) NULL
, &xpmAttr
); 
1078       if (errorStatus 
== XpmSuccess
) 
1080         M_BITMAPHANDLERDATA
->m_hBitmap 
= (WXHBITMAP
) ximage
->bitmap
; 
1083         GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
); 
1085         M_BITMAPHANDLERDATA
->m_width 
= (bm
.bmWidth
); 
1086         M_BITMAPHANDLERDATA
->m_height 
= (bm
.bmHeight
); 
1087         M_BITMAPHANDLERDATA
->m_depth 
= (bm
.bmPlanes 
* bm
.bmBitsPixel
); 
1088         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1089         XpmFreeAttributes(&xpmAttr
); 
1092         M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1097         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1106 bool wxXPMFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette
) 
1111       Visual 
*visual 
= NULL
; 
1114       dc 
= CreateCompatibleDC(NULL
); 
1117         if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
)) 
1120     ximage
.width 
= M_BITMAPHANDLERDATA
->m_width
;  
1121      ximage
.height 
= M_BITMAPHANDLERDATA
->m_height
; 
1122     ximage
.depth 
= M_BITMAPHANDLERDATA
->m_depth
;  
1123      ximage
.bitmap 
= (void *)M_BITMAPHANDLERDATA
->m_hBitmap
; 
1124     int errorStatus 
= XpmWriteFileFromImage(&dc
, WXSTRINGCAST name
, 
1125               &ximage
, (XImage 
*) NULL
, (XpmAttributes 
*) NULL
); 
1130     if (errorStatus 
== XpmSuccess
) 
1134         } else return FALSE
; 
1135       } else return FALSE
; 
1142 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
 
1144   DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
) 
1146   inline wxXPMDataHandler(void) 
1148   m_name 
= "XPM bitmap data"; 
1149   m_extension 
= "xpm"; 
1150   m_type 
= wxBITMAP_TYPE_XPM_DATA
; 
1153   virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth 
= 1); 
1155 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
) 
1157 bool wxXPMDataHandler::Create(wxBitmap 
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
) 
1159         XImage 
*                ximage 
= NULL 
; 
1160         XImage 
*                xshapeimage 
= NULL 
; 
1162         XpmAttributes   xpmAttr
; 
1164     xpmAttr
.valuemask 
= XpmReturnInfos
; // get infos back 
1165     ErrorStatus 
= XpmCreateImageFromData( GetMainDevice() , (char **)data
, 
1166          &ximage
, &xshapeimage
, &xpmAttr
); 
1168     if (ErrorStatus 
== XpmSuccess
) 
1170                         M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1171                         M_BITMAPHANDLERDATA
->m_numColors 
= 0; 
1172                         M_BITMAPHANDLERDATA
->m_hBitmap 
= ximage
->gworldptr 
; 
1174                         M_BITMAPHANDLERDATA
->m_width 
= ximage
->width
; 
1175                         M_BITMAPHANDLERDATA
->m_height 
= ximage
->height
; 
1176                         M_BITMAPHANDLERDATA
->m_depth 
= ximage
->depth
; 
1177                         M_BITMAPHANDLERDATA
->m_numColors 
= xpmAttr
.npixels
; 
1178         XpmFreeAttributes(&xpmAttr
); 
1179             M_BITMAPHANDLERDATA
->m_ok 
= TRUE
; 
1180                         ximage
->gworldptr 
= NULL 
; 
1181                         XImageFree(ximage
); // releases the malloc, but does not detroy 
1183                         M_BITMAPHANDLERDATA
->m_bitmapType 
= kMacBitmapTypeGrafWorld 
; 
1184                         if ( xshapeimage 
!= NULL 
) 
1186                                 wxMask
* m 
= new wxMask() ; 
1187                                 m
->SetMaskBitmap( xshapeimage
->gworldptr 
) ; 
1188                                 M_BITMAPHANDLERDATA
->m_bitmapMask 
= m 
; 
1194       M_BITMAPHANDLERDATA
->m_ok 
= FALSE
; 
1200 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
 
1202     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
) 
1204     inline wxBMPResourceHandler() 
1206         m_name 
= "Windows bitmap resource"; 
1208         m_type 
= wxBITMAP_TYPE_BMP_RESOURCE
; 
1211     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1212           int desiredWidth
, int desiredHeight
); 
1215 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
) 
1217 bool wxBMPResourceHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1218     int desiredWidth
, int desiredHeight
) 
1220     // TODO: load colourmap. 
1221   // it's probably not found 
1222   wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str()); 
1227 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
 
1229   DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
) 
1231   inline wxBMPFileHandler(void) 
1233   m_name 
= "Windows bitmap file"; 
1234   m_extension 
= "bmp"; 
1235   m_type 
= wxBITMAP_TYPE_BMP
; 
1238   virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1239       int desiredWidth
, int desiredHeight
); 
1240   virtual bool SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*palette 
= NULL
); 
1243 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
) 
1245 bool wxBMPFileHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
1246     int desiredWidth
, int desiredHeight
) 
1248 #if USE_IMAGE_LOADING_IN_MSW 
1249     wxPalette 
*palette 
= NULL
; 
1250     bool success 
= FALSE
; 
1251     success 
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0); 
1252     if (!success 
&& palette
) 
1258       M_BITMAPHANDLERDATA
->m_bitmapPalette 
= *palette
; 
1265 bool wxBMPFileHandler::SaveFile(wxBitmap 
*bitmap
, const wxString
& name
, int type
, const wxPalette 
*pal
) 
1267 #if USE_IMAGE_LOADING_IN_MSW 
1268     wxPalette 
*actualPalette 
= (wxPalette 
*)pal
; 
1269     if (!actualPalette 
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull())) 
1270       actualPalette 
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
); 
1271     return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0); 
1278 void wxBitmap::CleanUpHandlers() 
1280     wxNode 
*node 
= sm_handlers
.First(); 
1283         wxBitmapHandler 
*handler 
= (wxBitmapHandler 
*)node
->Data(); 
1284         wxNode 
*next 
= node
->Next(); 
1291 void wxBitmap::InitStandardHandlers() 
1293         AddHandler( new wxPICTResourceHandler 
) ; 
1294         AddHandler( new wxICONResourceHandler 
) ; 
1295         AddHandler(new wxXPMFileHandler
); 
1296         AddHandler(new wxXPMDataHandler
); 
1297         AddHandler(new wxBMPResourceHandler
); 
1298         AddHandler(new wxBMPFileHandler
);