1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Author:      Vaclav Slavik 
   5 // Copyright:   (c) 2001 Vaclav Slavik 
   6 // Licence:     wxWindows licence 
   7 ///////////////////////////////////////////////////////////////////////////// 
  10 #pragma implementation "bitmap.h" 
  13 // For compilers that support precompilation, includes "wx.h". 
  14 #include "wx/wxprec.h" 
  20 #include "wx/bitmap.h" 
  22 #include "wx/filefn.h" 
  24 #include "wx/dcmemory.h" 
  29 #include "wx/xpmdecod.h" 
  31 #include "wx/mgl/private.h" 
  35 //----------------------------------------------------------------------------- 
  37 //----------------------------------------------------------------------------- 
  39 static pixel_format_t gs_pixel_format_15 
= 
  40         {0x1F,0x0A,3, 0x1F,0x05,3, 0x1F,0x00,3, 0x01,0x0F,7}; // 555 15bpp 
  42 static pixel_format_t gs_pixel_format_16 
= 
  43         {0x1F,0x0B,3, 0x3F,0x05,2, 0x1F,0x00,3, 0x00,0x00,0}; // 565 16bpp 
  45 static pixel_format_t gs_pixel_format_24 
= 
  46         {0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0, 0x00,0x00,0}; // RGB 24bpp 
  48 static pixel_format_t gs_pixel_format_32 
= 
  49         {0xFF,0x18,0, 0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0}; // RGBA 32bpp 
  51 // FIXME_MGL -- these formats will probably have to go into another place, 
  52 //              where wxApp could use them to initialize g_displayDC 
  55 //----------------------------------------------------------------------------- 
  57 //----------------------------------------------------------------------------- 
  59 IMPLEMENT_DYNAMIC_CLASS(wxMask
,wxObject
) 
  66 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
  69     Create(bitmap
, colour
); 
  72 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
  75     Create(bitmap
, paletteIndex
); 
  78 wxMask::wxMask(const wxBitmap
& bitmap
) 
  89 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
  94     wxImage image 
= bitmap
.ConvertToImage().ConvertToMono( 
  95                                 colour
.Red(), colour
.Green(), colour
.Blue()); 
  96     if ( !image
.Ok() ) return FALSE
; 
  98     m_bitmap 
= new wxBitmap(image
, 1); 
 100     return m_bitmap
->Ok(); 
 103 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
 106     wxPalette 
*pal 
= bitmap
.GetPalette(); 
 108     wxCHECK_MSG( pal
, FALSE
, wxT("Cannot create mask from bitmap without palette") ); 
 110     pal
->GetRGB(paletteIndex
, &r
, &g
, &b
); 
 112     return Create(bitmap
, wxColour(r
, g
, b
)); 
 115 bool wxMask::Create(const wxBitmap
& bitmap
) 
 120     wxCHECK_MSG( bitmap
.Ok(), FALSE
, wxT("Invalid bitmap") ); 
 121     wxCHECK_MSG( bitmap
.GetDepth() == 1, FALSE
, wxT("Cannot create mask from colour bitmap") ); 
 123     m_bitmap 
= new wxBitmap(bitmap
); 
 128 //----------------------------------------------------------------------------- 
 130 //----------------------------------------------------------------------------- 
 132 class wxBitmapRefData
: public wxObjectRefData
 
 141     wxPalette      
*m_palette
; 
 146 wxBitmapRefData::wxBitmapRefData() 
 156 wxBitmapRefData::~wxBitmapRefData() 
 159         MGL_unloadBitmap(m_bitmap
); 
 164 //----------------------------------------------------------------------------- 
 166 #define M_BMPDATA ((wxBitmapRefData *)m_refData) 
 169 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
,wxObject
) 
 170 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxBitmapBase
) 
 174     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 177 wxBitmap::wxBitmap(int width
, int height
, int depth
) 
 179     Create(width
, height
, depth
); 
 181     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 185 static bitmap_t 
*MyMGL_createBitmap(int width
, int height
,  
 186                                     int bpp
, pixel_format_t 
*pf
) 
 188     MGLMemoryDC 
mdc(width
, height
, bpp
, pf
); 
 189     return MGL_getBitmapFromDC(mdc
.getDC(), 0, 0, width
, height
, TRUE
); 
 192 bool wxBitmap::Create(int width
, int height
, int depth
) 
 196     wxCHECK_MSG( (width 
> 0) && (height 
> 0), FALSE
, wxT("invalid bitmap size") ) 
 198     pixel_format_t pf_dummy
, *pf
; 
 199     int mglDepth 
= depth
; 
 204             wxASSERT_MSG( g_displayDC
, wxT("MGL display DC not created yet.") ); 
 206             g_displayDC
->getPixelFormat(pf_dummy
); 
 207             mglDepth 
= g_displayDC
->getBitsPerPixel();                 
 215             pf 
= &gs_pixel_format_15
; 
 218             pf 
= &gs_pixel_format_16
; 
 221             pf 
= &gs_pixel_format_24
; 
 224             pf 
= &gs_pixel_format_32
; 
 227             wxASSERT_MSG( 0, wxT("invalid bitmap depth") ); 
 232     m_refData 
= new wxBitmapRefData(); 
 233     M_BMPDATA
->m_mask 
= (wxMask 
*) NULL
; 
 234     M_BMPDATA
->m_palette 
= (wxPalette 
*) NULL
; 
 235     M_BMPDATA
->m_width 
= width
; 
 236     M_BMPDATA
->m_height 
= height
; 
 237     M_BMPDATA
->m_bpp 
= mglDepth
; 
 241         M_BMPDATA
->m_bitmap 
= MyMGL_createBitmap(width
, height
, mglDepth
, pf
); 
 245         // MGL does not support mono DCs, so we have to emulate them with 
 246         // 8bpp ones. We do that by using a special palette with color 0 
 247         // set to black and all other colors set to white.  
 249         M_BMPDATA
->m_bitmap 
= MyMGL_createBitmap(width
, height
, 8, pf
); 
 250         SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0)); 
 256 bool wxBitmap::CreateFromXpm(const char **bits
) 
 258     wxCHECK_MSG( bits 
!= NULL
, FALSE
, wxT("invalid bitmap data") ) 
 260     wxXPMDecoder decoder
; 
 261     wxImage img 
= decoder
.ReadData(bits
); 
 262     wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") ) 
 264     *this = wxBitmap(img
); 
 266     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 271 wxBitmap::wxBitmap(const wxImage
& image
, int depth 
= -1) 
 275     wxCHECK_RET( image
.Ok(), wxT("invalid image") ) 
 277     width 
= image
.GetWidth(); 
 278     height 
= image
.GetHeight(); 
 280     if ( !Create(width
, height
, depth
) ) return; 
 282     MGLMemoryDC 
idc(width
, height
, 24, &gs_pixel_format_24
, 
 283                     width 
* 3, (void*)image
.GetData(), NULL
); 
 284     wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") ); 
 286     MGLDevCtx 
*bdc 
= CreateTmpDC(); 
 288     if ( depth 
<= 8 && image
.HasPalette() ) 
 289         SetPalette(image
.GetPalette()); 
 291     bdc
->bitBlt(idc
, 0, 0, width
, height
, 0, 0, MGL_REPLACE_MODE
); 
 294     if ( image
.HasMask() ) 
 296         wxImage mask_image 
= image
.ConvertToMono(image
.GetMaskRed(), 
 297                                                  image
.GetMaskGreen(), 
 298                                                  image
.GetMaskBlue()); 
 299         mask_image
.SetMask(FALSE
); 
 300         wxBitmap 
mask_bmp(mask_image
, 1); 
 301         SetMask(new wxMask(mask_bmp
)); 
 305 wxImage 
wxBitmap::ConvertToImage() const 
 307     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") ); 
 311     height 
= GetHeight(); 
 313     wxImage 
image(width
, height
); 
 314     wxASSERT_MSG( image
.Ok(), wxT("cannot create image") ); 
 316     MGLMemoryDC 
idc(width
, height
, 24, &gs_pixel_format_24
, 
 317                     width 
* 3, (void*)image
.GetData(), NULL
); 
 318     wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") ); 
 320     if ( M_BMPDATA
->m_palette 
) 
 321         image
.SetPalette(*(M_BMPDATA
->m_palette
)); 
 325         // in consistency with other ports, we convert parts covered 
 326         // by the mask to <16,16,16> colour and set that colour to image's 
 327         // mask. We do that by OR-blitting the mask over image with 
 328         // bg colour set to black and fg colour to <16,16,16> 
 330         image
.SetMaskColour(16, 16, 16); 
 334         tmpDC
.SetMGLDC(&idc
, FALSE
); 
 335         tmpDC
.SetBackground(wxBrush(wxColour(16,16,16), wxSOLID
)); 
 337         tmpDC
.DrawBitmap(*this, 0, 0, TRUE
); 
 341         image
.SetMask(FALSE
); 
 342         idc
.putBitmap(0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
); 
 348 wxBitmap::wxBitmap(const wxBitmap
& bmp
) 
 352     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 355 wxBitmap::wxBitmap(const wxString 
&filename
, wxBitmapType type
) 
 357     LoadFile(filename
, type
); 
 359     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 362 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
) 
 364     wxCHECK_RET( depth 
== 1, wxT("can only create mono bitmap from XBM data") ); 
 366     if ( !Create(width
, height
, 1) ) return; 
 367     MGLDevCtx 
*bdc 
= CreateTmpDC(); 
 368     wxCurrentDCSwitcher 
curDC(bdc
); 
 370     bdc
->setBackColor(0); 
 372     bdc
->putMonoImage(0, 0, width
, (width 
+ 7) / 8, height
, (void*)bits
); 
 375     if ( wxTheBitmapList 
) wxTheBitmapList
->AddBitmap(this); 
 378 wxBitmap::~wxBitmap() 
 380     if ( wxTheBitmapList 
) wxTheBitmapList
->DeleteObject(this); 
 383 wxBitmap
& wxBitmap::operator = (const wxBitmap
& bmp
) 
 385     if ( *this == bmp 
) return (*this); 
 390 bool wxBitmap::operator == (const wxBitmap
& bmp
) const 
 392     return (m_refData 
== bmp
.m_refData
); 
 395 bool wxBitmap::operator != (const wxBitmap
& bmp
) const 
 397     return (m_refData 
!= bmp
.m_refData
); 
 400 bool wxBitmap::Ok() const 
 402     return (m_refData 
!= NULL 
&& M_BMPDATA
->m_bitmap 
!= NULL
); 
 405 int wxBitmap::GetHeight() const 
 407     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 409     return M_BMPDATA
->m_height
; 
 412 int wxBitmap::GetWidth() const 
 414     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 416     return M_BMPDATA
->m_width
; 
 419 int wxBitmap::GetDepth() const 
 421     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 423     return M_BMPDATA
->m_bpp
; 
 426 wxMask 
*wxBitmap::GetMask() const 
 428     wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 430     return M_BMPDATA
->m_mask
; 
 433 void wxBitmap::SetMask(wxMask 
*mask
) 
 435     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 437     delete M_BMPDATA
->m_mask
; 
 438     M_BMPDATA
->m_mask 
= mask
; 
 441 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 443     wxBitmap 
*bmp 
= (wxBitmap
*)(&icon
); 
 448 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect
& rect
) const 
 451                  (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 452                  (rect
.x
+rect
.width 
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height 
<= M_BMPDATA
->m_height
), 
 453                  wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 455     wxBitmap 
ret( rect
.width
, rect
.height
, M_BMPDATA
->m_bpp 
); 
 456     wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 459         ret
.SetPalette(*GetPalette()); 
 461     MGLDevCtx 
*tdc 
= ret
.CreateTmpDC(); 
 462     tdc
->putBitmapSection(rect
.x
, rect
.y
,  
 463                           rect
.x 
+ rect
.width
, rect
.y 
+ rect
.height
, 
 464                           0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
); 
 469         wxBitmap submask 
= GetMask()->GetBitmap()->GetSubBitmap(rect
); 
 470         ret
.SetMask(new wxMask(submask
)); 
 476 void wxBitmap::SetMonoPalette(const wxColour
& fg
, const wxColour
& bg
) 
 478     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 480     palette_t 
*mono 
= M_BMPDATA
->m_bitmap
->pal
; 
 482     wxCHECK_RET( M_BMPDATA
->m_bpp 
== 1, wxT("bitmap is not 1bpp") ); 
 483     wxCHECK_RET( mono 
!= NULL
, wxT("bitmap w/o palette") ); 
 485     mono
[0].red 
= bg
.Red(); 
 486     mono
[0].green 
= bg
.Green(); 
 487     mono
[0].blue 
= bg
.Blue(); 
 489     for (size_t i 
= 1; i 
< 256; i
++) 
 491         mono
[i
].red 
= fg
.Red(); 
 492         mono
[i
].green 
= fg
.Green(); 
 493         mono
[i
].blue 
= fg
.Blue(); 
 498 MGLDevCtx 
*wxBitmap::CreateTmpDC() const 
 500     wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 502     MGLDevCtx 
*tdc 
= new MGLMemoryDC(GetWidth(), GetHeight(), 
 503                                      M_BMPDATA
->m_bitmap
->bitsPerPixel
, 
 504                                      M_BMPDATA
->m_bitmap
->pf
, 
 505                                      M_BMPDATA
->m_bitmap
->bytesPerLine
, 
 506                                      M_BMPDATA
->m_bitmap
->surface
,  
 508     wxCHECK_MSG( tdc
->isValid(), NULL
, wxT("cannot create temporary MGLDC") ); 
 510     if ( M_BMPDATA
->m_bitmap
->pal 
!= NULL 
) 
 514         switch (M_BMPDATA
->m_bitmap
->bitsPerPixel
) 
 516             case  2: cnt 
= 2;   break; 
 517             case  4: cnt 
= 16;  break; 
 518             case  8: cnt 
= 256; break; 
 520                 wxFAIL_MSG( wxT("bitmap with this depth cannot have palette") ); 
 524         tdc
->setPalette(M_BMPDATA
->m_bitmap
->pal
, cnt
, 0); 
 525         tdc
->realizePalette(cnt
, 0, FALSE
); 
 531 bool wxBitmap::LoadFile(const wxString 
&name
, wxBitmapType type
) 
 535     if ( type 
== wxBITMAP_TYPE_BMP 
|| type 
== wxBITMAP_TYPE_PNG 
||  
 536          type 
== wxBITMAP_TYPE_PCX 
|| type 
== wxBITMAP_TYPE_JPEG 
) 
 538         // prevent accidental loading of bitmap from $MGL_ROOT: 
 539         if ( !wxFileExists(name
) ) 
 541             wxLogError(_("File %s does not exist."), name
.c_str()); 
 546     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 548     if ( handler 
== NULL 
)  
 551         if ( !image
.LoadFile(name
, type
) || !image
.Ok() ) 
 553             wxLogError("no bitmap handler for type %d defined.", type
);             
 558             *this = wxBitmap(image
); 
 563     m_refData 
= new wxBitmapRefData(); 
 565     return handler
->LoadFile(this, name
, type
, -1, -1); 
 568 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, const wxPalette 
*palette
) const 
 570     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") ); 
 572     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 574     if ( handler 
== NULL 
)  
 576         wxImage image 
= ConvertToImage(); 
 578             image
.SetPalette(*palette
); 
 581             return image
.SaveFile(filename
, type
); 
 584             wxLogError("no bitmap handler for type %d defined.", type
); 
 589     return handler
->SaveFile(this, filename
, type
, palette
); 
 592 wxPalette 
*wxBitmap::GetPalette() const 
 594     wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 596     return M_BMPDATA
->m_palette
; 
 599 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 601     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 602     wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") ); 
 604     delete M_BMPDATA
->m_palette
; 
 605     M_BMPDATA
->m_palette 
= NULL
; 
 607     if ( !palette
.Ok() ) return; 
 609     M_BMPDATA
->m_palette 
= new wxPalette(palette
); 
 611     int cnt 
= palette
.GetColoursCount(); 
 612     palette_t 
*pal 
= palette
.GetMGLpalette_t(); 
 613     memcpy(M_BMPDATA
->m_bitmap
->pal
, pal
, cnt 
* sizeof(palette_t
)); 
 616 void wxBitmap::SetHeight(int height
) 
 618     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 620     M_BMPDATA
->m_height 
= height
; 
 623 void wxBitmap::SetWidth(int width
) 
 625     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 627     M_BMPDATA
->m_width 
= width
; 
 630 void wxBitmap::SetDepth(int depth
) 
 632     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 634     M_BMPDATA
->m_bpp 
= depth
; 
 637 bitmap_t 
*wxBitmap::GetMGLbitmap_t() const 
 639     return M_BMPDATA
->m_bitmap
; 
 644 //----------------------------------------------------------------------------- 
 645 // wxBitmap I/O handlers 
 646 //----------------------------------------------------------------------------- 
 648 class wxMGLBitmapHandler
: public wxBitmapHandler
 
 651     wxMGLBitmapHandler(wxBitmapType type
, 
 652                        const wxString
& extension
, const wxString
& name
); 
 654     virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
,  
 655                           int width
, int height
, int depth 
= 1) 
 658     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 659                           int desiredWidth
, int desiredHeight
); 
 660     virtual bool SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 661                           int type
, const wxPalette 
*palette 
= NULL
); 
 664 wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type
,  
 665                                        const wxString
& extension
, 
 666                                        const wxString
& name
) 
 671     SetExtension(extension
); 
 674 bool wxMGLBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 676                                   int WXUNUSED(desiredWidth
),  
 677                                   int WXUNUSED(desiredHeight
)) 
 679     int width
, height
, bpp
; 
 686         case wxBITMAP_TYPE_BMP_RESOURCE
: 
 687         case wxBITMAP_TYPE_JPEG_RESOURCE
: 
 688         case wxBITMAP_TYPE_PNG_RESOURCE
: 
 689         case wxBITMAP_TYPE_PCX_RESOURCE
: 
 690             fullname 
= name 
+ wxT(".bmp"); 
 699         case wxBITMAP_TYPE_BMP
: 
 700         case wxBITMAP_TYPE_BMP_RESOURCE
: 
 701             if ( !MGL_getBitmapSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 703             bitmap
->Create(width
, height
, -1); 
 704             if ( !bitmap
->Ok() ) return FALSE
; 
 705             dc
.SelectObject(*bitmap
); 
 706             if ( !dc
.GetMGLDC()->loadBitmapIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 710         case wxBITMAP_TYPE_JPEG
: 
 711         case wxBITMAP_TYPE_JPEG_RESOURCE
: 
 712             if ( !MGL_getJPEGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 714             bitmap
->Create(width
, height
, -1); 
 715             if ( !bitmap
->Ok() ) return FALSE
; 
 716             dc
.SelectObject(*bitmap
); 
 717             if ( !dc
.GetMGLDC()->loadJPEGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 721         case wxBITMAP_TYPE_PNG
: 
 722         case wxBITMAP_TYPE_PNG_RESOURCE
: 
 723             if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 725             bitmap
->Create(width
, height
, -1); 
 726             if ( !bitmap
->Ok() ) return FALSE
; 
 727             dc
.SelectObject(*bitmap
); 
 728             if ( !dc
.GetMGLDC()->loadPNGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 732         case wxBITMAP_TYPE_PCX
: 
 733         case wxBITMAP_TYPE_PCX_RESOURCE
: 
 734             if ( !MGL_getPCXSize(fullname
.mb_str(), &width
, &height
, &bpp
) ) 
 736             bitmap
->Create(width
, height
, -1); 
 737             if ( !bitmap
->Ok() ) return FALSE
; 
 738             dc
.SelectObject(*bitmap
); 
 739             if ( !dc
.GetMGLDC()->loadPCXIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 744             wxFAIL_MSG(wxT("Unsupported image format.")); 
 751 bool wxMGLBitmapHandler::SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 752                                   int type
, const wxPalette 
* WXUNUSED(palette
)) 
 756     int w 
= bitmap
->GetWidth(), 
 757         h 
= bitmap
->GetHeight(); 
 759     mem
.SelectObject(*bitmap
); 
 760     tdc 
= mem
.GetMGLDC(); 
 764         case wxBITMAP_TYPE_BMP
: 
 765             return tdc
->saveBitmapFromDC(name
.mb_str(), 0, 0, w
, h
); 
 767         case wxBITMAP_TYPE_JPEG
: 
 768             return tdc
->saveJPEGFromDC(name
.mb_str(), 0, 0, w
, h
, 75); 
 770         case wxBITMAP_TYPE_PNG
: 
 771             return tdc
->savePNGFromDC(name
.mb_str(), 0, 0, w
, h
); 
 773         case wxBITMAP_TYPE_PCX
: 
 774             return tdc
->savePCXFromDC(name
.mb_str(), 0, 0, w
, h
); 
 784 // let's handle PNGs in special way because they have alpha channel  
 785 // which we can access via bitmap_t most easily 
 786 class wxPNGBitmapHandler
: public wxMGLBitmapHandler
 
 789     wxPNGBitmapHandler(wxBitmapType type
, 
 790                        const wxString
& extension
, const wxString
& name
) 
 791         : wxMGLBitmapHandler(type
, extension
, name
) {} 
 793     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 794                           int desiredWidth
, int desiredHeight
); 
 797 bool wxPNGBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 799                                   int desiredWidth
, int desiredHeight
) 
 801     int width
, height
, bpp
; 
 805     if ( flags 
== wxBITMAP_TYPE_PNG_RESOURCE 
) 
 806         fullname 
= name 
+ wxT(".png"); 
 810     if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 815         // We can load ordinary PNGs faster with 'normal' MGL handler. 
 816         // Only RGBA PNGs need to be processed in special way because 
 817         // we have to convert alpha channel to mask 
 818         return wxMGLBitmapHandler::LoadFile(bitmap
, name
, flags
,  
 819                                             desiredWidth
, desiredHeight
); 
 822     bitmap_t 
*bmp 
= MGL_loadPNG(fullname
.mb_str(), TRUE
); 
 824     if ( bmp 
== NULL 
) return FALSE
; 
 826     bitmap
->Create(bmp
->width
, bmp
->height
, -1); 
 827     if ( !bitmap
->Ok() ) return FALSE
; 
 829     // convert bmp to display's depth and write it to *bitmap: 
 831     dc
.SelectObject(*bitmap
); 
 832     dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
); 
 833     dc
.SelectObject(wxNullBitmap
); 
 835     // create mask, if bmp contains alpha channel (ARGB format): 
 836     if ( bmp
->bitsPerPixel 
== 32 ) 
 839         wxUint32 
*s 
= (wxUint32
*)bmp
->surface
; 
 840         for (y 
= 0; y 
< bmp
->height
; y
++) 
 842             s 
= ((wxUint32
*)bmp
->surface
) + y 
* bmp
->bytesPerLine
/4; 
 843             for (x 
= 0; x 
< bmp
->width
; x
++, s 
++) 
 845                 if ( ((((*s
) >> bmp
->pf
->rsvdPos
) & bmp
->pf
->rsvdMask
)  
 846                         << bmp
->pf
->rsvdAdjust
) < 128 ) 
 849                     *s 
= 0x00FFFFFF; // white 
 852         wxBitmap 
mask(bmp
->width
, bmp
->height
, 1); 
 853         dc
.SelectObject(mask
); 
 854         dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
); 
 855         dc
.SelectObject(wxNullBitmap
); 
 856         bitmap
->SetMask(new wxMask(mask
)); 
 859     MGL_unloadBitmap(bmp
); 
 867 class wxICOBitmapHandler
: public wxBitmapHandler
 
 870         wxICOBitmapHandler(wxBitmapType type
, 
 871                            const wxString
& extension
, const wxString
& name
); 
 873         virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
,  
 874                               int width
, int height
, int depth 
= 1) 
 877         virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 878                               int desiredWidth
, int desiredHeight
); 
 879         virtual bool SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 880                               int type
, const wxPalette 
*palette 
= NULL
); 
 883 wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type
,  
 884                                        const wxString
& extension
, 
 885                                        const wxString
& name
) 
 890     SetExtension(extension
); 
 893 bool wxICOBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 895                                   int WXUNUSED(desiredWidth
),  
 896                                   int WXUNUSED(desiredHeight
)) 
 901     if ( flags 
== wxBITMAP_TYPE_ICO_RESOURCE 
) 
 902         icon 
= MGL_loadIcon(wxString(name 
+ wxT(".ico")).mb_str(), TRUE
); 
 904         icon 
= MGL_loadIcon(name
.mb_str(), TRUE
); 
 906     if ( icon 
== NULL 
) return FALSE
; 
 908     bitmap
->Create(icon
->xorMask
.width
, icon
->xorMask
.height
); 
 911     mem
.SelectObject(*bitmap
); 
 913     dc
->putBitmap(0, 0, &(icon
->xorMask
), MGL_REPLACE_MODE
); 
 914     mem
.SelectObject(wxNullBitmap
); 
 916     wxBitmap 
mask(icon
->xorMask
.width
, icon
->xorMask
.height
, 1); 
 917     mem
.SelectObject(mask
); 
 920     wxCurrentDCSwitcher 
curDC(dc
); 
 924     dc
->putMonoImage(0, 0, icon
->xorMask
.width
, icon
->byteWidth
, 
 925                            icon
->xorMask
.height
, (void*)icon
->andMask
); 
 927     bitmap
->SetMask(new wxMask(mask
)); 
 929     MGL_unloadIcon(icon
); 
 934 bool wxICOBitmapHandler::SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 935                                   int type
, const wxPalette 
* WXUNUSED(palette
)) 
 943 /*static*/ void wxBitmap::InitStandardHandlers() 
 945     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP
, wxT("bmp"), wxT("Windows bitmap"))); 
 946     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP_RESOURCE
, wxEmptyString
, wxT("Windows bitmap resource"))); 
 947     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG
, wxT("jpg"), wxT("JPEG image"))); 
 948     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG_RESOURCE
, wxEmptyString
, wxT("JPEG resource"))); 
 949     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX
, wxT("pcx"), wxT("PCX image"))); 
 950     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX_RESOURCE
, wxEmptyString
, wxT("PCX resource"))); 
 952     AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG
, wxT("png"), wxT("PNG image"))); 
 953     AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG_RESOURCE
, wxEmptyString
, wxT("PNG resource"))); 
 955     AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO
, wxT("ico"), wxT("Icon resource"))); 
 956     AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO_RESOURCE
, wxEmptyString
, wxT("Icon resource")));