1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/bitmap.cpp
3 // Author: Vaclav Slavik
5 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
16 #include "wx/bitmap.h"
18 #include "wx/filefn.h"
20 #include "wx/dcmemory.h"
25 #include "wx/xpmdecod.h"
27 #include "wx/mgl/private.h"
31 //-----------------------------------------------------------------------------
33 //-----------------------------------------------------------------------------
35 static pixel_format_t gs_pixel_format_15
=
36 {0x1F,0x0A,3, 0x1F,0x05,3, 0x1F,0x00,3, 0x01,0x0F,7}; // 555 15bpp
38 static pixel_format_t gs_pixel_format_16
=
39 {0x1F,0x0B,3, 0x3F,0x05,2, 0x1F,0x00,3, 0x00,0x00,0}; // 565 16bpp
41 static pixel_format_t gs_pixel_format_24
=
42 {0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0, 0x00,0x00,0}; // RGB 24bpp
44 static pixel_format_t gs_pixel_format_32
=
45 {0xFF,0x18,0, 0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0}; // RGBA 32bpp
47 static pixel_format_t gs_pixel_format_wxImage
=
48 {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
54 // Convert wxColour into it's quantized value in lower-precision
55 // pixel format (needed for masking by colour).
56 static wxColour
wxQuantizeColour(const wxColour
& clr
, const wxBitmap
& bmp
)
58 pixel_format_t
*pf
= bmp
.GetMGLbitmap_t()->pf
;
60 if ( pf
->redAdjust
== 0 && pf
->greenAdjust
== 0 && pf
->blueAdjust
== 0 )
63 return wxColour((unsigned char)((clr
.Red() >> pf
->redAdjust
) << pf
->redAdjust
),
64 (unsigned char)((clr
.Green() >> pf
->greenAdjust
) << pf
->greenAdjust
),
65 (unsigned char)((clr
.Blue() >> pf
->blueAdjust
) << pf
->blueAdjust
));
70 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
74 IMPLEMENT_DYNAMIC_CLASS(wxMask
,wxObject
)
81 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
84 Create(bitmap
, colour
);
87 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
90 Create(bitmap
, paletteIndex
);
93 wxMask::wxMask(const wxBitmap
& bitmap
)
104 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
109 wxColour
clr(wxQuantizeColour(colour
, bitmap
));
111 wxImage
imgSrc(bitmap
.ConvertToImage());
112 imgSrc
.SetMask(false);
113 wxImage
image(imgSrc
.ConvertToMono(clr
.Red(), clr
.Green(), clr
.Blue()));
117 m_bitmap
= new wxBitmap(image
, 1);
119 return m_bitmap
->Ok();
122 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
125 wxPalette
*pal
= bitmap
.GetPalette();
127 wxCHECK_MSG( pal
, false, wxT("Cannot create mask from bitmap without palette") );
129 pal
->GetRGB(paletteIndex
, &r
, &g
, &b
);
131 return Create(bitmap
, wxColour(r
, g
, b
));
134 bool wxMask::Create(const wxBitmap
& bitmap
)
139 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap") );
140 wxCHECK_MSG( bitmap
.GetDepth() == 1, false, wxT("Cannot create mask from colour bitmap") );
142 m_bitmap
= new wxBitmap(bitmap
);
147 //-----------------------------------------------------------------------------
149 //-----------------------------------------------------------------------------
151 class wxBitmapRefData
: public wxObjectRefData
160 wxPalette
*m_palette
;
165 wxBitmapRefData::wxBitmapRefData()
175 wxBitmapRefData::~wxBitmapRefData()
178 MGL_unloadBitmap(m_bitmap
);
183 //-----------------------------------------------------------------------------
185 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
188 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler
,wxObject
)
189 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxBitmapBase
)
191 wxBitmap::wxBitmap(int width
, int height
, int depth
)
193 Create(width
, height
, depth
);
197 static bitmap_t
*MyMGL_createBitmap(int width
, int height
,
198 int bpp
, pixel_format_t
*pf
)
200 MGLMemoryDC
mdc(width
, height
, bpp
, pf
);
201 return MGL_getBitmapFromDC(mdc
.getDC(), 0, 0, width
, height
, TRUE
);
204 bool wxBitmap::Create(int width
, int height
, int depth
)
208 wxCHECK_MSG( (width
> 0) && (height
> 0), false, wxT("invalid bitmap size") )
210 pixel_format_t pf_dummy
;
212 int mglDepth
= depth
;
217 wxASSERT_MSG( g_displayDC
, wxT("MGL display DC not created yet.") );
219 g_displayDC
->getPixelFormat(pf_dummy
);
220 mglDepth
= g_displayDC
->getBitsPerPixel();
228 pf
= &gs_pixel_format_15
;
231 pf
= &gs_pixel_format_16
;
234 pf
= &gs_pixel_format_24
;
237 pf
= &gs_pixel_format_32
;
240 wxASSERT_MSG( 0, wxT("invalid bitmap depth") );
244 m_refData
= new wxBitmapRefData();
245 M_BMPDATA
->m_mask
= (wxMask
*) NULL
;
246 M_BMPDATA
->m_palette
= (wxPalette
*) NULL
;
247 M_BMPDATA
->m_width
= width
;
248 M_BMPDATA
->m_height
= height
;
249 M_BMPDATA
->m_bpp
= mglDepth
;
253 M_BMPDATA
->m_bitmap
= MyMGL_createBitmap(width
, height
, mglDepth
, pf
);
257 // MGL does not support mono DCs, so we have to emulate them with
258 // 8bpp ones. We do that by using a special palette with color 0
259 // set to black and all other colors set to white.
261 M_BMPDATA
->m_bitmap
= MyMGL_createBitmap(width
, height
, 8, pf
);
262 SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0));
268 bool wxBitmap::CreateFromXpm(const char **bits
)
270 wxCHECK_MSG( bits
!= NULL
, false, wxT("invalid bitmap data") )
272 wxXPMDecoder decoder
;
273 wxImage img
= decoder
.ReadData(bits
);
274 wxCHECK_MSG( img
.Ok(), false, wxT("invalid bitmap data") )
276 *this = wxBitmap(img
);
281 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
285 wxCHECK_RET( image
.Ok(), wxT("invalid image") )
287 width
= image
.GetWidth();
288 height
= image
.GetHeight();
290 if ( !Create(width
, height
, depth
) ) return;
292 MGLMemoryDC
idc(width
, height
, 24, &gs_pixel_format_wxImage
,
293 width
* 3, (void*)image
.GetData(), NULL
);
294 wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") );
296 MGLDevCtx
*bdc
= CreateTmpDC();
298 if ( GetDepth() <= 8 && image
.HasPalette() )
299 SetPalette(image
.GetPalette());
301 bdc
->bitBlt(idc
, 0, 0, width
, height
, 0, 0, MGL_REPLACE_MODE
);
304 if ( image
.HasMask() )
306 wxImage mask_image
= image
.ConvertToMono(image
.GetMaskRed(),
307 image
.GetMaskGreen(),
308 image
.GetMaskBlue());
309 mask_image
.SetMask(false);
310 wxBitmap
mask_bmp(mask_image
, 1);
311 SetMask(new wxMask(mask_bmp
));
315 wxImage
wxBitmap::ConvertToImage() const
317 wxCHECK_MSG( Ok(), wxImage(), wxT("invalid bitmap") );
321 height
= GetHeight();
323 wxImage
image(width
, height
);
324 wxASSERT_MSG( image
.Ok(), wxT("cannot create image") );
326 MGLMemoryDC
idc(width
, height
, 24, &gs_pixel_format_wxImage
,
327 width
* 3, (void*)image
.GetData(), NULL
);
328 wxASSERT_MSG( idc
.isValid(), wxT("cannot create custom MGLDC") );
330 if ( M_BMPDATA
->m_palette
)
331 image
.SetPalette(*(M_BMPDATA
->m_palette
));
335 // in consistency with other ports, we convert parts covered
336 // by the mask to <16,16,16> colour and set that colour to image's
337 // mask. We do that by OR-blitting the mask over image with
338 // bg colour set to black and fg colour to <16,16,16>
340 image
.SetMaskColour(16, 16, 16);
344 tmpDC
.SetMGLDC(&idc
, false);
345 tmpDC
.SetBackground(wxBrush(wxColour(16,16,16), wxSOLID
));
347 tmpDC
.DrawBitmap(*this, 0, 0, true);
351 image
.SetMask(false);
352 idc
.putBitmap(0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
);
358 wxBitmap::wxBitmap(const wxBitmap
& bmp
)
363 wxBitmap::wxBitmap(const wxString
&filename
, wxBitmapType type
)
365 LoadFile(filename
, type
);
368 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
370 wxCHECK_RET( depth
== 1, wxT("can only create mono bitmap from XBM data") );
372 if ( !Create(width
, height
, 1) ) return;
373 MGLDevCtx
*bdc
= CreateTmpDC();
374 wxCurrentDCSwitcher
curDC(bdc
);
376 bdc
->setBackColor(0);
378 bdc
->putMonoImage(0, 0, width
, (width
+ 7) / 8, height
, (void*)bits
);
382 wxBitmap
& wxBitmap::operator = (const wxBitmap
& bmp
)
384 if ( *this == bmp
) return (*this);
389 bool wxBitmap::operator == (const wxBitmap
& bmp
) const
391 return (m_refData
== bmp
.m_refData
);
394 bool wxBitmap::operator != (const wxBitmap
& bmp
) const
396 return (m_refData
!= bmp
.m_refData
);
399 bool wxBitmap::Ok() const
401 return (m_refData
!= NULL
&& M_BMPDATA
->m_bitmap
!= NULL
);
404 int wxBitmap::GetHeight() const
406 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
408 return M_BMPDATA
->m_height
;
411 int wxBitmap::GetWidth() const
413 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
415 return M_BMPDATA
->m_width
;
418 int wxBitmap::GetDepth() const
420 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
422 return M_BMPDATA
->m_bpp
;
425 wxMask
*wxBitmap::GetMask() const
427 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
429 return M_BMPDATA
->m_mask
;
432 void wxBitmap::SetMask(wxMask
*mask
)
434 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
436 delete M_BMPDATA
->m_mask
;
437 M_BMPDATA
->m_mask
= mask
;
440 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
442 wxBitmap
*bmp
= (wxBitmap
*)(&icon
);
447 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
& rect
) const
450 (rect
.x
>= 0) && (rect
.y
>= 0) &&
451 (rect
.x
+rect
.width
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height
<= M_BMPDATA
->m_height
),
452 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
454 wxBitmap
ret( rect
.width
, rect
.height
, M_BMPDATA
->m_bpp
);
455 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
458 ret
.SetPalette(*GetPalette());
460 MGLDevCtx
*tdc
= ret
.CreateTmpDC();
461 tdc
->putBitmapSection(rect
.x
, rect
.y
,
462 rect
.x
+ rect
.width
, rect
.y
+ rect
.height
,
463 0, 0, M_BMPDATA
->m_bitmap
, MGL_REPLACE_MODE
);
468 wxBitmap submask
= GetMask()->GetBitmap()->GetSubBitmap(rect
);
469 ret
.SetMask(new wxMask(submask
));
475 void wxBitmap::SetMonoPalette(const wxColour
& fg
, const wxColour
& bg
)
477 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
479 palette_t
*mono
= M_BMPDATA
->m_bitmap
->pal
;
481 wxCHECK_RET( M_BMPDATA
->m_bpp
== 1, wxT("bitmap is not 1bpp") );
482 wxCHECK_RET( mono
!= NULL
, wxT("bitmap w/o palette") );
484 mono
[0].red
= bg
.Red();
485 mono
[0].green
= bg
.Green();
486 mono
[0].blue
= bg
.Blue();
488 for (size_t i
= 1; i
< 256; i
++)
490 mono
[i
].red
= fg
.Red();
491 mono
[i
].green
= fg
.Green();
492 mono
[i
].blue
= fg
.Blue();
497 MGLDevCtx
*wxBitmap::CreateTmpDC() const
499 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
501 MGLDevCtx
*tdc
= new MGLMemoryDC(GetWidth(), GetHeight(),
502 M_BMPDATA
->m_bitmap
->bitsPerPixel
,
503 M_BMPDATA
->m_bitmap
->pf
,
504 M_BMPDATA
->m_bitmap
->bytesPerLine
,
505 M_BMPDATA
->m_bitmap
->surface
,
507 wxCHECK_MSG( tdc
->isValid(), NULL
, wxT("cannot create temporary MGLDC") );
509 if ( M_BMPDATA
->m_bitmap
->pal
!= NULL
)
513 switch (M_BMPDATA
->m_bitmap
->bitsPerPixel
)
515 case 2: cnt
= 2; break;
516 case 4: cnt
= 16; break;
517 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
*WXUNUSED(bitmap
),
655 void *WXUNUSED(data
),
656 long WXUNUSED(flags
),
658 int WXUNUSED(height
),
659 int WXUNUSED(depth
) = 1)
662 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
663 int desiredWidth
, int desiredHeight
);
664 virtual bool SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
665 int type
, const wxPalette
*palette
= NULL
);
668 wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type
,
669 const wxString
& extension
,
670 const wxString
& name
)
675 SetExtension(extension
);
678 bool wxMGLBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
,
680 int WXUNUSED(desiredWidth
),
681 int WXUNUSED(desiredHeight
))
683 int width
, height
, bpp
;
690 case wxBITMAP_TYPE_BMP_RESOURCE
:
691 case wxBITMAP_TYPE_JPEG_RESOURCE
:
692 case wxBITMAP_TYPE_PNG_RESOURCE
:
693 case wxBITMAP_TYPE_PCX_RESOURCE
:
694 fullname
= name
+ wxT(".bmp");
703 case wxBITMAP_TYPE_BMP
:
704 case wxBITMAP_TYPE_BMP_RESOURCE
:
705 if ( !MGL_getBitmapSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
707 bitmap
->Create(width
, height
, -1);
708 if ( !bitmap
->Ok() ) return false;
709 dc
.SelectObject(*bitmap
);
710 if ( !dc
.GetMGLDC()->loadBitmapIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
714 case wxBITMAP_TYPE_JPEG
:
715 case wxBITMAP_TYPE_JPEG_RESOURCE
:
716 if ( !MGL_getJPEGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
718 bitmap
->Create(width
, height
, -1);
719 if ( !bitmap
->Ok() ) return false;
720 dc
.SelectObject(*bitmap
);
721 if ( !dc
.GetMGLDC()->loadJPEGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
725 case wxBITMAP_TYPE_PNG
:
726 case wxBITMAP_TYPE_PNG_RESOURCE
:
727 if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
729 bitmap
->Create(width
, height
, -1);
730 if ( !bitmap
->Ok() ) return false;
731 dc
.SelectObject(*bitmap
);
732 if ( !dc
.GetMGLDC()->loadPNGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
736 case wxBITMAP_TYPE_PCX
:
737 case wxBITMAP_TYPE_PCX_RESOURCE
:
738 if ( !MGL_getPCXSize(fullname
.mb_str(), &width
, &height
, &bpp
) )
740 bitmap
->Create(width
, height
, -1);
741 if ( !bitmap
->Ok() ) return false;
742 dc
.SelectObject(*bitmap
);
743 if ( !dc
.GetMGLDC()->loadPCXIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
748 wxFAIL_MSG(wxT("Unsupported image format."));
755 bool wxMGLBitmapHandler::SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
756 int type
, const wxPalette
* WXUNUSED(palette
))
760 int w
= bitmap
->GetWidth(),
761 h
= bitmap
->GetHeight();
763 mem
.SelectObject(*bitmap
);
764 tdc
= mem
.GetMGLDC();
768 case wxBITMAP_TYPE_BMP
:
769 return (bool)tdc
->saveBitmapFromDC(name
.mb_str(), 0, 0, w
, h
);
770 case wxBITMAP_TYPE_JPEG
:
771 return (bool)tdc
->saveJPEGFromDC(name
.mb_str(), 0, 0, w
, h
, 75);
772 case wxBITMAP_TYPE_PNG
:
773 return (bool)tdc
->savePNGFromDC(name
.mb_str(), 0, 0, w
, h
);
774 case wxBITMAP_TYPE_PCX
:
775 return (bool)tdc
->savePCXFromDC(name
.mb_str(), 0, 0, w
, h
);
783 // let's handle PNGs in special way because they have alpha channel
784 // which we can access via bitmap_t most easily
785 class wxPNGBitmapHandler
: public wxMGLBitmapHandler
788 wxPNGBitmapHandler(wxBitmapType type
,
789 const wxString
& extension
, const wxString
& name
)
790 : wxMGLBitmapHandler(type
, extension
, name
) {}
792 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
793 int desiredWidth
, int desiredHeight
);
796 bool wxPNGBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
,
798 int desiredWidth
, int desiredHeight
)
800 int width
, height
, bpp
;
804 if ( flags
== wxBITMAP_TYPE_PNG_RESOURCE
)
805 fullname
= name
+ wxT(".png");
809 if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
814 // We can load ordinary PNGs faster with 'normal' MGL handler.
815 // Only RGBA PNGs need to be processed in special way because
816 // we have to convert alpha channel to mask
817 return wxMGLBitmapHandler::LoadFile(bitmap
, name
, flags
,
818 desiredWidth
, desiredHeight
);
821 bitmap_t
*bmp
= MGL_loadPNG(fullname
.mb_str(), TRUE
);
823 if ( bmp
== NULL
) return false;
825 bitmap
->Create(bmp
->width
, bmp
->height
, -1);
826 if ( !bitmap
->Ok() ) return false;
828 // convert bmp to display's depth and write it to *bitmap:
830 dc
.SelectObject(*bitmap
);
831 dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
);
832 dc
.SelectObject(wxNullBitmap
);
834 // create mask, if bmp contains alpha channel (ARGB format):
835 if ( bmp
->bitsPerPixel
== 32 )
838 wxUint32
*s
= (wxUint32
*)bmp
->surface
;
839 for (y
= 0; y
< bmp
->height
; y
++)
841 s
= ((wxUint32
*)bmp
->surface
) + y
* bmp
->bytesPerLine
/4;
842 for (x
= 0; x
< bmp
->width
; x
++, s
++)
844 if ( ((((*s
) >> bmp
->pf
->alphaPos
) & bmp
->pf
->alphaMask
)
845 << bmp
->pf
->alphaAdjust
) < 128 )
848 *s
= 0x00FFFFFF; // white
851 wxBitmap
mask(bmp
->width
, bmp
->height
, 1);
852 dc
.SelectObject(mask
);
853 dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
);
854 dc
.SelectObject(wxNullBitmap
);
855 bitmap
->SetMask(new wxMask(mask
));
858 MGL_unloadBitmap(bmp
);
866 class wxICOBitmapHandler
: public wxBitmapHandler
869 wxICOBitmapHandler(wxBitmapType type
,
870 const wxString
& extension
, const wxString
& name
);
872 virtual bool Create(wxBitmap
*WXUNUSED(bitmap
),
873 void *WXUNUSED(data
),
874 long WXUNUSED(flags
),
876 int WXUNUSED(height
),
877 int WXUNUSED(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
*WXUNUSED(bitmap
),
938 const wxString
& WXUNUSED(name
),
940 const wxPalette
* WXUNUSED(palette
))
948 /*static*/ void wxBitmap::InitStandardHandlers()
950 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP
, wxT("bmp"), wxT("Windows bitmap")));
951 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP_RESOURCE
, wxEmptyString
, wxT("Windows bitmap resource")));
952 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG
, wxT("jpg"), wxT("JPEG image")));
953 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG_RESOURCE
, wxEmptyString
, wxT("JPEG resource")));
954 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX
, wxT("pcx"), wxT("PCX image")));
955 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX_RESOURCE
, wxEmptyString
, wxT("PCX resource")));
957 AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG
, wxT("png"), wxT("PNG image")));
958 AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG_RESOURCE
, wxEmptyString
, wxT("PNG resource")));
960 AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO
, wxT("ico"), wxT("Icon resource")));
961 AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO_RESOURCE
, wxEmptyString
, wxT("Icon resource")));