]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bitmap.cpp
Minor doc tweaks plus major wxTreeCtrl bug fixed (double deletion of tree items
[wxWidgets.git] / src / msw / bitmap.cpp
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/dcmemory.h"
31 #include "wx/bitmap.h"
32 #include "wx/icon.h"
33 #endif
34
35 #include "wx/msw/private.h"
36 #include "wx/log.h"
37
38 #include "assert.h"
39
40 #include "wx/msw/dib.h"
41
42 #if !USE_SHARED_LIBRARIES
43 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
44 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
45 #endif
46
47 wxBitmapRefData::wxBitmapRefData(void)
48 {
49 m_ok = FALSE;
50 m_width = 0;
51 m_height = 0;
52 m_depth = 0;
53 m_quality = 0;
54 m_hBitmap = 0 ;
55 m_selectedInto = NULL;
56 m_numColors = 0;
57 m_bitmapMask = NULL;
58 }
59
60 wxBitmapRefData::~wxBitmapRefData(void)
61 {
62 if (m_selectedInto)
63 {
64 char buf[200];
65 sprintf(buf, "Bitmap was deleted without selecting out of wxMemoryDC %X.", (unsigned int) m_selectedInto);
66 wxFatalError(buf);
67 }
68 if (m_hBitmap)
69 {
70 DeleteObject((HBITMAP) m_hBitmap);
71 }
72 m_hBitmap = 0 ;
73
74 if (m_bitmapMask)
75 delete m_bitmapMask;
76 m_bitmapMask = NULL;
77
78 }
79
80 wxList wxBitmap::sm_handlers;
81
82 wxBitmap::wxBitmap(void)
83 {
84 if ( wxTheBitmapList )
85 wxTheBitmapList->AddBitmap(this);
86 }
87
88 wxBitmap::~wxBitmap(void)
89 {
90 if (wxTheBitmapList)
91 wxTheBitmapList->DeleteObject(this);
92 }
93
94 bool wxBitmap::FreeResource(bool WXUNUSED(force))
95 {
96 if ( !M_BITMAPDATA )
97 return FALSE;
98
99 if (M_BITMAPDATA->m_selectedInto)
100 {
101 char buf[200];
102 sprintf(buf, "Bitmap %X was deleted without selecting out of wxMemoryDC %X.", (unsigned int) this, (unsigned int) M_BITMAPDATA->m_selectedInto);
103 wxFatalError(buf);
104 }
105 if (M_BITMAPDATA->m_hBitmap)
106 {
107 DeleteObject((HBITMAP) M_BITMAPDATA->m_hBitmap);
108 }
109 M_BITMAPDATA->m_hBitmap = 0 ;
110
111 /*
112 if (M_BITMAPDATA->m_bitmapPalette)
113 delete M_BITMAPDATA->m_bitmapPalette;
114
115 M_BITMAPDATA->m_bitmapPalette = NULL ;
116 */
117
118 return TRUE;
119 }
120
121
122 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
123 {
124 m_refData = new wxBitmapRefData;
125
126 M_BITMAPDATA->m_width = the_width ;
127 M_BITMAPDATA->m_height = the_height ;
128 M_BITMAPDATA->m_depth = no_bits ;
129 M_BITMAPDATA->m_numColors = 0;
130
131 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, 1, no_bits, bits);
132
133 if (M_BITMAPDATA->m_hBitmap)
134 M_BITMAPDATA->m_ok = TRUE;
135 else
136 M_BITMAPDATA->m_ok = FALSE;
137
138 M_BITMAPDATA->m_selectedInto = NULL;
139
140 if ( wxTheBitmapList )
141 wxTheBitmapList->AddBitmap(this);
142 }
143
144 // Create from XPM data
145 wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
146 {
147 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
148 }
149
150 wxBitmap::wxBitmap(int w, int h, int d)
151 {
152 (void)Create(w, h, d);
153
154 if ( wxTheBitmapList )
155 wxTheBitmapList->AddBitmap(this);
156 }
157
158 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
159 {
160 (void) Create(data, type, width, height, depth);
161
162 if ( wxTheBitmapList )
163 wxTheBitmapList->AddBitmap(this);
164 }
165
166 wxBitmap::wxBitmap(const wxString& filename, long type)
167 {
168 LoadFile(filename, (int)type);
169
170 if ( wxTheBitmapList )
171 wxTheBitmapList->AddBitmap(this);
172 }
173
174 bool wxBitmap::Create(int w, int h, int d)
175 {
176 UnRef();
177
178 m_refData = new wxBitmapRefData;
179
180 M_BITMAPDATA->m_width = w;
181 M_BITMAPDATA->m_height = h;
182 M_BITMAPDATA->m_depth = d;
183
184 if (d > 0)
185 {
186 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, 1, d, NULL);
187 }
188 else
189 {
190 HDC dc = GetDC((HWND) NULL);
191 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
192 ReleaseDC((HWND) NULL, dc);
193 M_BITMAPDATA->m_depth = wxDisplayDepth();
194 }
195 if (M_BITMAPDATA->m_hBitmap)
196 M_BITMAPDATA->m_ok = TRUE;
197 else
198 M_BITMAPDATA->m_ok = FALSE;
199 return M_BITMAPDATA->m_ok;
200 }
201
202 bool wxBitmap::LoadFile(const wxString& filename, long type)
203 {
204 UnRef();
205
206 m_refData = new wxBitmapRefData;
207
208 wxBitmapHandler *handler = FindHandler(type);
209
210 if ( handler == NULL ) {
211 wxLogWarning("no bitmap handler for type %d defined.", type);
212
213 return FALSE;
214 }
215
216 return handler->LoadFile(this, filename, type, -1, -1);
217 }
218
219 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
220 {
221 UnRef();
222
223 m_refData = new wxBitmapRefData;
224
225 wxBitmapHandler *handler = FindHandler(type);
226
227 if ( handler == NULL ) {
228 wxLogWarning("no bitmap handler for type %d defined.", type);
229
230 return FALSE;
231 }
232
233 return handler->Create(this, data, type, width, height, depth);
234 }
235
236 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
237 {
238 wxBitmapHandler *handler = FindHandler(type);
239
240 if ( handler == NULL ) {
241 wxLogWarning("no bitmap handler for type %d defined.", type);
242
243 return FALSE;
244 }
245
246 return handler->SaveFile(this, filename, type, palette);
247 }
248
249 void wxBitmap::SetWidth(int w)
250 {
251 if (!M_BITMAPDATA)
252 m_refData = new wxBitmapRefData;
253
254 M_BITMAPDATA->m_width = w;
255 }
256
257 void wxBitmap::SetHeight(int h)
258 {
259 if (!M_BITMAPDATA)
260 m_refData = new wxBitmapRefData;
261
262 M_BITMAPDATA->m_height = h;
263 }
264
265 void wxBitmap::SetDepth(int d)
266 {
267 if (!M_BITMAPDATA)
268 m_refData = new wxBitmapRefData;
269
270 M_BITMAPDATA->m_depth = d;
271 }
272
273 void wxBitmap::SetQuality(int q)
274 {
275 if (!M_BITMAPDATA)
276 m_refData = new wxBitmapRefData;
277
278 M_BITMAPDATA->m_quality = q;
279 }
280
281 void wxBitmap::SetOk(bool isOk)
282 {
283 if (!M_BITMAPDATA)
284 m_refData = new wxBitmapRefData;
285
286 M_BITMAPDATA->m_ok = isOk;
287 }
288
289 void wxBitmap::SetPalette(const wxPalette& palette)
290 {
291 if (!M_BITMAPDATA)
292 m_refData = new wxBitmapRefData;
293
294 M_BITMAPDATA->m_bitmapPalette = palette ;
295 }
296
297 void wxBitmap::SetMask(wxMask *mask)
298 {
299 if (!M_BITMAPDATA)
300 m_refData = new wxBitmapRefData;
301
302 M_BITMAPDATA->m_bitmapMask = mask ;
303 }
304
305 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
306 {
307 if (!M_BITMAPDATA)
308 m_refData = new wxBitmapRefData;
309
310 M_BITMAPDATA->m_hBitmap = bmp;
311 }
312
313 void wxBitmap::AddHandler(wxBitmapHandler *handler)
314 {
315 sm_handlers.Append(handler);
316 }
317
318 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
319 {
320 sm_handlers.Insert(handler);
321 }
322
323 bool wxBitmap::RemoveHandler(const wxString& name)
324 {
325 wxBitmapHandler *handler = FindHandler(name);
326 if ( handler )
327 {
328 sm_handlers.DeleteObject(handler);
329 return TRUE;
330 }
331 else
332 return FALSE;
333 }
334
335 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
336 {
337 wxNode *node = sm_handlers.First();
338 while ( node )
339 {
340 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
341 if ( (handler->GetName().Cmp(name) == 0) )
342 return handler;
343 node = node->Next();
344 }
345 return NULL;
346 }
347
348 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
349 {
350 wxNode *node = sm_handlers.First();
351 while ( node )
352 {
353 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
354 if ( (handler->GetExtension().Cmp(extension) == 0) &&
355 (bitmapType == -1 || (handler->GetType() == bitmapType)) )
356 return handler;
357 node = node->Next();
358 }
359 return NULL;
360 }
361
362 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
363 {
364 wxNode *node = sm_handlers.First();
365 while ( node )
366 {
367 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
368 if (handler->GetType() == bitmapType)
369 return handler;
370 node = node->Next();
371 }
372 return NULL;
373 }
374
375 // New Create/FreeDIB functions since ones in dibutils.cpp are confusing
376 static long createDIB(long xSize, long ySize, long bitsPerPixel,
377 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
378 static long freeDIB(LPBITMAPINFO lpDIBHeader);
379
380 // Creates a bitmap that matches the device context, from
381 // an arbitray bitmap. At present, the original bitmap must have an
382 // associated palette. TODO: use a default palette if no palette exists.
383 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
384 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
385 {
386 wxMemoryDC memDC;
387 wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
388 HPALETTE hPal = (HPALETTE) NULL;
389 LPBITMAPINFO lpDib;
390 void *lpBits = (void*) NULL;
391
392 /*
393 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
394
395 tmpBitmap.SetPalette(this->GetPalette());
396 memDC.SelectObject(tmpBitmap);
397 memDC.SetPalette(this->GetPalette());
398
399 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
400 */
401 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
402 {
403 tmpBitmap.SetPalette(* this->GetPalette());
404 memDC.SelectObject(tmpBitmap);
405 memDC.SetPalette(* this->GetPalette());
406 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
407 }
408 else
409 {
410 hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);
411 wxPalette palette;
412 palette.SetHPALETTE( (WXHPALETTE)hPal );
413 tmpBitmap.SetPalette( palette );
414 memDC.SelectObject(tmpBitmap);
415 memDC.SetPalette( palette );
416 }
417
418 // set the height negative because in a DIB the order of the lines is reversed
419 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib);
420
421 lpBits = malloc(lpDib->bmiHeader.biSizeImage);
422
423 ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits);
424
425 ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
426 0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS);
427
428 free(lpBits);
429
430 freeDIB(lpDib);
431 return (tmpBitmap);
432 }
433
434 /*
435 * wxMask
436 */
437
438 wxMask::wxMask(void)
439 {
440 m_maskBitmap = 0;
441 }
442
443 // Construct a mask from a bitmap and a colour indicating
444 // the transparent area
445 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
446 {
447 m_maskBitmap = 0;
448 Create(bitmap, colour);
449 }
450
451 // Construct a mask from a bitmap and a palette index indicating
452 // the transparent area
453 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
454 {
455 m_maskBitmap = 0;
456 Create(bitmap, paletteIndex);
457 }
458
459 // Construct a mask from a mono bitmap (copies the bitmap).
460 wxMask::wxMask(const wxBitmap& bitmap)
461 {
462 m_maskBitmap = 0;
463 Create(bitmap);
464 }
465
466 wxMask::~wxMask(void)
467 {
468 if ( m_maskBitmap )
469 ::DeleteObject((HBITMAP) m_maskBitmap);
470 }
471
472 // Create a mask from a mono bitmap (copies the bitmap).
473 bool wxMask::Create(const wxBitmap& bitmap)
474 {
475 if ( m_maskBitmap )
476 {
477 ::DeleteObject((HBITMAP) m_maskBitmap);
478 m_maskBitmap = 0;
479 }
480 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
481 {
482 return FALSE;
483 }
484 m_maskBitmap = (WXHBITMAP) CreateBitmap(
485 bitmap.GetWidth(),
486 bitmap.GetHeight(),
487 1, 1, 0
488 );
489 HDC srcDC = CreateCompatibleDC(0);
490 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
491 HDC destDC = CreateCompatibleDC(0);
492 SelectObject(destDC, (HBITMAP) m_maskBitmap);
493 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
494 SelectObject(srcDC, 0);
495 DeleteDC(srcDC);
496 SelectObject(destDC, 0);
497 DeleteDC(destDC);
498 return TRUE;
499 }
500
501 // Create a mask from a bitmap and a palette index indicating
502 // the transparent area
503 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
504 {
505 if ( m_maskBitmap )
506 {
507 ::DeleteObject((HBITMAP) m_maskBitmap);
508 m_maskBitmap = 0;
509 }
510 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
511 {
512 unsigned char red, green, blue;
513 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
514 {
515 wxColour transparentColour(red, green, blue);
516 return Create(bitmap, transparentColour);
517 }
518 }
519 return FALSE;
520 }
521
522 // Create a mask from a bitmap and a colour indicating
523 // the transparent area
524 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
525 {
526 if ( m_maskBitmap )
527 {
528 ::DeleteObject((HBITMAP) m_maskBitmap);
529 m_maskBitmap = 0;
530 }
531 if (!bitmap.Ok())
532 {
533 return FALSE;
534 }
535
536 // scan the bitmap for the transparent colour and set
537 // the corresponding pixels in the mask to BLACK and
538 // the rest to WHITE
539 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
540 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
541 bitmap.GetWidth(),
542 bitmap.GetHeight(),
543 1, 1, 0
544 );
545 HDC srcDC = ::CreateCompatibleDC(0);
546 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
547 HDC destDC = ::CreateCompatibleDC(0);
548 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
549
550 // this is not very efficient, but I can't think
551 // of a better way of doing it
552 for (int w = 0; w < bitmap.GetWidth(); w++)
553 {
554 for (int h = 0; h < bitmap.GetHeight(); h++)
555 {
556 COLORREF col = GetPixel(srcDC, w, h);
557 if (col == maskColour)
558 {
559 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
560 }
561 else
562 {
563 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
564 }
565 }
566 }
567 ::SelectObject(srcDC, 0);
568 ::DeleteDC(srcDC);
569 ::SelectObject(destDC, 0);
570 ::DeleteDC(destDC);
571 return TRUE;
572 }
573
574 /*
575 * wxBitmapHandler
576 */
577
578 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
579
580 bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
581 {
582 return FALSE;
583 }
584
585 bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
586 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
587 {
588 return FALSE;
589 }
590
591 bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette))
592 {
593 return FALSE;
594 }
595
596 /*
597 * Standard handlers
598 */
599
600 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
601 {
602 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
603 public:
604 inline wxBMPResourceHandler(void)
605 {
606 m_name = "Windows bitmap resource";
607 m_extension = "";
608 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
609 };
610
611 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
612 int desiredWidth, int desiredHeight);
613 };
614 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
615
616 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
617 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
618 {
619 // TODO: load colourmap.
620 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
621 if (M_BITMAPHANDLERDATA->m_hBitmap)
622 {
623 M_BITMAPHANDLERDATA->m_ok = TRUE;
624 BITMAP bm;
625 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
626 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
627 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
628 M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
629
630 if ( bitmap->IsKindOf(CLASSINFO(wxIcon)) )
631 {
632 }
633
634 return TRUE;
635 }
636
637 // it's probably not found
638 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
639
640 return FALSE;
641 }
642
643 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
644 {
645 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
646 public:
647 inline wxBMPFileHandler(void)
648 {
649 m_name = "Windows bitmap file";
650 m_extension = "bmp";
651 m_type = wxBITMAP_TYPE_BMP;
652 };
653
654 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
655 int desiredWidth, int desiredHeight);
656 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
657 };
658 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
659
660 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
661 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
662 {
663 #if wxUSE_IMAGE_LOADING_IN_MSW
664 wxPalette *palette = NULL;
665 bool success = FALSE;
666 /*
667 if (type & wxBITMAP_DISCARD_COLOURMAP)
668 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
669 else
670 */
671 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
672 if (!success && palette)
673 {
674 delete palette;
675 palette = NULL;
676 }
677 if (palette)
678 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
679 return success;
680 #else
681 return FALSE;
682 #endif
683 }
684
685 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal)
686 {
687 #if wxUSE_IMAGE_LOADING_IN_MSW
688 wxPalette *actualPalette = (wxPalette *)pal;
689 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
690 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
691 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
692 #else
693 return FALSE;
694 #endif
695 }
696
697 void wxBitmap::CleanUpHandlers(void)
698 {
699 wxNode *node = sm_handlers.First();
700 while ( node )
701 {
702 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
703 wxNode *next = node->Next();
704 delete handler;
705 delete node;
706 node = next;
707 }
708 }
709
710 void wxBitmap::InitStandardHandlers(void)
711 {
712 AddHandler(new wxBMPResourceHandler);
713 AddHandler(new wxBMPFileHandler);
714
715 // Not added by default: include xpmhand.h in your app
716 // and call these in your wxApp::OnInit.
717 // AddHandler(new wxXPMFileHandler);
718 // AddHandler(new wxXPMDataHandler);
719
720 AddHandler(new wxICOResourceHandler);
721 AddHandler(new wxICOFileHandler);
722 }
723
724 static long createDIB(long xSize, long ySize, long bitsPerPixel,
725 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader)
726 {
727 unsigned long i, headerSize;
728 LPBITMAPINFO lpDIBheader = NULL;
729 LPPALETTEENTRY lpPe = NULL;
730
731
732 // Allocate space for a DIB header
733 headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY)));
734 lpDIBheader = (BITMAPINFO *) malloc(headerSize);
735 lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER));
736
737 GetPaletteEntries(hPal, 0, 256, lpPe);
738
739
740 memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER));
741
742
743 // Fill in the static parts of the DIB header
744 lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
745 lpDIBheader->bmiHeader.biWidth = xSize;
746 lpDIBheader->bmiHeader.biHeight = ySize;
747 lpDIBheader->bmiHeader.biPlanes = 1;
748
749 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
750 lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel);
751 lpDIBheader->bmiHeader.biCompression = BI_RGB;
752 lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >>
753 3;
754 lpDIBheader->bmiHeader.biClrUsed = 256;
755
756
757 // Initialize the DIB palette
758 for (i = 0; i < 256; i++) {
759 lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags;
760 lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed;
761 lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen;
762 lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue;
763 }
764
765 *lpDIBHeader = lpDIBheader;
766
767
768 return (0);
769
770 }
771
772
773
774 static long freeDIB(LPBITMAPINFO lpDIBHeader)
775 {
776
777 if (lpDIBHeader != NULL) {
778 free(lpDIBHeader);
779 }
780
781 return (0);
782 }
783
784