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