1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Author:      Vaclav Slavik 
   5 // Copyright:   (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) 
   6 // Licence:     wxWindows licence 
   7 ///////////////////////////////////////////////////////////////////////////// 
   9 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  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 static pixel_format_t gs_pixel_format_wxImage 
= 
  52         {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage 
  54 //----------------------------------------------------------------------------- 
  56 //----------------------------------------------------------------------------- 
  58 // Convert wxColour into it's quantized value in lower-precision 
  59 // pixel format (needed for masking by colour). 
  60 static wxColour 
wxQuantizeColour(const wxColour
& clr
, const wxBitmap
& bmp
) 
  62     pixel_format_t 
*pf 
= bmp
.GetMGLbitmap_t()->pf
; 
  64     if ( pf
->redAdjust 
== 0 && pf
->greenAdjust 
== 0 && pf
->blueAdjust 
== 0 ) 
  67         return wxColour((clr
.Red() >> pf
->redAdjust
) << pf
->redAdjust
, 
  68                         (clr
.Green() >> pf
->greenAdjust
) << pf
->greenAdjust
, 
  69                         (clr
.Blue() >> pf
->blueAdjust
) << pf
->blueAdjust
); 
  74 //----------------------------------------------------------------------------- 
  76 //----------------------------------------------------------------------------- 
  78 IMPLEMENT_DYNAMIC_CLASS(wxMask
,wxObject
) 
  85 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
) 
  88     Create(bitmap
, colour
); 
  91 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
) 
  94     Create(bitmap
, paletteIndex
); 
  97 wxMask::wxMask(const wxBitmap
& bitmap
) 
 108 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 113     wxColour 
clr(wxQuantizeColour(colour
, bitmap
)); 
 115     wxImage 
imgSrc(bitmap
.ConvertToImage()); 
 116     imgSrc
.SetMask(FALSE
); 
 117     wxImage 
image(imgSrc
.ConvertToMono(clr
.Red(), clr
.Green(), clr
.Blue())); 
 118     if ( !image
.Ok() ) return FALSE
; 
 120     m_bitmap 
= new wxBitmap(image
, 1); 
 122     return m_bitmap
->Ok(); 
 125 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
) 
 128     wxPalette 
*pal 
= bitmap
.GetPalette(); 
 130     wxCHECK_MSG( pal
, FALSE
, wxT("Cannot create mask from bitmap without palette") ); 
 132     pal
->GetRGB(paletteIndex
, &r
, &g
, &b
); 
 134     return Create(bitmap
, wxColour(r
, g
, b
)); 
 137 bool wxMask::Create(const wxBitmap
& bitmap
) 
 142     wxCHECK_MSG( bitmap
.Ok(), FALSE
, wxT("Invalid bitmap") ); 
 143     wxCHECK_MSG( bitmap
.GetDepth() == 1, FALSE
, wxT("Cannot create mask from colour bitmap") ); 
 145     m_bitmap 
= new wxBitmap(bitmap
); 
 150 //----------------------------------------------------------------------------- 
 152 //----------------------------------------------------------------------------- 
 154 class wxBitmapRefData
: public wxObjectRefData
 
 163     wxPalette      
*m_palette
; 
 168 wxBitmapRefData::wxBitmapRefData() 
 178 wxBitmapRefData::~wxBitmapRefData() 
 181         MGL_unloadBitmap(m_bitmap
); 
 186 //----------------------------------------------------------------------------- 
 188 #define M_BMPDATA ((wxBitmapRefData *)m_refData) 
 191 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
,wxObject
) 
 192 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxBitmapBase
) 
 194 wxBitmap::wxBitmap(int width
, int height
, int depth
) 
 196     Create(width
, height
, depth
); 
 200 static bitmap_t 
*MyMGL_createBitmap(int width
, int height
,  
 201                                     int bpp
, pixel_format_t 
*pf
) 
 203     MGLMemoryDC 
mdc(width
, height
, bpp
, pf
); 
 204     return MGL_getBitmapFromDC(mdc
.getDC(), 0, 0, width
, height
, TRUE
); 
 207 bool wxBitmap::Create(int width
, int height
, int depth
) 
 211     wxCHECK_MSG( (width 
> 0) && (height 
> 0), FALSE
, wxT("invalid bitmap size") ) 
 213     pixel_format_t pf_dummy
, *pf
; 
 214     int mglDepth 
= depth
; 
 219             wxASSERT_MSG( g_displayDC
, wxT("MGL display DC not created yet.") ); 
 221             g_displayDC
->getPixelFormat(pf_dummy
); 
 222             mglDepth 
= g_displayDC
->getBitsPerPixel();                 
 230             pf 
= &gs_pixel_format_15
; 
 233             pf 
= &gs_pixel_format_16
; 
 236             pf 
= &gs_pixel_format_24
; 
 239             pf 
= &gs_pixel_format_32
; 
 242             wxASSERT_MSG( 0, wxT("invalid bitmap depth") ); 
 247     m_refData 
= new wxBitmapRefData(); 
 248     M_BMPDATA
->m_mask 
= (wxMask 
*) NULL
; 
 249     M_BMPDATA
->m_palette 
= (wxPalette 
*) NULL
; 
 250     M_BMPDATA
->m_width 
= width
; 
 251     M_BMPDATA
->m_height 
= height
; 
 252     M_BMPDATA
->m_bpp 
= mglDepth
; 
 256         M_BMPDATA
->m_bitmap 
= MyMGL_createBitmap(width
, height
, mglDepth
, pf
); 
 260         // MGL does not support mono DCs, so we have to emulate them with 
 261         // 8bpp ones. We do that by using a special palette with color 0 
 262         // set to black and all other colors set to white.  
 264         M_BMPDATA
->m_bitmap 
= MyMGL_createBitmap(width
, height
, 8, pf
); 
 265         SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0)); 
 271 bool wxBitmap::CreateFromXpm(const char **bits
) 
 273     wxCHECK_MSG( bits 
!= NULL
, FALSE
, wxT("invalid bitmap data") ) 
 275     wxXPMDecoder decoder
; 
 276     wxImage img 
= decoder
.ReadData(bits
); 
 277     wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") ) 
 279     *this = wxBitmap(img
); 
 284 wxBitmap::wxBitmap(const wxImage
& image
, int depth
) 
 288     wxCHECK_RET( image
.Ok(), wxT("invalid image") ) 
 290     width 
= image
.GetWidth(); 
 291     height 
= image
.GetHeight(); 
 293     if ( !Create(width
, height
, depth
) ) return; 
 295     MGLMemoryDC 
idc(width
, height
, 24, &gs_pixel_format_wxImage
, 
 296                     width 
* 3, (void*)image
.GetData(), NULL
); 
 297     wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") ); 
 299     MGLDevCtx 
*bdc 
= CreateTmpDC(); 
 301     if ( GetDepth() <= 8 && image
.HasPalette() ) 
 302         SetPalette(image
.GetPalette()); 
 304     bdc
->bitBlt(idc
, 0, 0, width
, height
, 0, 0, MGL_REPLACE_MODE
); 
 307     if ( image
.HasMask() ) 
 309         wxImage mask_image 
= image
.ConvertToMono(image
.GetMaskRed(), 
 310                                                  image
.GetMaskGreen(), 
 311                                                  image
.GetMaskBlue()); 
 312         mask_image
.SetMask(FALSE
); 
 313         wxBitmap 
mask_bmp(mask_image
, 1); 
 314         SetMask(new wxMask(mask_bmp
)); 
 318 wxImage 
wxBitmap::ConvertToImage() const 
 320     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") ); 
 324     height 
= GetHeight(); 
 326     wxImage 
image(width
, height
); 
 327     wxASSERT_MSG( image
.Ok(), wxT("cannot create image") ); 
 329     MGLMemoryDC 
idc(width
, height
, 24, &gs_pixel_format_wxImage
, 
 330                     width 
* 3, (void*)image
.GetData(), NULL
); 
 331     wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") ); 
 333     if ( M_BMPDATA
->m_palette 
) 
 334         image
.SetPalette(*(M_BMPDATA
->m_palette
)); 
 338         // in consistency with other ports, we convert parts covered 
 339         // by the mask to <16,16,16> colour and set that colour to image's 
 340         // mask. We do that by OR-blitting the mask over image with 
 341         // bg colour set to black and fg colour to <16,16,16> 
 343         image
.SetMaskColour(16, 16, 16); 
 347         tmpDC
.SetMGLDC(&idc
, FALSE
); 
 348         tmpDC
.SetBackground(wxBrush(wxColour(16,16,16), wxSOLID
)); 
 350         tmpDC
.DrawBitmap(*this, 0, 0, TRUE
); 
 354         image
.SetMask(FALSE
); 
 355         idc
.putBitmap(0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
); 
 361 wxBitmap::wxBitmap(const wxBitmap
& bmp
) 
 366 wxBitmap::wxBitmap(const wxString 
&filename
, wxBitmapType type
) 
 368     LoadFile(filename
, type
); 
 371 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
) 
 373     wxCHECK_RET( depth 
== 1, wxT("can only create mono bitmap from XBM data") ); 
 375     if ( !Create(width
, height
, 1) ) return; 
 376     MGLDevCtx 
*bdc 
= CreateTmpDC(); 
 377     wxCurrentDCSwitcher 
curDC(bdc
); 
 379     bdc
->setBackColor(0); 
 381     bdc
->putMonoImage(0, 0, width
, (width 
+ 7) / 8, height
, (void*)bits
); 
 385 wxBitmap
& wxBitmap::operator = (const wxBitmap
& bmp
) 
 387     if ( *this == bmp 
) return (*this); 
 392 bool wxBitmap::operator == (const wxBitmap
& bmp
) const 
 394     return (m_refData 
== bmp
.m_refData
); 
 397 bool wxBitmap::operator != (const wxBitmap
& bmp
) const 
 399     return (m_refData 
!= bmp
.m_refData
); 
 402 bool wxBitmap::Ok() const 
 404     return (m_refData 
!= NULL 
&& M_BMPDATA
->m_bitmap 
!= NULL
); 
 407 int wxBitmap::GetHeight() const 
 409     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 411     return M_BMPDATA
->m_height
; 
 414 int wxBitmap::GetWidth() const 
 416     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 418     return M_BMPDATA
->m_width
; 
 421 int wxBitmap::GetDepth() const 
 423     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); 
 425     return M_BMPDATA
->m_bpp
; 
 428 wxMask 
*wxBitmap::GetMask() const 
 430     wxCHECK_MSG( Ok(), (wxMask 
*) NULL
, wxT("invalid bitmap") ); 
 432     return M_BMPDATA
->m_mask
; 
 435 void wxBitmap::SetMask(wxMask 
*mask
) 
 437     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 439     delete M_BMPDATA
->m_mask
; 
 440     M_BMPDATA
->m_mask 
= mask
; 
 443 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 445     wxBitmap 
*bmp 
= (wxBitmap
*)(&icon
); 
 450 wxBitmap 
wxBitmap::GetSubBitmap(const wxRect
& rect
) const 
 453                  (rect
.x 
>= 0) && (rect
.y 
>= 0) && 
 454                  (rect
.x
+rect
.width 
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height 
<= M_BMPDATA
->m_height
), 
 455                  wxNullBitmap
, wxT("invalid bitmap or bitmap region") ); 
 457     wxBitmap 
ret( rect
.width
, rect
.height
, M_BMPDATA
->m_bpp 
); 
 458     wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") ); 
 461         ret
.SetPalette(*GetPalette()); 
 463     MGLDevCtx 
*tdc 
= ret
.CreateTmpDC(); 
 464     tdc
->putBitmapSection(rect
.x
, rect
.y
,  
 465                           rect
.x 
+ rect
.width
, rect
.y 
+ rect
.height
, 
 466                           0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
); 
 471         wxBitmap submask 
= GetMask()->GetBitmap()->GetSubBitmap(rect
); 
 472         ret
.SetMask(new wxMask(submask
)); 
 478 void wxBitmap::SetMonoPalette(const wxColour
& fg
, const wxColour
& bg
) 
 480     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 482     palette_t 
*mono 
= M_BMPDATA
->m_bitmap
->pal
; 
 484     wxCHECK_RET( M_BMPDATA
->m_bpp 
== 1, wxT("bitmap is not 1bpp") ); 
 485     wxCHECK_RET( mono 
!= NULL
, wxT("bitmap w/o palette") ); 
 487     mono
[0].red 
= bg
.Red(); 
 488     mono
[0].green 
= bg
.Green(); 
 489     mono
[0].blue 
= bg
.Blue(); 
 491     for (size_t i 
= 1; i 
< 256; i
++) 
 493         mono
[i
].red 
= fg
.Red(); 
 494         mono
[i
].green 
= fg
.Green(); 
 495         mono
[i
].blue 
= fg
.Blue(); 
 500 MGLDevCtx 
*wxBitmap::CreateTmpDC() const 
 502     wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 504     MGLDevCtx 
*tdc 
= new MGLMemoryDC(GetWidth(), GetHeight(), 
 505                                      M_BMPDATA
->m_bitmap
->bitsPerPixel
, 
 506                                      M_BMPDATA
->m_bitmap
->pf
, 
 507                                      M_BMPDATA
->m_bitmap
->bytesPerLine
, 
 508                                      M_BMPDATA
->m_bitmap
->surface
,  
 510     wxCHECK_MSG( tdc
->isValid(), NULL
, wxT("cannot create temporary MGLDC") ); 
 512     if ( M_BMPDATA
->m_bitmap
->pal 
!= NULL 
) 
 516         switch (M_BMPDATA
->m_bitmap
->bitsPerPixel
) 
 518             case  2: cnt 
= 2;   break; 
 519             case  4: cnt 
= 16;  break; 
 520             case  8: cnt 
= 256; break; 
 523                 wxFAIL_MSG( wxT("bitmap with this depth cannot have palette") ); 
 527         tdc
->setPalette(M_BMPDATA
->m_bitmap
->pal
, cnt
, 0); 
 528         tdc
->realizePalette(cnt
, 0, FALSE
); 
 534 bool wxBitmap::LoadFile(const wxString 
&name
, wxBitmapType type
) 
 538     if ( type 
== wxBITMAP_TYPE_BMP 
|| type 
== wxBITMAP_TYPE_PNG 
||  
 539          type 
== wxBITMAP_TYPE_PCX 
|| type 
== wxBITMAP_TYPE_JPEG 
) 
 541         // prevent accidental loading of bitmap from $MGL_ROOT: 
 542         if ( !wxFileExists(name
) ) 
 544             wxLogError(_("File %s does not exist."), name
.c_str()); 
 549     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 551     if ( handler 
== NULL 
)  
 554         if ( !image
.LoadFile(name
, type
) || !image
.Ok() ) 
 556             wxLogError("no bitmap handler for type %d defined.", type
);             
 561             *this = wxBitmap(image
); 
 566     m_refData 
= new wxBitmapRefData(); 
 568     return handler
->LoadFile(this, name
, type
, -1, -1); 
 571 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, const wxPalette 
*palette
) const 
 573     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") ); 
 575     wxBitmapHandler 
*handler 
= FindHandler(type
); 
 577     if ( handler 
== NULL 
)  
 579         wxImage image 
= ConvertToImage(); 
 581             image
.SetPalette(*palette
); 
 584             return image
.SaveFile(filename
, type
); 
 587             wxLogError("no bitmap handler for type %d defined.", type
); 
 592     return handler
->SaveFile(this, filename
, type
, palette
); 
 595 wxPalette 
*wxBitmap::GetPalette() const 
 597     wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") ); 
 599     return M_BMPDATA
->m_palette
; 
 602 void wxBitmap::SetPalette(const wxPalette
& palette
) 
 604     wxCHECK_RET( Ok(), wxT("invalid bitmap") ); 
 605     wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") ); 
 607     delete M_BMPDATA
->m_palette
; 
 608     M_BMPDATA
->m_palette 
= NULL
; 
 610     if ( !palette
.Ok() ) return; 
 612     M_BMPDATA
->m_palette 
= new wxPalette(palette
); 
 614     int cnt 
= palette
.GetColoursCount(); 
 615     palette_t 
*pal 
= palette
.GetMGLpalette_t(); 
 616     memcpy(M_BMPDATA
->m_bitmap
->pal
, pal
, cnt 
* sizeof(palette_t
)); 
 619 void wxBitmap::SetHeight(int height
) 
 621     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 623     M_BMPDATA
->m_height 
= height
; 
 626 void wxBitmap::SetWidth(int width
) 
 628     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 630     M_BMPDATA
->m_width 
= width
; 
 633 void wxBitmap::SetDepth(int depth
) 
 635     if (!m_refData
) m_refData 
= new wxBitmapRefData(); 
 637     M_BMPDATA
->m_bpp 
= depth
; 
 640 bitmap_t 
*wxBitmap::GetMGLbitmap_t() const 
 642     return M_BMPDATA
->m_bitmap
; 
 647 //----------------------------------------------------------------------------- 
 648 // wxBitmap I/O handlers 
 649 //----------------------------------------------------------------------------- 
 651 class wxMGLBitmapHandler
: public wxBitmapHandler
 
 654     wxMGLBitmapHandler(wxBitmapType type
, 
 655                        const wxString
& extension
, const wxString
& name
); 
 657     virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
,  
 658                           int width
, int height
, int depth 
= 1) 
 661     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 662                           int desiredWidth
, int desiredHeight
); 
 663     virtual bool SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 664                           int type
, const wxPalette 
*palette 
= NULL
); 
 667 wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type
,  
 668                                        const wxString
& extension
, 
 669                                        const wxString
& name
) 
 674     SetExtension(extension
); 
 677 bool wxMGLBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 679                                   int WXUNUSED(desiredWidth
),  
 680                                   int WXUNUSED(desiredHeight
)) 
 682     int width
, height
, bpp
; 
 689         case wxBITMAP_TYPE_BMP_RESOURCE
: 
 690         case wxBITMAP_TYPE_JPEG_RESOURCE
: 
 691         case wxBITMAP_TYPE_PNG_RESOURCE
: 
 692         case wxBITMAP_TYPE_PCX_RESOURCE
: 
 693             fullname 
= name 
+ wxT(".bmp"); 
 702         case wxBITMAP_TYPE_BMP
: 
 703         case wxBITMAP_TYPE_BMP_RESOURCE
: 
 704             if ( !MGL_getBitmapSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 706             bitmap
->Create(width
, height
, -1); 
 707             if ( !bitmap
->Ok() ) return FALSE
; 
 708             dc
.SelectObject(*bitmap
); 
 709             if ( !dc
.GetMGLDC()->loadBitmapIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 713         case wxBITMAP_TYPE_JPEG
: 
 714         case wxBITMAP_TYPE_JPEG_RESOURCE
: 
 715             if ( !MGL_getJPEGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 717             bitmap
->Create(width
, height
, -1); 
 718             if ( !bitmap
->Ok() ) return FALSE
; 
 719             dc
.SelectObject(*bitmap
); 
 720             if ( !dc
.GetMGLDC()->loadJPEGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 724         case wxBITMAP_TYPE_PNG
: 
 725         case wxBITMAP_TYPE_PNG_RESOURCE
: 
 726             if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 728             bitmap
->Create(width
, height
, -1); 
 729             if ( !bitmap
->Ok() ) return FALSE
; 
 730             dc
.SelectObject(*bitmap
); 
 731             if ( !dc
.GetMGLDC()->loadPNGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 735         case wxBITMAP_TYPE_PCX
: 
 736         case wxBITMAP_TYPE_PCX_RESOURCE
: 
 737             if ( !MGL_getPCXSize(fullname
.mb_str(), &width
, &height
, &bpp
) ) 
 739             bitmap
->Create(width
, height
, -1); 
 740             if ( !bitmap
->Ok() ) return FALSE
; 
 741             dc
.SelectObject(*bitmap
); 
 742             if ( !dc
.GetMGLDC()->loadPCXIntoDC(fullname
.mb_str(), 0, 0, TRUE
) ) 
 747             wxFAIL_MSG(wxT("Unsupported image format.")); 
 754 bool wxMGLBitmapHandler::SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 755                                   int type
, const wxPalette 
* WXUNUSED(palette
)) 
 759     int w 
= bitmap
->GetWidth(), 
 760         h 
= bitmap
->GetHeight(); 
 762     mem
.SelectObject(*bitmap
); 
 763     tdc 
= mem
.GetMGLDC(); 
 767         case wxBITMAP_TYPE_BMP
: 
 768             return tdc
->saveBitmapFromDC(name
.mb_str(), 0, 0, w
, h
); 
 770         case wxBITMAP_TYPE_JPEG
: 
 771             return tdc
->saveJPEGFromDC(name
.mb_str(), 0, 0, w
, h
, 75); 
 773         case wxBITMAP_TYPE_PNG
: 
 774             return tdc
->savePNGFromDC(name
.mb_str(), 0, 0, w
, h
); 
 776         case wxBITMAP_TYPE_PCX
: 
 777             return tdc
->savePCXFromDC(name
.mb_str(), 0, 0, w
, h
); 
 787 // let's handle PNGs in special way because they have alpha channel  
 788 // which we can access via bitmap_t most easily 
 789 class wxPNGBitmapHandler
: public wxMGLBitmapHandler
 
 792     wxPNGBitmapHandler(wxBitmapType type
, 
 793                        const wxString
& extension
, const wxString
& name
) 
 794         : wxMGLBitmapHandler(type
, extension
, name
) {} 
 796     virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 797                           int desiredWidth
, int desiredHeight
); 
 800 bool wxPNGBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 802                                   int desiredWidth
, int desiredHeight
) 
 804     int width
, height
, bpp
; 
 808     if ( flags 
== wxBITMAP_TYPE_PNG_RESOURCE 
) 
 809         fullname 
= name 
+ wxT(".png"); 
 813     if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) ) 
 818         // We can load ordinary PNGs faster with 'normal' MGL handler. 
 819         // Only RGBA PNGs need to be processed in special way because 
 820         // we have to convert alpha channel to mask 
 821         return wxMGLBitmapHandler::LoadFile(bitmap
, name
, flags
,  
 822                                             desiredWidth
, desiredHeight
); 
 825     bitmap_t 
*bmp 
= MGL_loadPNG(fullname
.mb_str(), TRUE
); 
 827     if ( bmp 
== NULL 
) return FALSE
; 
 829     bitmap
->Create(bmp
->width
, bmp
->height
, -1); 
 830     if ( !bitmap
->Ok() ) return FALSE
; 
 832     // convert bmp to display's depth and write it to *bitmap: 
 834     dc
.SelectObject(*bitmap
); 
 835     dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
); 
 836     dc
.SelectObject(wxNullBitmap
); 
 838     // create mask, if bmp contains alpha channel (ARGB format): 
 839     if ( bmp
->bitsPerPixel 
== 32 ) 
 842         wxUint32 
*s 
= (wxUint32
*)bmp
->surface
; 
 843         for (y 
= 0; y 
< bmp
->height
; y
++) 
 845             s 
= ((wxUint32
*)bmp
->surface
) + y 
* bmp
->bytesPerLine
/4; 
 846             for (x 
= 0; x 
< bmp
->width
; x
++, s 
++) 
 848                 if ( ((((*s
) >> bmp
->pf
->alphaPos
) & bmp
->pf
->alphaMask
)  
 849                         << bmp
->pf
->alphaAdjust
) < 128 ) 
 852                     *s 
= 0x00FFFFFF; // white 
 855         wxBitmap 
mask(bmp
->width
, bmp
->height
, 1); 
 856         dc
.SelectObject(mask
); 
 857         dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
); 
 858         dc
.SelectObject(wxNullBitmap
); 
 859         bitmap
->SetMask(new wxMask(mask
)); 
 862     MGL_unloadBitmap(bmp
); 
 870 class wxICOBitmapHandler
: public wxBitmapHandler
 
 873         wxICOBitmapHandler(wxBitmapType type
, 
 874                            const wxString
& extension
, const wxString
& name
); 
 876         virtual bool Create(wxBitmap 
*bitmap
, void *data
, long flags
,  
 877                               int width
, int height
, int depth 
= 1) 
 880         virtual bool LoadFile(wxBitmap 
*bitmap
, const wxString
& name
, long flags
, 
 881                               int desiredWidth
, int desiredHeight
); 
 882         virtual bool SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 883                               int type
, const wxPalette 
*palette 
= NULL
); 
 886 wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type
,  
 887                                        const wxString
& extension
, 
 888                                        const wxString
& name
) 
 893     SetExtension(extension
); 
 896 bool wxICOBitmapHandler::LoadFile(wxBitmap 
*bitmap
, const wxString
& name
,  
 898                                   int WXUNUSED(desiredWidth
),  
 899                                   int WXUNUSED(desiredHeight
)) 
 904     if ( flags 
== wxBITMAP_TYPE_ICO_RESOURCE 
) 
 905         icon 
= MGL_loadIcon(wxString(name 
+ wxT(".ico")).mb_str(), TRUE
); 
 907         icon 
= MGL_loadIcon(name
.mb_str(), TRUE
); 
 909     if ( icon 
== NULL 
) return FALSE
; 
 911     bitmap
->Create(icon
->xorMask
.width
, icon
->xorMask
.height
); 
 914     mem
.SelectObject(*bitmap
); 
 916     dc
->putBitmap(0, 0, &(icon
->xorMask
), MGL_REPLACE_MODE
); 
 917     mem
.SelectObject(wxNullBitmap
); 
 919     wxBitmap 
mask(icon
->xorMask
.width
, icon
->xorMask
.height
, 1); 
 920     mem
.SelectObject(mask
); 
 923     wxCurrentDCSwitcher 
curDC(dc
); 
 927     dc
->putMonoImage(0, 0, icon
->xorMask
.width
, icon
->byteWidth
, 
 928                            icon
->xorMask
.height
, (void*)icon
->andMask
); 
 930     bitmap
->SetMask(new wxMask(mask
)); 
 932     MGL_unloadIcon(icon
); 
 937 bool wxICOBitmapHandler::SaveFile(const wxBitmap 
*bitmap
, const wxString
& name
,  
 938                                   int type
, const wxPalette 
* WXUNUSED(palette
)) 
 946 /*static*/ void wxBitmap::InitStandardHandlers() 
 948     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP
, wxT("bmp"), wxT("Windows bitmap"))); 
 949     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP_RESOURCE
, wxEmptyString
, wxT("Windows bitmap resource"))); 
 950     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG
, wxT("jpg"), wxT("JPEG image"))); 
 951     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG_RESOURCE
, wxEmptyString
, wxT("JPEG resource"))); 
 952     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX
, wxT("pcx"), wxT("PCX image"))); 
 953     AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX_RESOURCE
, wxEmptyString
, wxT("PCX resource"))); 
 955     AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG
, wxT("png"), wxT("PNG image"))); 
 956     AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG_RESOURCE
, wxEmptyString
, wxT("PNG resource"))); 
 958     AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO
, wxT("ico"), wxT("Icon resource"))); 
 959     AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO_RESOURCE
, wxEmptyString
, wxT("Icon resource")));