1 /////////////////////////////////////////////////////////////////////////////
3 // Author: Vaclav Slavik
5 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
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;
521 wxFAIL_MSG( wxT("bitmap with this depth cannot have palette") );
525 tdc
->setPalette(M_BMPDATA
->m_bitmap
->pal
, cnt
, 0);
526 tdc
->realizePalette(cnt
, 0, FALSE
);
532 bool wxBitmap::LoadFile(const wxString
&name
, wxBitmapType type
)
536 if ( type
== wxBITMAP_TYPE_BMP
|| type
== wxBITMAP_TYPE_PNG
||
537 type
== wxBITMAP_TYPE_PCX
|| type
== wxBITMAP_TYPE_JPEG
)
539 // prevent accidental loading of bitmap from $MGL_ROOT:
540 if ( !wxFileExists(name
) )
542 wxLogError(_("File %s does not exist."), name
.c_str());
547 wxBitmapHandler
*handler
= FindHandler(type
);
549 if ( handler
== NULL
)
552 if ( !image
.LoadFile(name
, type
) || !image
.Ok() )
554 wxLogError("no bitmap handler for type %d defined.", type
);
559 *this = wxBitmap(image
);
564 m_refData
= new wxBitmapRefData();
566 return handler
->LoadFile(this, name
, type
, -1, -1);
569 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
, const wxPalette
*palette
) const
571 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid bitmap") );
573 wxBitmapHandler
*handler
= FindHandler(type
);
575 if ( handler
== NULL
)
577 wxImage image
= ConvertToImage();
579 image
.SetPalette(*palette
);
582 return image
.SaveFile(filename
, type
);
585 wxLogError("no bitmap handler for type %d defined.", type
);
590 return handler
->SaveFile(this, filename
, type
, palette
);
593 wxPalette
*wxBitmap::GetPalette() const
595 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
597 return M_BMPDATA
->m_palette
;
600 void wxBitmap::SetPalette(const wxPalette
& palette
)
602 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
603 wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
605 delete M_BMPDATA
->m_palette
;
606 M_BMPDATA
->m_palette
= NULL
;
608 if ( !palette
.Ok() ) return;
610 M_BMPDATA
->m_palette
= new wxPalette(palette
);
612 int cnt
= palette
.GetColoursCount();
613 palette_t
*pal
= palette
.GetMGLpalette_t();
614 memcpy(M_BMPDATA
->m_bitmap
->pal
, pal
, cnt
* sizeof(palette_t
));
617 void wxBitmap::SetHeight(int height
)
619 if (!m_refData
) m_refData
= new wxBitmapRefData();
621 M_BMPDATA
->m_height
= height
;
624 void wxBitmap::SetWidth(int width
)
626 if (!m_refData
) m_refData
= new wxBitmapRefData();
628 M_BMPDATA
->m_width
= width
;
631 void wxBitmap::SetDepth(int depth
)
633 if (!m_refData
) m_refData
= new wxBitmapRefData();
635 M_BMPDATA
->m_bpp
= depth
;
638 bitmap_t
*wxBitmap::GetMGLbitmap_t() const
640 return M_BMPDATA
->m_bitmap
;
645 //-----------------------------------------------------------------------------
646 // wxBitmap I/O handlers
647 //-----------------------------------------------------------------------------
649 class wxMGLBitmapHandler
: public wxBitmapHandler
652 wxMGLBitmapHandler(wxBitmapType type
,
653 const wxString
& extension
, const wxString
& name
);
655 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
,
656 int width
, int height
, int depth
= 1)
659 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
660 int desiredWidth
, int desiredHeight
);
661 virtual bool SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
662 int type
, const wxPalette
*palette
= NULL
);
665 wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type
,
666 const wxString
& extension
,
667 const wxString
& name
)
672 SetExtension(extension
);
675 bool wxMGLBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
,
677 int WXUNUSED(desiredWidth
),
678 int WXUNUSED(desiredHeight
))
680 int width
, height
, bpp
;
687 case wxBITMAP_TYPE_BMP_RESOURCE
:
688 case wxBITMAP_TYPE_JPEG_RESOURCE
:
689 case wxBITMAP_TYPE_PNG_RESOURCE
:
690 case wxBITMAP_TYPE_PCX_RESOURCE
:
691 fullname
= name
+ wxT(".bmp");
700 case wxBITMAP_TYPE_BMP
:
701 case wxBITMAP_TYPE_BMP_RESOURCE
:
702 if ( !MGL_getBitmapSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
704 bitmap
->Create(width
, height
, -1);
705 if ( !bitmap
->Ok() ) return FALSE
;
706 dc
.SelectObject(*bitmap
);
707 if ( !dc
.GetMGLDC()->loadBitmapIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
711 case wxBITMAP_TYPE_JPEG
:
712 case wxBITMAP_TYPE_JPEG_RESOURCE
:
713 if ( !MGL_getJPEGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
715 bitmap
->Create(width
, height
, -1);
716 if ( !bitmap
->Ok() ) return FALSE
;
717 dc
.SelectObject(*bitmap
);
718 if ( !dc
.GetMGLDC()->loadJPEGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
722 case wxBITMAP_TYPE_PNG
:
723 case wxBITMAP_TYPE_PNG_RESOURCE
:
724 if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
726 bitmap
->Create(width
, height
, -1);
727 if ( !bitmap
->Ok() ) return FALSE
;
728 dc
.SelectObject(*bitmap
);
729 if ( !dc
.GetMGLDC()->loadPNGIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
733 case wxBITMAP_TYPE_PCX
:
734 case wxBITMAP_TYPE_PCX_RESOURCE
:
735 if ( !MGL_getPCXSize(fullname
.mb_str(), &width
, &height
, &bpp
) )
737 bitmap
->Create(width
, height
, -1);
738 if ( !bitmap
->Ok() ) return FALSE
;
739 dc
.SelectObject(*bitmap
);
740 if ( !dc
.GetMGLDC()->loadPCXIntoDC(fullname
.mb_str(), 0, 0, TRUE
) )
745 wxFAIL_MSG(wxT("Unsupported image format."));
752 bool wxMGLBitmapHandler::SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
753 int type
, const wxPalette
* WXUNUSED(palette
))
757 int w
= bitmap
->GetWidth(),
758 h
= bitmap
->GetHeight();
760 mem
.SelectObject(*bitmap
);
761 tdc
= mem
.GetMGLDC();
765 case wxBITMAP_TYPE_BMP
:
766 return tdc
->saveBitmapFromDC(name
.mb_str(), 0, 0, w
, h
);
768 case wxBITMAP_TYPE_JPEG
:
769 return tdc
->saveJPEGFromDC(name
.mb_str(), 0, 0, w
, h
, 75);
771 case wxBITMAP_TYPE_PNG
:
772 return tdc
->savePNGFromDC(name
.mb_str(), 0, 0, w
, h
);
774 case wxBITMAP_TYPE_PCX
:
775 return tdc
->savePCXFromDC(name
.mb_str(), 0, 0, w
, h
);
785 // let's handle PNGs in special way because they have alpha channel
786 // which we can access via bitmap_t most easily
787 class wxPNGBitmapHandler
: public wxMGLBitmapHandler
790 wxPNGBitmapHandler(wxBitmapType type
,
791 const wxString
& extension
, const wxString
& name
)
792 : wxMGLBitmapHandler(type
, extension
, name
) {}
794 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
795 int desiredWidth
, int desiredHeight
);
798 bool wxPNGBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
,
800 int desiredWidth
, int desiredHeight
)
802 int width
, height
, bpp
;
806 if ( flags
== wxBITMAP_TYPE_PNG_RESOURCE
)
807 fullname
= name
+ wxT(".png");
811 if ( !MGL_getPNGSize(fullname
.mb_str(), &width
, &height
, &bpp
, &pf
) )
816 // We can load ordinary PNGs faster with 'normal' MGL handler.
817 // Only RGBA PNGs need to be processed in special way because
818 // we have to convert alpha channel to mask
819 return wxMGLBitmapHandler::LoadFile(bitmap
, name
, flags
,
820 desiredWidth
, desiredHeight
);
823 bitmap_t
*bmp
= MGL_loadPNG(fullname
.mb_str(), TRUE
);
825 if ( bmp
== NULL
) return FALSE
;
827 bitmap
->Create(bmp
->width
, bmp
->height
, -1);
828 if ( !bitmap
->Ok() ) return FALSE
;
830 // convert bmp to display's depth and write it to *bitmap:
832 dc
.SelectObject(*bitmap
);
833 dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
);
834 dc
.SelectObject(wxNullBitmap
);
836 // create mask, if bmp contains alpha channel (ARGB format):
837 if ( bmp
->bitsPerPixel
== 32 )
840 wxUint32
*s
= (wxUint32
*)bmp
->surface
;
841 for (y
= 0; y
< bmp
->height
; y
++)
843 s
= ((wxUint32
*)bmp
->surface
) + y
* bmp
->bytesPerLine
/4;
844 for (x
= 0; x
< bmp
->width
; x
++, s
++)
846 if ( ((((*s
) >> bmp
->pf
->rsvdPos
) & bmp
->pf
->rsvdMask
)
847 << bmp
->pf
->rsvdAdjust
) < 128 )
850 *s
= 0x00FFFFFF; // white
853 wxBitmap
mask(bmp
->width
, bmp
->height
, 1);
854 dc
.SelectObject(mask
);
855 dc
.GetMGLDC()->putBitmap(0, 0, bmp
, MGL_REPLACE_MODE
);
856 dc
.SelectObject(wxNullBitmap
);
857 bitmap
->SetMask(new wxMask(mask
));
860 MGL_unloadBitmap(bmp
);
868 class wxICOBitmapHandler
: public wxBitmapHandler
871 wxICOBitmapHandler(wxBitmapType type
,
872 const wxString
& extension
, const wxString
& name
);
874 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
,
875 int width
, int height
, int depth
= 1)
878 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
879 int desiredWidth
, int desiredHeight
);
880 virtual bool SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
881 int type
, const wxPalette
*palette
= NULL
);
884 wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type
,
885 const wxString
& extension
,
886 const wxString
& name
)
891 SetExtension(extension
);
894 bool wxICOBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
,
896 int WXUNUSED(desiredWidth
),
897 int WXUNUSED(desiredHeight
))
902 if ( flags
== wxBITMAP_TYPE_ICO_RESOURCE
)
903 icon
= MGL_loadIcon(wxString(name
+ wxT(".ico")).mb_str(), TRUE
);
905 icon
= MGL_loadIcon(name
.mb_str(), TRUE
);
907 if ( icon
== NULL
) return FALSE
;
909 bitmap
->Create(icon
->xorMask
.width
, icon
->xorMask
.height
);
912 mem
.SelectObject(*bitmap
);
914 dc
->putBitmap(0, 0, &(icon
->xorMask
), MGL_REPLACE_MODE
);
915 mem
.SelectObject(wxNullBitmap
);
917 wxBitmap
mask(icon
->xorMask
.width
, icon
->xorMask
.height
, 1);
918 mem
.SelectObject(mask
);
921 wxCurrentDCSwitcher
curDC(dc
);
925 dc
->putMonoImage(0, 0, icon
->xorMask
.width
, icon
->byteWidth
,
926 icon
->xorMask
.height
, (void*)icon
->andMask
);
928 bitmap
->SetMask(new wxMask(mask
));
930 MGL_unloadIcon(icon
);
935 bool wxICOBitmapHandler::SaveFile(const wxBitmap
*bitmap
, const wxString
& name
,
936 int type
, const wxPalette
* WXUNUSED(palette
))
944 /*static*/ void wxBitmap::InitStandardHandlers()
946 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP
, wxT("bmp"), wxT("Windows bitmap")));
947 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_BMP_RESOURCE
, wxEmptyString
, wxT("Windows bitmap resource")));
948 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG
, wxT("jpg"), wxT("JPEG image")));
949 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_JPEG_RESOURCE
, wxEmptyString
, wxT("JPEG resource")));
950 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX
, wxT("pcx"), wxT("PCX image")));
951 AddHandler(new wxMGLBitmapHandler(wxBITMAP_TYPE_PCX_RESOURCE
, wxEmptyString
, wxT("PCX resource")));
953 AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG
, wxT("png"), wxT("PNG image")));
954 AddHandler(new wxPNGBitmapHandler(wxBITMAP_TYPE_PNG_RESOURCE
, wxEmptyString
, wxT("PNG resource")));
956 AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO
, wxT("ico"), wxT("Icon resource")));
957 AddHandler(new wxICOBitmapHandler(wxBITMAP_TYPE_ICO_RESOURCE
, wxEmptyString
, wxT("Icon resource")));