1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 #include "wx/palette.h"
30 #include "wx/bitmap.h"
35 #include "wx/msw/private.h"
42 #include "../src/xpm/xpm34.h"
45 #include "wx/msw/dib.h"
47 #if !USE_SHARED_LIBRARIES
48 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
49 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
52 wxBitmapRefData::wxBitmapRefData(void)
60 m_selectedInto
= NULL
;
65 wxBitmapRefData::~wxBitmapRefData(void)
70 sprintf(buf
, "Bitmap was deleted without selecting out of wxMemoryDC %X.", (unsigned int) m_selectedInto
);
75 DeleteObject((HBITMAP
) m_hBitmap
);
80 // delete m_bitmapMask; // this line cause an exception
85 wxList
wxBitmap::sm_handlers
;
87 wxBitmap::wxBitmap(void)
89 if ( wxTheBitmapList
)
90 wxTheBitmapList
->AddBitmap(this);
93 wxBitmap::~wxBitmap(void)
96 wxTheBitmapList
->DeleteObject(this);
99 bool wxBitmap::FreeResource(bool force
)
104 if (M_BITMAPDATA
->m_selectedInto
)
107 sprintf(buf
, "Bitmap %X was deleted without selecting out of wxMemoryDC %X.", (unsigned int) this, (unsigned int) M_BITMAPDATA
->m_selectedInto
);
110 if (M_BITMAPDATA
->m_hBitmap
)
112 DeleteObject((HBITMAP
) M_BITMAPDATA
->m_hBitmap
);
114 M_BITMAPDATA
->m_hBitmap
= 0 ;
117 if (M_BITMAPDATA->m_bitmapPalette)
118 delete M_BITMAPDATA->m_bitmapPalette;
120 M_BITMAPDATA->m_bitmapPalette = NULL ;
127 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
129 m_refData
= new wxBitmapRefData
;
131 M_BITMAPDATA
->m_width
= the_width
;
132 M_BITMAPDATA
->m_height
= the_height
;
133 M_BITMAPDATA
->m_depth
= no_bits
;
134 M_BITMAPDATA
->m_numColors
= 0;
136 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateBitmap(the_width
, the_height
, 1, no_bits
, bits
);
138 if (M_BITMAPDATA
->m_hBitmap
)
139 M_BITMAPDATA
->m_ok
= TRUE
;
141 M_BITMAPDATA
->m_ok
= FALSE
;
143 M_BITMAPDATA
->m_selectedInto
= NULL
;
145 if ( wxTheBitmapList
)
146 wxTheBitmapList
->AddBitmap(this);
149 wxBitmap::wxBitmap(int w
, int h
, int d
)
151 (void)Create(w
, h
, d
);
153 if ( wxTheBitmapList
)
154 wxTheBitmapList
->AddBitmap(this);
157 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
159 (void) Create(data
, type
, width
, height
, depth
);
161 if ( wxTheBitmapList
)
162 wxTheBitmapList
->AddBitmap(this);
165 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
167 LoadFile(filename
, (int)type
);
169 if ( wxTheBitmapList
)
170 wxTheBitmapList
->AddBitmap(this);
175 wxBitmap::wxBitmap(char **data
, wxItem
*WXUNUSED(anItem
))
177 (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
181 bool wxBitmap::Create(int w
, int h
, int d
)
185 m_refData
= new wxBitmapRefData
;
187 M_BITMAPDATA
->m_width
= w
;
188 M_BITMAPDATA
->m_height
= h
;
189 M_BITMAPDATA
->m_depth
= d
;
193 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateBitmap(w
, h
, 1, d
, NULL
);
197 HDC dc
= GetDC(NULL
);
198 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateCompatibleBitmap(dc
, w
, h
);
200 M_BITMAPDATA
->m_depth
= wxDisplayDepth();
202 if (M_BITMAPDATA
->m_hBitmap
)
203 M_BITMAPDATA
->m_ok
= TRUE
;
205 M_BITMAPDATA
->m_ok
= FALSE
;
206 return M_BITMAPDATA
->m_ok
;
209 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
213 m_refData
= new wxBitmapRefData
;
215 wxBitmapHandler
*handler
= FindHandler(type
);
217 if ( handler
== NULL
) {
218 wxLogWarning("no bitmap handler for type %d defined.", type
);
223 return handler
->LoadFile(this, filename
, type
, -1, -1);
226 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
230 m_refData
= new wxBitmapRefData
;
232 wxBitmapHandler
*handler
= FindHandler(type
);
234 if ( handler
== NULL
) {
235 wxLogWarning("no bitmap handler for type %d defined.", type
);
240 return handler
->Create(this, data
, type
, width
, height
, depth
);
243 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
245 wxBitmapHandler
*handler
= FindHandler(type
);
247 if ( handler
== NULL
) {
248 wxLogWarning("no bitmap handler for type %d defined.", type
);
253 return handler
->SaveFile(this, filename
, type
, palette
);
256 void wxBitmap::SetWidth(int w
)
259 m_refData
= new wxBitmapRefData
;
261 M_BITMAPDATA
->m_width
= w
;
264 void wxBitmap::SetHeight(int h
)
267 m_refData
= new wxBitmapRefData
;
269 M_BITMAPDATA
->m_height
= h
;
272 void wxBitmap::SetDepth(int d
)
275 m_refData
= new wxBitmapRefData
;
277 M_BITMAPDATA
->m_depth
= d
;
280 void wxBitmap::SetQuality(int q
)
283 m_refData
= new wxBitmapRefData
;
285 M_BITMAPDATA
->m_quality
= q
;
288 void wxBitmap::SetOk(bool isOk
)
291 m_refData
= new wxBitmapRefData
;
293 M_BITMAPDATA
->m_ok
= isOk
;
296 void wxBitmap::SetPalette(const wxPalette
& palette
)
299 m_refData
= new wxBitmapRefData
;
301 M_BITMAPDATA
->m_bitmapPalette
= palette
;
304 void wxBitmap::SetMask(wxMask
*mask
)
307 m_refData
= new wxBitmapRefData
;
309 M_BITMAPDATA
->m_bitmapMask
= mask
;
312 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
315 m_refData
= new wxBitmapRefData
;
317 M_BITMAPDATA
->m_hBitmap
= bmp
;
320 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
322 sm_handlers
.Append(handler
);
325 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
327 sm_handlers
.Insert(handler
);
330 bool wxBitmap::RemoveHandler(const wxString
& name
)
332 wxBitmapHandler
*handler
= FindHandler(name
);
335 sm_handlers
.DeleteObject(handler
);
342 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
344 wxNode
*node
= sm_handlers
.First();
347 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
348 if ( handler
->GetName() == name
)
355 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
357 wxNode
*node
= sm_handlers
.First();
360 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
361 if ( handler
->GetExtension() == extension
&&
362 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
369 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
371 wxNode
*node
= sm_handlers
.First();
374 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
375 if (handler
->GetType() == bitmapType
)
382 // New Create/FreeDIB functions since ones in dibutils.cpp are confusing
383 static long createDIB(long xSize
, long ySize
, long bitsPerPixel
,
384 HPALETTE hPal
, LPBITMAPINFO
* lpDIBHeader
);
385 static long freeDIB(LPBITMAPINFO lpDIBHeader
);
387 // Creates a bitmap that matches the device context, from
388 // an arbitray bitmap. At present, the original bitmap must have an
389 // associated palette. TODO: use a default palette if no palette exists.
390 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
391 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& dc
) const
394 wxBitmap
tmpBitmap(this->GetWidth(), this->GetHeight(), dc
.GetDepth());
395 HPALETTE hPal
= NULL
;
400 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
402 tmpBitmap.SetPalette(this->GetPalette());
403 memDC.SelectObject(tmpBitmap);
404 memDC.SetPalette(this->GetPalette());
406 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
408 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
410 tmpBitmap
.SetPalette(* this->GetPalette());
411 memDC
.SelectObject(tmpBitmap
);
412 memDC
.SetPalette(* this->GetPalette());
413 hPal
= (HPALETTE
) this->GetPalette()->GetHPALETTE();
417 hPal
= (HPALETTE
) ::GetStockObject(DEFAULT_PALETTE
);
419 palette
.SetHPALETTE( (WXHPALETTE
)hPal
);
420 tmpBitmap
.SetPalette( palette
);
421 memDC
.SelectObject(tmpBitmap
);
422 memDC
.SetPalette( palette
);
425 // set the height negative because in a DIB the order of the lines is reversed
426 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal
, &lpDib
);
428 lpBits
= malloc(lpDib
->bmiHeader
.biSizeImage
);
430 ::GetBitmapBits((HBITMAP
)GetHBITMAP(), lpDib
->bmiHeader
.biSizeImage
, lpBits
);
432 ::SetDIBitsToDevice((HDC
) memDC
.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
433 0, 0, 0, this->GetHeight(), lpBits
, lpDib
, DIB_RGB_COLORS
);
450 // Construct a mask from a bitmap and a colour indicating
451 // the transparent area
452 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
455 Create(bitmap
, colour
);
458 // Construct a mask from a bitmap and a palette index indicating
459 // the transparent area
460 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
463 Create(bitmap
, paletteIndex
);
466 // Construct a mask from a mono bitmap (copies the bitmap).
467 wxMask::wxMask(const wxBitmap
& bitmap
)
473 wxMask::~wxMask(void)
476 ::DeleteObject((HBITMAP
) m_maskBitmap
);
479 // Create a mask from a mono bitmap (copies the bitmap).
480 bool wxMask::Create(const wxBitmap
& bitmap
)
484 ::DeleteObject((HBITMAP
) m_maskBitmap
);
487 if (!bitmap
.Ok() || bitmap
.GetDepth() != 1)
491 m_maskBitmap
= (WXHBITMAP
) CreateBitmap(
496 HDC srcDC
= CreateCompatibleDC(0);
497 SelectObject(srcDC
, (HBITMAP
) bitmap
.GetHBITMAP());
498 HDC destDC
= CreateCompatibleDC(0);
499 SelectObject(destDC
, (HBITMAP
) m_maskBitmap
);
500 BitBlt(destDC
, 0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), srcDC
, 0, 0, SRCCOPY
);
501 SelectObject(srcDC
, 0);
503 SelectObject(destDC
, 0);
508 // Create a mask from a bitmap and a palette index indicating
509 // the transparent area
510 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
514 ::DeleteObject((HBITMAP
) m_maskBitmap
);
517 if (bitmap
.Ok() && bitmap
.GetPalette()->Ok())
519 unsigned char red
, green
, blue
;
520 if (bitmap
.GetPalette()->GetRGB(paletteIndex
, &red
, &green
, &blue
))
522 wxColour
transparentColour(red
, green
, blue
);
523 return Create(bitmap
, transparentColour
);
529 // Create a mask from a bitmap and a colour indicating
530 // the transparent area
531 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
535 ::DeleteObject((HBITMAP
) m_maskBitmap
);
543 // scan the bitmap for the transparent colour and set
544 // the corresponding pixels in the mask to BLACK and
546 COLORREF maskColour
= RGB(colour
.Red(), colour
.Green(), colour
.Blue());
547 m_maskBitmap
= (WXHBITMAP
) ::CreateBitmap(
552 HDC srcDC
= ::CreateCompatibleDC(0);
553 ::SelectObject(srcDC
, (HBITMAP
) bitmap
.GetHBITMAP());
554 HDC destDC
= ::CreateCompatibleDC(0);
555 ::SelectObject(destDC
, (HBITMAP
) m_maskBitmap
);
557 // this is not very efficient, but I can't think
558 // of a better way of doing it
559 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
561 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
563 COLORREF col
= GetPixel(srcDC
, w
, h
);
564 if (col
== maskColour
)
566 ::SetPixel(destDC
, w
, h
, RGB(0, 0, 0));
570 ::SetPixel(destDC
, w
, h
, RGB(255, 255, 255));
574 ::SelectObject(srcDC
, 0);
576 ::SelectObject(destDC
, 0);
585 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
587 bool wxBitmapHandler::Create(wxBitmap
*bitmap
, void *data
, long type
, int width
, int height
, int depth
)
592 bool wxBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long type
,
593 int desiredWidth
, int desiredHeight
)
598 bool wxBitmapHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
607 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
609 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
611 inline wxBMPResourceHandler(void)
613 m_name
= "Windows bitmap resource";
615 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
618 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
619 int desiredWidth
, int desiredHeight
);
621 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
623 bool wxBMPResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
624 int desiredWidth
, int desiredHeight
)
626 // TODO: load colourmap.
627 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ::LoadBitmap(wxGetInstance(), name
);
628 if (M_BITMAPHANDLERDATA
->m_hBitmap
)
630 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
632 GetObject((HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(BITMAP
), (LPSTR
) &bm
);
633 M_BITMAPHANDLERDATA
->m_width
= bm
.bmWidth
;
634 M_BITMAPHANDLERDATA
->m_height
= bm
.bmHeight
;
635 M_BITMAPHANDLERDATA
->m_depth
= bm
.bmBitsPixel
;
639 // it's probably not found
640 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str());
645 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
647 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
)
649 inline wxBMPFileHandler(void)
651 m_name
= "Windows bitmap file";
653 m_type
= wxBITMAP_TYPE_BMP
;
656 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
657 int desiredWidth
, int desiredHeight
);
658 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
660 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
)
662 bool wxBMPFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
663 int desiredWidth
, int desiredHeight
)
665 #if wxUSE_IMAGE_LOADING_IN_MSW
666 wxPalette
*palette
= NULL
;
667 bool success
= FALSE
;
669 if (type & wxBITMAP_DISCARD_COLOURMAP)
670 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
673 success
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0);
674 if (!success
&& palette
)
680 M_BITMAPHANDLERDATA
->m_bitmapPalette
= *palette
;
687 bool wxBMPFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*pal
)
689 #if wxUSE_IMAGE_LOADING_IN_MSW
690 wxPalette
*actualPalette
= (wxPalette
*)pal
;
691 if (!actualPalette
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull()))
692 actualPalette
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
);
693 return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0);
699 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
701 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
703 inline wxXPMFileHandler(void)
705 m_name
= "XPM bitmap file";
707 m_type
= wxBITMAP_TYPE_XPM
;
710 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
711 int desiredWidth
= -1, int desiredHeight
= -1);
712 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
714 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
716 bool wxXPMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
717 int desiredWidth
, int desiredHeight
)
721 XpmAttributes xpmAttr
;
724 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
725 dc
= CreateCompatibleDC(NULL
);
728 xpmAttr
.valuemask
= XpmReturnPixels
;
729 int errorStatus
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage
**) NULL
, &xpmAttr
);
731 if (errorStatus
== XpmSuccess
)
733 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ximage
->bitmap
;
736 GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
);
738 M_BITMAPHANDLERDATA
->m_width
= (bm
.bmWidth
);
739 M_BITMAPHANDLERDATA
->m_height
= (bm
.bmHeight
);
740 M_BITMAPHANDLERDATA
->m_depth
= (bm
.bmPlanes
* bm
.bmBitsPixel
);
741 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
742 XpmFreeAttributes(&xpmAttr
);
745 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
750 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
759 bool wxXPMFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
766 dc
= CreateCompatibleDC(NULL
);
769 if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
))
771 /* for following SetPixel */
772 /* fill the XImage struct 'by hand' */
773 ximage
.width
= M_BITMAPHANDLERDATA
->m_width
;
774 ximage
.height
= M_BITMAPHANDLERDATA
->m_height
;
775 ximage
.depth
= M_BITMAPHANDLERDATA
->m_depth
;
776 ximage
.bitmap
= (HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
;
777 int errorStatus
= XpmWriteFileFromImage(&dc
, WXSTRINGCAST name
,
778 &ximage
, (XImage
*) NULL
, (XpmAttributes
*) NULL
);
783 if (errorStatus
== XpmSuccess
)
784 return TRUE
; /* no error */
794 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
796 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
798 inline wxXPMDataHandler(void)
800 m_name
= "XPM bitmap data";
802 m_type
= wxBITMAP_TYPE_XPM_DATA
;
805 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
807 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
809 bool wxXPMDataHandler::Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
)
814 XpmAttributes xpmAttr
;
817 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
818 M_BITMAPHANDLERDATA
->m_numColors
= 0;
820 dc
= CreateCompatibleDC(NULL
); /* memory DC */
824 xpmAttr
.valuemask
= XpmReturnInfos
; /* get infos back */
825 ErrorStatus
= XpmCreateImageFromData(&dc
, (char **)data
,
826 &ximage
, (XImage
**) NULL
, &xpmAttr
);
828 if (ErrorStatus
== XpmSuccess
)
830 /* ximage is malloced and contains bitmap and attributes */
831 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ximage
->bitmap
;
834 GetObject((HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
);
836 M_BITMAPHANDLERDATA
->m_width
= (bm
.bmWidth
);
837 M_BITMAPHANDLERDATA
->m_height
= (bm
.bmHeight
);
838 M_BITMAPHANDLERDATA
->m_depth
= (bm
.bmPlanes
* bm
.bmBitsPixel
);
839 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
840 XpmFreeAttributes(&xpmAttr
);
842 XImageFree(ximage
); // releases the malloc, but does not detroy
844 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
851 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
852 // XpmDebugError(ErrorStatus, NULL);
862 void wxBitmap::CleanUpHandlers(void)
864 wxNode
*node
= sm_handlers
.First();
867 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
868 wxNode
*next
= node
->Next();
875 void wxBitmap::InitStandardHandlers(void)
877 AddHandler(new wxBMPResourceHandler
);
878 AddHandler(new wxBMPFileHandler
);
879 AddHandler(new wxXPMFileHandler
);
880 AddHandler(new wxXPMDataHandler
);
881 AddHandler(new wxICOResourceHandler
);
882 AddHandler(new wxICOFileHandler
);
885 static long createDIB(long xSize
, long ySize
, long bitsPerPixel
,
886 HPALETTE hPal
, LPBITMAPINFO
* lpDIBHeader
)
888 unsigned long i
, headerSize
;
889 LPBITMAPINFO lpDIBheader
= NULL
;
890 LPPALETTEENTRY lpPe
= NULL
;
893 // Allocate space for a DIB header
894 headerSize
= (sizeof(BITMAPINFOHEADER
) + (256 * sizeof(PALETTEENTRY
)));
895 lpDIBheader
= (BITMAPINFO
*) malloc(headerSize
);
896 lpPe
= (PALETTEENTRY
*)((BYTE
*)lpDIBheader
+ sizeof(BITMAPINFOHEADER
));
898 GetPaletteEntries(hPal
, 0, 256, lpPe
);
901 memset(lpDIBheader
, 0x00, sizeof(BITMAPINFOHEADER
));
904 // Fill in the static parts of the DIB header
905 lpDIBheader
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
906 lpDIBheader
->bmiHeader
.biWidth
= xSize
;
907 lpDIBheader
->bmiHeader
.biHeight
= ySize
;
908 lpDIBheader
->bmiHeader
.biPlanes
= 1;
910 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
911 lpDIBheader
->bmiHeader
.biBitCount
= (WORD
)(bitsPerPixel
);
912 lpDIBheader
->bmiHeader
.biCompression
= BI_RGB
;
913 lpDIBheader
->bmiHeader
.biSizeImage
= xSize
* abs(ySize
) * bitsPerPixel
>>
915 lpDIBheader
->bmiHeader
.biClrUsed
= 256;
918 // Initialize the DIB palette
919 for (i
= 0; i
< 256; i
++) {
920 lpDIBheader
->bmiColors
[i
].rgbReserved
= lpPe
[i
].peFlags
;
921 lpDIBheader
->bmiColors
[i
].rgbRed
= lpPe
[i
].peRed
;
922 lpDIBheader
->bmiColors
[i
].rgbGreen
= lpPe
[i
].peGreen
;
923 lpDIBheader
->bmiColors
[i
].rgbBlue
= lpPe
[i
].peBlue
;
926 *lpDIBHeader
= lpDIBheader
;
935 static long freeDIB(LPBITMAPINFO lpDIBHeader
)
938 if (lpDIBHeader
!= NULL
) {
946 //-----------------------------------------------------------------------------
947 // also implemented here from wxImage
948 //-----------------------------------------------------------------------------
951 class wxImage : wxGDIObject
953 wxImage( const wxBitmap &bitmap );
954 wxBitmap ConvertToBitmap() const;
959 wxBitmap
wxImage::ConvertToBitmap() const
963 wxCHECK_MSG( Ok(), bitmap
, "invalid image" );
964 int width
= GetWidth();
965 int height
= GetHeight();
966 bitmap
.SetWidth( width
);
967 bitmap
.SetHeight( height
);
968 bitmap
.SetDepth( wxDisplayDepth() );
970 int headersize
= sizeof(BITMAPINFOHEADER
);
971 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
972 wxCHECK_MSG( lpDIBh
, bitmap
, "could not allocate memory for DIB header" );
974 // Fill in the DIB header
975 lpDIBh
->bmiHeader
.biSize
= headersize
;
976 lpDIBh
->bmiHeader
.biWidth
= width
;
977 lpDIBh
->bmiHeader
.biHeight
= -height
;
978 lpDIBh
->bmiHeader
.biSizeImage
= width
* height
* 3;
980 lpDIBh
->bmiHeader
.biPlanes
= 1;
981 lpDIBh
->bmiHeader
.biBitCount
= 24;
982 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
983 lpDIBh
->bmiHeader
.biClrUsed
= 0;
985 // These seem not needed for our purpose here.
986 // lpDIBh->bmiHeader.biClrImportant = 0;
987 // lpDIBh->bmiHeader.biXPelsPerMeter = 0;
988 // lpDIBh->bmiHeader.biYPelsPerMeter = 0;
990 unsigned char *lpBits
= (unsigned char *) malloc( width
*height
*3 );
993 wxFAIL_MSG( "could not allocate memory for DIB" );
998 unsigned char *data
= GetData();
1000 unsigned char *ptdata
= data
, *ptbits
= lpBits
;
1001 for( int i
=0; i
<width
*height
; i
++ )
1003 *(ptbits
++) = *(ptdata
+2);
1004 *(ptbits
++) = *(ptdata
+1);
1005 *(ptbits
++) = *(ptdata
);
1009 HDC hdc
= ::GetDC(NULL
);
1012 hbitmap
= CreateDIBitmap( hdc
, &(lpDIBh
->bmiHeader
), CBM_INIT
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1014 // The above line is equivalent to the following two lines.
1015 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1016 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
1017 // or the following lines
1018 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1019 // HDC memdc = ::CreateCompatibleDC( hdc );
1020 // ::SelectObject( memdc, hbitmap);
1021 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,\
1022 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
1023 // ::SelectObject( memdc, 0 );
1024 // ::DeleteDC( memdc );
1026 bitmap
.SetHBITMAP( (WXHBITMAP
) hbitmap
);
1030 unsigned char r
= GetMaskRed();
1031 unsigned char g
= GetMaskGreen();
1032 unsigned char b
= GetMaskBlue();
1033 unsigned char zero
= 0, one
= 255;
1036 for( int i
=0; i
<width
*height
; i
++ )
1038 if( (*(ptdata
++)!=r
) | (*(ptdata
++)!=g
) | (*(ptdata
++)!=b
) )
1051 hbitmap
= ::CreateBitmap( (WORD
)width
, (WORD
)height
, 1, 1, NULL
);
1052 ::SetDIBits( hdc
, hbitmap
, 0, (WORD
)height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1054 bmpmask
.SetMaskBitmap( (WXHBITMAP
) hbitmap
);
1055 bitmap
.SetMask( &bmpmask
);
1057 /* The following can also be used but is slow to run
1058 wxColour colour( GetMaskRed(), GetMaskGreen(), GetMaskBlue());
1059 wxMask bmpmask( bitmap, colour );
1060 bitmap.SetMask( &bmpmask );
1064 ::ReleaseDC(NULL
, hdc
);
1068 if( bitmap
.GetHBITMAP() )
1069 bitmap
.SetOk( TRUE
);
1071 bitmap
.SetOk( FALSE
);
1077 wxImage::wxImage( const wxBitmap
&bitmap
)
1081 wxFAIL_MSG( "invalid bitmap" );
1085 int width
= bitmap
.GetWidth();
1086 int height
= bitmap
.GetHeight();
1087 Create( width
, height
);
1088 unsigned char *data
= GetData();
1091 wxFAIL_MSG( "could not allocate data for image" );
1095 int headersize
= sizeof(BITMAPINFOHEADER
);
1096 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
1099 wxFAIL_MSG( "could not allocate data for DIB header" );
1104 // Fill in the DIB header
1105 lpDIBh
->bmiHeader
.biSize
= headersize
;
1106 lpDIBh
->bmiHeader
.biWidth
= width
;
1107 lpDIBh
->bmiHeader
.biHeight
= -height
;
1108 lpDIBh
->bmiHeader
.biSizeImage
= width
* height
* 3;
1110 lpDIBh
->bmiHeader
.biPlanes
= 1;
1111 lpDIBh
->bmiHeader
.biBitCount
= 24;
1112 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
1113 lpDIBh
->bmiHeader
.biClrUsed
= 0;
1115 // These seem not needed for our purpose here.
1116 // lpDIBh->bmiHeader.biClrImportant = 0;
1117 // lpDIBh->bmiHeader.biXPelsPerMeter = 0;
1118 // lpDIBh->bmiHeader.biYPelsPerMeter = 0;
1120 unsigned char *lpBits
= (unsigned char *) malloc( width
*height
*3 );
1123 wxFAIL_MSG( "could not allocate data for DIB" );
1130 hbitmap
= (HBITMAP
) bitmap
.GetHBITMAP();
1131 HDC hdc
= ::GetDC(NULL
);
1132 ::GetDIBits( hdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1134 unsigned char *ptdata
= data
, *ptbits
= lpBits
;
1135 for( int i
=0; i
<width
*height
; i
++ )
1137 *(ptdata
++) = *(ptbits
+2);
1138 *(ptdata
++) = *(ptbits
+1);
1139 *(ptdata
++) = *(ptbits
);
1143 if( bitmap
.GetMask() && bitmap
.GetMask()->GetMaskBitmap() )
1145 hbitmap
= (HBITMAP
) bitmap
.GetMask()->GetMaskBitmap();
1146 HDC memdc
= ::CreateCompatibleDC( hdc
);
1147 ::SetTextColor( memdc
, RGB( 0, 0, 0 ) );
1148 ::SetBkColor( memdc
, RGB( 255, 255, 255 ) );
1149 ::GetDIBits( memdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1150 ::DeleteDC( memdc
);
1151 unsigned char r
=16, g
=16, b
=16; // background set to RGB(16,16,16)
1154 for( int i
=0; i
<width
*height
; i
++ )
1164 SetMaskColour( r
, g
, b
);
1167 ::ReleaseDC(NULL
, hdc
);