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