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