]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bitmap.cpp
added © -> (c) conversion in html docs
[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 0
282 if ( handler == NULL )
283 return FALSE;
284 #else
285 if ( handler == NULL ) {
286 wxImage image;
287 if (!image.LoadFile( filename, type )) return FALSE;
288 if (image.Ok())
289 {
290 *this = image.ConvertToBitmap();
291 return TRUE;
292 }
293 else return FALSE;
294 }
295 #endif
296 return handler->LoadFile(this, filename, type, -1, -1);
297 }
298
299 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
300 {
301 UnRef();
302
303 m_refData = new wxBitmapRefData;
304
305 wxBitmapHandler *handler = FindHandler(type);
306
307 if ( handler == NULL ) {
308 wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
309
310 return FALSE;
311 }
312
313 return handler->Create(this, data, type, width, height, depth);
314 }
315
316 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
317 {
318 wxBitmapHandler *handler = FindHandler(type);
319
320 #if 0
321 if ( handler == NULL )
322 return FALSE;
323 #else
324 if ( handler == NULL ) { // try wxImage
325 wxImage image( *this );
326 if (image.Ok()) return image.SaveFile( filename, type );
327 else return FALSE;
328 }
329 #endif
330
331 return handler->SaveFile(this, filename, type, palette);
332 }
333
334 void wxBitmap::SetWidth(int w)
335 {
336 if (!M_BITMAPDATA)
337 m_refData = new wxBitmapRefData;
338
339 M_BITMAPDATA->m_width = w;
340 }
341
342 void wxBitmap::SetHeight(int h)
343 {
344 if (!M_BITMAPDATA)
345 m_refData = new wxBitmapRefData;
346
347 M_BITMAPDATA->m_height = h;
348 }
349
350 void wxBitmap::SetDepth(int d)
351 {
352 if (!M_BITMAPDATA)
353 m_refData = new wxBitmapRefData;
354
355 M_BITMAPDATA->m_depth = d;
356 }
357
358 void wxBitmap::SetQuality(int q)
359 {
360 if (!M_BITMAPDATA)
361 m_refData = new wxBitmapRefData;
362
363 M_BITMAPDATA->m_quality = q;
364 }
365
366 void wxBitmap::SetOk(bool isOk)
367 {
368 if (!M_BITMAPDATA)
369 m_refData = new wxBitmapRefData;
370
371 M_BITMAPDATA->m_ok = isOk;
372 }
373
374 void wxBitmap::SetPalette(const wxPalette& palette)
375 {
376 if (!M_BITMAPDATA)
377 m_refData = new wxBitmapRefData;
378
379 M_BITMAPDATA->m_bitmapPalette = palette ;
380 }
381
382 void wxBitmap::SetMask(wxMask *mask)
383 {
384 if (!M_BITMAPDATA)
385 m_refData = new wxBitmapRefData;
386
387 M_BITMAPDATA->m_bitmapMask = mask ;
388 }
389
390 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
391 {
392 if (!M_BITMAPDATA)
393 m_refData = new wxBitmapRefData;
394
395 M_BITMAPDATA->m_hBitmap = bmp;
396 M_BITMAPDATA->m_ok = bmp != 0;
397 }
398
399 void wxBitmap::AddHandler(wxBitmapHandler *handler)
400 {
401 sm_handlers.Append(handler);
402 }
403
404 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
405 {
406 sm_handlers.Insert(handler);
407 }
408
409 bool wxBitmap::RemoveHandler(const wxString& name)
410 {
411 wxBitmapHandler *handler = FindHandler(name);
412 if ( handler )
413 {
414 sm_handlers.DeleteObject(handler);
415 return TRUE;
416 }
417 else
418 return FALSE;
419 }
420
421 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
422 {
423 wxNode *node = sm_handlers.First();
424 while ( node )
425 {
426 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
427 if ( (handler->GetName().Cmp(name) == 0) )
428 return handler;
429 node = node->Next();
430 }
431 return NULL;
432 }
433
434 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
435 {
436 wxNode *node = sm_handlers.First();
437 while ( node )
438 {
439 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
440 if ( (handler->GetExtension().Cmp(extension) == 0) &&
441 (bitmapType == -1 || (handler->GetType() == bitmapType)) )
442 return handler;
443 node = node->Next();
444 }
445 return NULL;
446 }
447
448 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
449 {
450 wxNode *node = sm_handlers.First();
451 while ( node )
452 {
453 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
454 if (handler->GetType() == bitmapType)
455 return handler;
456 node = node->Next();
457 }
458 return NULL;
459 }
460
461 // New Create/FreeDIB functions since ones in dibutils.cpp are confusing
462 static long createDIB(long xSize, long ySize, long bitsPerPixel,
463 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
464 static long freeDIB(LPBITMAPINFO lpDIBHeader);
465
466 // Creates a bitmap that matches the device context, from
467 // an arbitray bitmap. At present, the original bitmap must have an
468 // associated palette. TODO: use a default palette if no palette exists.
469 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
470 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
471 {
472 wxMemoryDC memDC;
473 wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
474 HPALETTE hPal = (HPALETTE) NULL;
475 LPBITMAPINFO lpDib;
476 void *lpBits = (void*) NULL;
477
478 /*
479 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
480
481 tmpBitmap.SetPalette(this->GetPalette());
482 memDC.SelectObject(tmpBitmap);
483 memDC.SetPalette(this->GetPalette());
484
485 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
486 */
487 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
488 {
489 tmpBitmap.SetPalette(* this->GetPalette());
490 memDC.SelectObject(tmpBitmap);
491 memDC.SetPalette(* this->GetPalette());
492 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
493 }
494 else
495 {
496 hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);
497 wxPalette palette;
498 palette.SetHPALETTE( (WXHPALETTE)hPal );
499 tmpBitmap.SetPalette( palette );
500 memDC.SelectObject(tmpBitmap);
501 memDC.SetPalette( palette );
502 }
503
504 // set the height negative because in a DIB the order of the lines is reversed
505 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib);
506
507 lpBits = malloc(lpDib->bmiHeader.biSizeImage);
508
509 ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits);
510
511 ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
512 0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS);
513
514 free(lpBits);
515
516 freeDIB(lpDib);
517 return (tmpBitmap);
518 }
519
520 /*
521 * wxMask
522 */
523
524 wxMask::wxMask()
525 {
526 m_maskBitmap = 0;
527 }
528
529 // Construct a mask from a bitmap and a colour indicating
530 // the transparent area
531 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
532 {
533 m_maskBitmap = 0;
534 Create(bitmap, colour);
535 }
536
537 // Construct a mask from a bitmap and a palette index indicating
538 // the transparent area
539 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
540 {
541 m_maskBitmap = 0;
542 Create(bitmap, paletteIndex);
543 }
544
545 // Construct a mask from a mono bitmap (copies the bitmap).
546 wxMask::wxMask(const wxBitmap& bitmap)
547 {
548 m_maskBitmap = 0;
549 Create(bitmap);
550 }
551
552 wxMask::~wxMask()
553 {
554 if ( m_maskBitmap )
555 ::DeleteObject((HBITMAP) m_maskBitmap);
556 }
557
558 // Create a mask from a mono bitmap (copies the bitmap).
559 bool wxMask::Create(const wxBitmap& bitmap)
560 {
561 if ( m_maskBitmap )
562 {
563 ::DeleteObject((HBITMAP) m_maskBitmap);
564 m_maskBitmap = 0;
565 }
566 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
567 {
568 return FALSE;
569 }
570 m_maskBitmap = (WXHBITMAP) CreateBitmap(
571 bitmap.GetWidth(),
572 bitmap.GetHeight(),
573 1, 1, 0
574 );
575 HDC srcDC = CreateCompatibleDC(0);
576 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
577 HDC destDC = CreateCompatibleDC(0);
578 SelectObject(destDC, (HBITMAP) m_maskBitmap);
579 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
580 SelectObject(srcDC, 0);
581 DeleteDC(srcDC);
582 SelectObject(destDC, 0);
583 DeleteDC(destDC);
584 return TRUE;
585 }
586
587 // Create a mask from a bitmap and a palette index indicating
588 // the transparent area
589 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
590 {
591 if ( m_maskBitmap )
592 {
593 ::DeleteObject((HBITMAP) m_maskBitmap);
594 m_maskBitmap = 0;
595 }
596 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
597 {
598 unsigned char red, green, blue;
599 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
600 {
601 wxColour transparentColour(red, green, blue);
602 return Create(bitmap, transparentColour);
603 }
604 }
605 return FALSE;
606 }
607
608 // Create a mask from a bitmap and a colour indicating
609 // the transparent area
610 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
611 {
612 if ( m_maskBitmap )
613 {
614 ::DeleteObject((HBITMAP) m_maskBitmap);
615 m_maskBitmap = 0;
616 }
617 if (!bitmap.Ok())
618 {
619 return FALSE;
620 }
621
622 // scan the bitmap for the transparent colour and set
623 // the corresponding pixels in the mask to BLACK and
624 // the rest to WHITE
625 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
626 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
627 bitmap.GetWidth(),
628 bitmap.GetHeight(),
629 1, 1, 0
630 );
631 HDC srcDC = ::CreateCompatibleDC(0);
632 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
633 HDC destDC = ::CreateCompatibleDC(0);
634 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
635
636 // this is not very efficient, but I can't think
637 // of a better way of doing it
638 for (int w = 0; w < bitmap.GetWidth(); w++)
639 {
640 for (int h = 0; h < bitmap.GetHeight(); h++)
641 {
642 COLORREF col = GetPixel(srcDC, w, h);
643 if (col == maskColour)
644 {
645 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
646 }
647 else
648 {
649 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
650 }
651 }
652 }
653 ::SelectObject(srcDC, 0);
654 ::DeleteDC(srcDC);
655 ::SelectObject(destDC, 0);
656 ::DeleteDC(destDC);
657 return TRUE;
658 }
659
660 /*
661 * wxBitmapHandler
662 */
663
664 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
665
666 bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
667 {
668 return FALSE;
669 }
670
671 bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
672 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
673 {
674 return FALSE;
675 }
676
677 bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette))
678 {
679 return FALSE;
680 }
681
682 /*
683 * Standard handlers
684 */
685
686 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
687 {
688 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
689 public:
690 inline wxBMPResourceHandler()
691 {
692 m_name = "Windows bitmap resource";
693 m_extension = "";
694 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
695 };
696
697 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
698 int desiredWidth, int desiredHeight);
699 };
700 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
701
702 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
703 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
704 {
705 // TODO: load colourmap.
706 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
707 if (M_BITMAPHANDLERDATA->m_hBitmap)
708 {
709 M_BITMAPHANDLERDATA->m_ok = TRUE;
710 BITMAP bm;
711 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
712 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
713 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
714 M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
715
716 if ( bitmap->IsKindOf(CLASSINFO(wxIcon)) )
717 {
718 }
719
720 return TRUE;
721 }
722
723 // it's probably not found
724 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str());
725
726 return FALSE;
727 }
728
729 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
730 {
731 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
732 public:
733 inline wxBMPFileHandler()
734 {
735 m_name = "Windows bitmap file";
736 m_extension = "bmp";
737 m_type = wxBITMAP_TYPE_BMP;
738 };
739
740 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
741 int desiredWidth, int desiredHeight);
742 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
743 };
744 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
745
746 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
747 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
748 {
749 #if wxUSE_IMAGE_LOADING_IN_MSW
750 wxPalette *palette = NULL;
751 bool success = FALSE;
752 /*
753 if (type & wxBITMAP_DISCARD_COLOURMAP)
754 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
755 else
756 */
757 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
758 if (!success && palette)
759 {
760 delete palette;
761 palette = NULL;
762 }
763 if (palette)
764 {
765 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
766 delete palette;
767 }
768 return success;
769 #else
770 return FALSE;
771 #endif
772 }
773
774 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal)
775 {
776 #if wxUSE_IMAGE_LOADING_IN_MSW
777 wxPalette *actualPalette = (wxPalette *)pal;
778 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
779 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
780 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
781 #else
782 return FALSE;
783 #endif
784 }
785
786 void wxBitmap::CleanUpHandlers()
787 {
788 wxNode *node = sm_handlers.First();
789 while ( node )
790 {
791 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
792 wxNode *next = node->Next();
793 delete handler;
794 delete node;
795 node = next;
796 }
797 }
798
799 void wxBitmap::InitStandardHandlers()
800 {
801 AddHandler(new wxBMPResourceHandler);
802 AddHandler(new wxBMPFileHandler);
803
804 // Not added by default: include xpmhand.h in your app
805 // and call these in your wxApp::OnInit.
806 // AddHandler(new wxXPMFileHandler);
807 // AddHandler(new wxXPMDataHandler);
808
809 AddHandler(new wxICOResourceHandler);
810 AddHandler(new wxICOFileHandler);
811 }
812
813 static long createDIB(long xSize, long ySize, long bitsPerPixel,
814 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader)
815 {
816 unsigned long i, headerSize;
817 LPBITMAPINFO lpDIBheader = NULL;
818 LPPALETTEENTRY lpPe = NULL;
819
820
821 // Allocate space for a DIB header
822 headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY)));
823 lpDIBheader = (BITMAPINFO *) malloc(headerSize);
824 lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER));
825
826 GetPaletteEntries(hPal, 0, 256, lpPe);
827
828
829 memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER));
830
831
832 // Fill in the static parts of the DIB header
833 lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
834 lpDIBheader->bmiHeader.biWidth = xSize;
835 lpDIBheader->bmiHeader.biHeight = ySize;
836 lpDIBheader->bmiHeader.biPlanes = 1;
837
838 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
839 lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel);
840 lpDIBheader->bmiHeader.biCompression = BI_RGB;
841 lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >>
842 3;
843 lpDIBheader->bmiHeader.biClrUsed = 256;
844
845
846 // Initialize the DIB palette
847 for (i = 0; i < 256; i++) {
848 lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags;
849 lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed;
850 lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen;
851 lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue;
852 }
853
854 *lpDIBHeader = lpDIBheader;
855
856
857 return (0);
858
859 }
860
861
862
863 static long freeDIB(LPBITMAPINFO lpDIBHeader)
864 {
865
866 if (lpDIBHeader != NULL) {
867 free(lpDIBHeader);
868 }
869
870 return (0);
871 }
872
873