]> git.saurik.com Git - wxWidgets.git/blame - src/msw/bitmap.cpp
App declarations modified; cursor was corrupt; needed to add PostScript-related variable.
[wxWidgets.git] / src / msw / bitmap.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: bitmap.cpp
3// Purpose: wxBitmap
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "bitmap.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <stdio.h>
25#include "wx/setup.h"
26#include "wx/list.h"
27#include "wx/utils.h"
28#include "wx/app.h"
29#include "wx/palette.h"
30#include "wx/bitmap.h"
31#include "wx/icon.h"
32#endif
33
34#include "wx/msw/private.h"
35#include "assert.h"
36
37#if USE_XPM_IN_MSW
38#define FOR_MSW 1
39#include "..\..\contrib\wxxpm\libxpm.34b\lib\xpm34.h"
40#endif
41
42#include "wx/msw/dib.h"
43
44#if !USE_SHARED_LIBRARIES
45IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
46IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
47#endif
48
49wxBitmapRefData::wxBitmapRefData(void)
50{
51 m_ok = FALSE;
52 m_width = 0;
53 m_height = 0;
54 m_depth = 0;
55 m_quality = 0;
56 m_hBitmap = 0 ;
57 m_selectedInto = NULL;
58 m_numColors = 0;
59 m_bitmapMask = NULL;
60}
61
62wxBitmapRefData::~wxBitmapRefData(void)
63{
64 if (m_selectedInto)
65 {
66 char buf[200];
67 sprintf(buf, "Bitmap was deleted without selecting out of wxMemoryDC %X.", (unsigned int) m_selectedInto);
68 wxFatalError(buf);
69 }
70 if (m_hBitmap)
71 {
72 DeleteObject((HBITMAP) m_hBitmap);
73 }
74 m_hBitmap = 0 ;
75
76 if (m_bitmapMask)
77 delete m_bitmapMask;
78 m_bitmapMask = NULL;
79}
80
81wxList wxBitmap::sm_handlers;
82
83wxBitmap::wxBitmap(void)
84{
85 m_refData = NULL; // new wxBitmapRefData;
86
87 if ( wxTheBitmapList )
88 wxTheBitmapList->AddBitmap(this);
89}
90
91wxBitmap::~wxBitmap(void)
92{
93 if (wxTheBitmapList)
94 wxTheBitmapList->DeleteObject(this);
95}
96
97bool wxBitmap::FreeResource(bool force)
98{
99 if ( !M_BITMAPDATA )
100 return FALSE;
101
102 if (M_BITMAPDATA->m_selectedInto)
103 {
104 char buf[200];
105 sprintf(buf, "Bitmap %X was deleted without selecting out of wxMemoryDC %X.", (unsigned int) this, (unsigned int) M_BITMAPDATA->m_selectedInto);
106 wxFatalError(buf);
107 }
108 if (M_BITMAPDATA->m_hBitmap)
109 {
110 DeleteObject((HBITMAP) M_BITMAPDATA->m_hBitmap);
111 }
112 M_BITMAPDATA->m_hBitmap = 0 ;
113
114/*
115 if (M_BITMAPDATA->m_bitmapPalette)
116 delete M_BITMAPDATA->m_bitmapPalette;
117
118 M_BITMAPDATA->m_bitmapPalette = NULL ;
119*/
120
121 return TRUE;
122}
123
124
125wxBitmap::wxBitmap(const char bits[], const int the_width, const int the_height, const int no_bits)
126{
127 m_refData = new wxBitmapRefData;
128
129 M_BITMAPDATA->m_width = the_width ;
130 M_BITMAPDATA->m_height = the_height ;
131 M_BITMAPDATA->m_depth = no_bits ;
132 M_BITMAPDATA->m_numColors = 0;
133
134 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, no_bits, 1, bits);
135
136 if (M_BITMAPDATA->m_hBitmap)
137 M_BITMAPDATA->m_ok = TRUE;
138 else
139 M_BITMAPDATA->m_ok = FALSE;
140
141 M_BITMAPDATA->m_selectedInto = NULL;
142
143 if ( wxTheBitmapList )
144 wxTheBitmapList->AddBitmap(this);
145}
146
147wxBitmap::wxBitmap(const int w, const int h, const int d)
148{
149 (void)Create(w, h, d);
150
151 if ( wxTheBitmapList )
152 wxTheBitmapList->AddBitmap(this);
153}
154
155wxBitmap::wxBitmap(void *data, const long type, const int width, const int height, const int depth)
156{
157 (void) Create(data, type, width, height, depth);
158
159 if ( wxTheBitmapList )
160 wxTheBitmapList->AddBitmap(this);
161}
162
163wxBitmap::wxBitmap(const wxString& filename, const long type)
164{
165 LoadFile(filename, (int)type);
166
167 if ( wxTheBitmapList )
168 wxTheBitmapList->AddBitmap(this);
169}
170
171#if USE_XPM_IN_MSW
172// Create from data
173wxBitmap::wxBitmap(const char **data, wxItem *WXUNUSED(anItem))
174{
175 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
176}
177#endif
178
179bool wxBitmap::Create(const int w, const int h, const int d)
180{
181 UnRef();
182
183 m_refData = new wxBitmapRefData;
184
185 M_BITMAPDATA->m_width = w;
186 M_BITMAPDATA->m_height = h;
187 M_BITMAPDATA->m_depth = d;
188
189 if (d > 0)
190 {
191 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, d, 1, NULL);
192 }
193 else
194 {
195 HDC dc = GetDC(NULL);
196 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
197 ReleaseDC(NULL, dc);
198 M_BITMAPDATA->m_depth = wxDisplayDepth();
199 }
200 if (M_BITMAPDATA->m_hBitmap)
201 M_BITMAPDATA->m_ok = TRUE;
202 else
203 M_BITMAPDATA->m_ok = FALSE;
204 return M_BITMAPDATA->m_ok;
205}
206
207bool wxBitmap::LoadFile(const wxString& filename, const long type)
208{
209 UnRef();
210
211 m_refData = new wxBitmapRefData;
212
213 wxBitmapHandler *handler = FindHandler(type);
214
215 if ( handler )
216 return handler->LoadFile(this, filename, type, -1, -1);
217 else
218 return FALSE;
219}
220
221bool wxBitmap::Create(void *data, const long type, const int width, const int height, const int depth)
222{
223 UnRef();
224
225 m_refData = new wxBitmapRefData;
226
227 wxBitmapHandler *handler = FindHandler(type);
228
229 if ( handler )
230 return handler->Create(this, data, type, width, height, depth);
231 else
232 return FALSE;
233}
234
235bool wxBitmap::SaveFile(const wxString& filename, const int type, const wxPalette *palette)
236{
237 wxBitmapHandler *handler = FindHandler(type);
238
239 if ( handler )
240 return handler->SaveFile(this, filename, type, palette);
241 else
242 return FALSE;
243}
244
245void wxBitmap::SetWidth(int w)
246{
247 if (!M_BITMAPDATA)
248 m_refData = new wxBitmapRefData;
249
250 M_BITMAPDATA->m_width = w;
251}
252
253void wxBitmap::SetHeight(int h)
254{
255 if (!M_BITMAPDATA)
256 m_refData = new wxBitmapRefData;
257
258 M_BITMAPDATA->m_height = h;
259}
260
261void wxBitmap::SetDepth(int d)
262{
263 if (!M_BITMAPDATA)
264 m_refData = new wxBitmapRefData;
265
266 M_BITMAPDATA->m_depth = d;
267}
268
269void wxBitmap::SetQuality(int q)
270{
271 if (!M_BITMAPDATA)
272 m_refData = new wxBitmapRefData;
273
274 M_BITMAPDATA->m_quality = q;
275}
276
277void wxBitmap::SetOk(bool isOk)
278{
279 if (!M_BITMAPDATA)
280 m_refData = new wxBitmapRefData;
281
282 M_BITMAPDATA->m_ok = isOk;
283}
284
285void wxBitmap::SetPalette(const wxPalette& palette)
286{
287 if (!M_BITMAPDATA)
288 m_refData = new wxBitmapRefData;
289
290 M_BITMAPDATA->m_bitmapPalette = palette ;
291}
292
293void wxBitmap::SetMask(wxMask *mask)
294{
295 if (!M_BITMAPDATA)
296 m_refData = new wxBitmapRefData;
297
298 M_BITMAPDATA->m_bitmapMask = mask ;
299}
300
301void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
302{
303 if (!M_BITMAPDATA)
304 m_refData = new wxBitmapRefData;
305
306 M_BITMAPDATA->m_hBitmap = bmp;
307}
308
309void wxBitmap::AddHandler(wxBitmapHandler *handler)
310{
311 sm_handlers.Append(handler);
312}
313
314void wxBitmap::InsertHandler(wxBitmapHandler *handler)
315{
316 sm_handlers.Insert(handler);
317}
318
319bool wxBitmap::RemoveHandler(const wxString& name)
320{
321 wxBitmapHandler *handler = FindHandler(name);
322 if ( handler )
323 {
324 sm_handlers.DeleteObject(handler);
325 return TRUE;
326 }
327 else
328 return FALSE;
329}
330
331wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
332{
333 wxNode *node = sm_handlers.First();
334 while ( node )
335 {
336 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
337 if ( handler->GetName() == name )
338 return handler;
339 node = node->Next();
340 }
341 return NULL;
342}
343
344wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
345{
346 wxNode *node = sm_handlers.First();
347 while ( node )
348 {
349 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
350 if ( handler->GetExtension() == extension &&
351 (bitmapType == -1 || handler->GetType() == bitmapType) )
352 return handler;
353 node = node->Next();
354 }
355 return NULL;
356}
357
358wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
359{
360 wxNode *node = sm_handlers.First();
361 while ( node )
362 {
363 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
364 if (handler->GetType() == bitmapType)
365 return handler;
366 node = node->Next();
367 }
368 return NULL;
369}
370
371/*
372 * wxMask
373 */
374
375wxMask::wxMask(void)
376{
377 m_maskBitmap = 0;
378}
379
380// Construct a mask from a bitmap and a colour indicating
381// the transparent area
382wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
383{
384 m_maskBitmap = 0;
385 Create(bitmap, colour);
386}
387
388// Construct a mask from a bitmap and a palette index indicating
389// the transparent area
390wxMask::wxMask(const wxBitmap& bitmap, const int paletteIndex)
391{
392 m_maskBitmap = 0;
393 Create(bitmap, paletteIndex);
394}
395
396// Construct a mask from a mono bitmap (copies the bitmap).
397wxMask::wxMask(const wxBitmap& bitmap)
398{
399 m_maskBitmap = 0;
400 Create(bitmap);
401}
402
403wxMask::~wxMask(void)
404{
405 if ( m_maskBitmap )
406 ::DeleteObject((HBITMAP) m_maskBitmap);
407}
408
409// Create a mask from a mono bitmap (copies the bitmap).
410bool wxMask::Create(const wxBitmap& bitmap)
411{
412 if ( m_maskBitmap )
413 {
414 ::DeleteObject((HBITMAP) m_maskBitmap);
415 m_maskBitmap = 0;
416 }
417 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
418 {
419 return FALSE;
420 }
421 m_maskBitmap = (WXHBITMAP) CreateBitmap(
422 bitmap.GetWidth(),
423 bitmap.GetHeight(),
424 1, 1, 0
425 );
426 HDC srcDC = CreateCompatibleDC(0);
427 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
428 HDC destDC = CreateCompatibleDC(0);
429 SelectObject(destDC, (HBITMAP) m_maskBitmap);
430 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
431 SelectObject(srcDC, 0);
432 DeleteDC(srcDC);
433 SelectObject(destDC, 0);
434 DeleteDC(destDC);
435 return TRUE;
436}
437
438// Create a mask from a bitmap and a palette index indicating
439// the transparent area
440bool wxMask::Create(const wxBitmap& bitmap, const int paletteIndex)
441{
442 if ( m_maskBitmap )
443 {
444 ::DeleteObject((HBITMAP) m_maskBitmap);
445 m_maskBitmap = 0;
446 }
447 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
448 {
449 unsigned char red, green, blue;
450 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
451 {
452 wxColour transparentColour(red, green, blue);
453 return Create(bitmap, transparentColour);
454 }
455 }
456 return FALSE;
457}
458
459// Create a mask from a bitmap and a colour indicating
460// the transparent area
461bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
462{
463 if ( m_maskBitmap )
464 {
465 ::DeleteObject((HBITMAP) m_maskBitmap);
466 m_maskBitmap = 0;
467 }
468 if (!bitmap.Ok())
469 {
470 return FALSE;
471 }
472
473 // scan the bitmap for the transparent colour and set
474 // the corresponding pixels in the mask to BLACK and
475 // the rest to WHITE
476 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
477 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
478 bitmap.GetWidth(),
479 bitmap.GetHeight(),
480 1, 1, 0
481 );
482 HDC srcDC = ::CreateCompatibleDC(0);
483 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
484 HDC destDC = ::CreateCompatibleDC(0);
485 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
486
487 // this is not very efficient, but I can't think
488 // of a better way of doing it
489 for (int w = 0; w < bitmap.GetWidth(); w++)
490 {
491 for (int h = 0; h < bitmap.GetHeight(); h++)
492 {
493 COLORREF col = GetPixel(srcDC, w, h);
494 if (col == maskColour)
495 {
496 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
497 }
498 else
499 {
500 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
501 }
502 }
503 }
504 ::SelectObject(srcDC, 0);
505 ::DeleteDC(srcDC);
506 ::SelectObject(destDC, 0);
507 ::DeleteDC(destDC);
508 return TRUE;
509}
510
511/*
512 * wxBitmapHandler
513 */
514
515IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
516
517bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, const long type, const int width, const int height, const int depth)
518{
519 return FALSE;
520}
521
522bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, const long type,
523 int desiredWidth, int desiredHeight)
524{
525 return FALSE;
526}
527
528bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, const int type, const wxPalette *palette)
529{
530 return FALSE;
531}
532
533/*
534 * Standard handlers
535 */
536
537class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
538{
539 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
540public:
541 inline wxBMPResourceHandler(void)
542 {
543 m_name = "Windows bitmap resource";
544 m_extension = "";
545 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
546 };
547
548 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
549 int desiredWidth, int desiredHeight);
550};
551IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
552
553bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
554 int desiredWidth, int desiredHeight)
555{
556 // TODO: load colourmap.
557 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
558 if (M_BITMAPHANDLERDATA->m_hBitmap)
559 {
560 M_BITMAPHANDLERDATA->m_ok = TRUE;
561 BITMAP bm;
562 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
563 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
564 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
565 M_BITMAPHANDLERDATA->m_depth = bm.bmPlanes;
566 return TRUE;
567 }
568 return FALSE;
569}
570
571class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
572{
573 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
574public:
575 inline wxBMPFileHandler(void)
576 {
577 m_name = "Windows bitmap file";
578 m_extension = "bmp";
579 m_type = wxBITMAP_TYPE_BMP;
580 };
581
582 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
583 int desiredWidth, int desiredHeight);
584 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, const int type, const wxPalette *palette = NULL);
585};
586IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
587
588bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
589 int desiredWidth, int desiredHeight)
590{
591#if USE_IMAGE_LOADING_IN_MSW
592 wxPalette *palette = NULL;
593 bool success = FALSE;
594/*
595 if (type & wxBITMAP_DISCARD_COLOURMAP)
596 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
597 else
598*/
599 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
600 if (!success && palette)
601 {
602 delete palette;
603 palette = NULL;
604 }
605 if (palette)
606 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
607 return success;
608#else
609 return FALSE;
610#endif
611}
612
613bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, const int type, const wxPalette *pal)
614{
615#if USE_IMAGE_LOADING_IN_MSW
616 wxPalette *actualPalette = (wxPalette *)pal;
617 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
618 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
619 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
620#else
621 return FALSE;
622#endif
623}
624
625class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
626{
627 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
628public:
629 inline wxXPMFileHandler(void)
630 {
631 m_name = "XPM bitmap file";
632 m_extension = "xpm";
633 m_type = wxBITMAP_TYPE_XPM;
634 };
635
636 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
637 int desiredWidth = -1, int desiredHeight = -1);
638 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, const int type, const wxPalette *palette = NULL);
639};
640IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
641
642bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, const long flags,
643 int desiredWidth, int desiredHeight)
644{
645#if USE_XPM_IN_MSW
646 XImage *ximage;
647 XpmAttributes xpmAttr;
648 HDC dc;
649
650 M_BITMAPHANDLERDATA->m_ok = FALSE;
651 dc = CreateCompatibleDC(NULL);
652 if (dc)
653 {
654 xpmAttr.valuemask = XpmReturnPixels;
655 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
656 DeleteDC(dc);
657 if (errorStatus == XpmSuccess)
658 {
659 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
660
661 BITMAP bm;
662 GetObject((HBITMAP) m_hBitmap, sizeof(bm), (LPSTR) & bm);
663
664 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
665 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
666 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
667 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
668 XpmFreeAttributes(&xpmAttr);
669 XImageFree(ximage);
670
671 M_BITMAPHANDLERDATA->m_ok = TRUE;
672 return TRUE;
673 }
674 else
675 {
676 M_BITMAPHANDLERDATA->m_ok = FALSE;
677 return FALSE;
678 }
679 }
680#else
681 return FALSE;
682#endif
683}
684
685bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, const int type, const wxPalette *palette)
686{
687#if USE_XPM_IN_MSW
688 HDC dc = NULL;
689
690 Visual *visual = NULL;
691 XImage ximage;
692
693 dc = CreateCompatibleDC(NULL);
694 if (dc)
695 {
696 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
697 { /* for following SetPixel */
698 /* fill the XImage struct 'by hand' */
699 ximage.width = M_BITMAPHANDLERDATA->m_width; ximage.height = M_BITMAPHANDLERDATA->m_height;
700 ximage.depth = M_BITMAPHANDLERDATA->m_depth; ximage.bitmap = M_BITMAPHANDLERDATA->m_hBitmap;
701 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
702 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
703
704 if (dc)
705 DeleteDC(dc);
706
707 if (errorStatus == XpmSuccess)
708 return TRUE; /* no error */
709 else
710 return FALSE;
711 } else return FALSE;
712 } else return FALSE;
713#else
714 return FALSE;
715#endif
716}
717
718class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
719{
720 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
721public:
722 inline wxXPMDataHandler(void)
723 {
724 m_name = "XPM bitmap data";
725 m_extension = "xpm";
726 m_type = wxBITMAP_TYPE_XPM_DATA;
727 };
728
729 virtual bool Create(wxBitmap *bitmap, void *data, const long flags, const int width, const int height, const int depth = 1);
730};
731IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
732
733bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, const long flags, const int width, const int height, const int depth)
734{
735#if USE_XPM_IN_MSW
736 XImage *ximage;
737 int ErrorStatus;
738 XpmAttributes xpmAttr;
739 HDC dc;
740
741 M_BITMAPHANDLERDATA->m_ok = FALSE;
742 M_BITMAPHANDLERDATA->m_numColors = 0;
743
744 dc = CreateCompatibleDC(NULL); /* memory DC */
745
746 if (dc)
747 {
748 xpmAttr.valuemask = XpmReturnInfos; /* get infos back */
749 ErrorStatus = XpmCreateImageFromData(&dc, (char **)data,
750 &ximage, (XImage **) NULL, &xpmAttr);
751
752 if (ErrorStatus == XpmSuccess)
753 {
754 /* ximage is malloced and contains bitmap and attributes */
755 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
756
757 BITMAP bm;
758 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
759
760 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
761 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
762 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
763 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
764 XpmFreeAttributes(&xpmAttr);
765
766 XImageFree(ximage); // releases the malloc, but does not detroy
767 // the bitmap
768 M_BITMAPHANDLERDATA->m_ok = TRUE;
769 DeleteDC(dc);
770
771 } else
772 {
773 M_BITMAPHANDLERDATA->m_ok = FALSE;
774// XpmDebugError(ErrorStatus, NULL);
775 DeleteDC(dc);
776 return FALSE;
777 }
778 }
779#else
780 return FALSE;
781#endif
782}
783
784void wxBitmap::CleanUpHandlers(void)
785{
786 wxNode *node = sm_handlers.First();
787 while ( node )
788 {
789 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
790 wxNode *next = node->Next();
791 delete handler;
792 delete node;
793 node = next;
794 }
795}
796
797void wxBitmap::InitStandardHandlers(void)
798{
799 AddHandler(new wxBMPResourceHandler);
800 AddHandler(new wxBMPFileHandler);
801 AddHandler(new wxXPMFileHandler);
802 AddHandler(new wxXPMDataHandler);
803 AddHandler(new wxICOResourceHandler);
804 AddHandler(new wxICOFileHandler);
805}
806
807
808