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