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