]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/bitmap.cpp
now we initialize wxListEvent correctly
[wxWidgets.git] / src / msw / bitmap.cpp
... / ...
CommitLineData
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
65wxBitmapRefData::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
78wxBitmapRefData::~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
102wxList wxBitmap::sm_handlers;
103
104wxBitmap::wxBitmap()
105{
106 if ( wxTheBitmapList )
107 wxTheBitmapList->AddBitmap(this);
108}
109
110wxBitmap::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
135wxBitmap::~wxBitmap()
136{
137 if (wxTheBitmapList)
138 wxTheBitmapList->DeleteObject(this);
139}
140
141bool 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
169wxBitmap::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
192wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
193{
194 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
195}
196
197wxBitmap::wxBitmap(int w, int h, int d)
198{
199 (void)Create(w, h, d);
200
201 if ( wxTheBitmapList )
202 wxTheBitmapList->AddBitmap(this);
203}
204
205wxBitmap::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
213wxBitmap::wxBitmap(const wxString& filename, long type)
214{
215 LoadFile(filename, (int)type);
216
217 if ( wxTheBitmapList )
218 wxTheBitmapList->AddBitmap(this);
219}
220
221bool 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
249bool 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
266bool 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
283bool 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
296void wxBitmap::SetWidth(int w)
297{
298 if (!M_BITMAPDATA)
299 m_refData = new wxBitmapRefData;
300
301 M_BITMAPDATA->m_width = w;
302}
303
304void wxBitmap::SetHeight(int h)
305{
306 if (!M_BITMAPDATA)
307 m_refData = new wxBitmapRefData;
308
309 M_BITMAPDATA->m_height = h;
310}
311
312void wxBitmap::SetDepth(int d)
313{
314 if (!M_BITMAPDATA)
315 m_refData = new wxBitmapRefData;
316
317 M_BITMAPDATA->m_depth = d;
318}
319
320void wxBitmap::SetQuality(int q)
321{
322 if (!M_BITMAPDATA)
323 m_refData = new wxBitmapRefData;
324
325 M_BITMAPDATA->m_quality = q;
326}
327
328void wxBitmap::SetOk(bool isOk)
329{
330 if (!M_BITMAPDATA)
331 m_refData = new wxBitmapRefData;
332
333 M_BITMAPDATA->m_ok = isOk;
334}
335
336void wxBitmap::SetPalette(const wxPalette& palette)
337{
338 if (!M_BITMAPDATA)
339 m_refData = new wxBitmapRefData;
340
341 M_BITMAPDATA->m_bitmapPalette = palette ;
342}
343
344void wxBitmap::SetMask(wxMask *mask)
345{
346 if (!M_BITMAPDATA)
347 m_refData = new wxBitmapRefData;
348
349 M_BITMAPDATA->m_bitmapMask = mask ;
350}
351
352void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
353{
354 if (!M_BITMAPDATA)
355 m_refData = new wxBitmapRefData;
356
357 M_BITMAPDATA->m_hBitmap = bmp;
358}
359
360void wxBitmap::AddHandler(wxBitmapHandler *handler)
361{
362 sm_handlers.Append(handler);
363}
364
365void wxBitmap::InsertHandler(wxBitmapHandler *handler)
366{
367 sm_handlers.Insert(handler);
368}
369
370bool 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
382wxBitmapHandler *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
395wxBitmapHandler *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
409wxBitmapHandler *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
423static long createDIB(long xSize, long ySize, long bitsPerPixel,
424 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
425static 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>
431wxBitmap 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
485wxMask::wxMask()
486{
487 m_maskBitmap = 0;
488}
489
490// Construct a mask from a bitmap and a colour indicating
491// the transparent area
492wxMask::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
500wxMask::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).
507wxMask::wxMask(const wxBitmap& bitmap)
508{
509 m_maskBitmap = 0;
510 Create(bitmap);
511}
512
513wxMask::~wxMask()
514{
515 if ( m_maskBitmap )
516 ::DeleteObject((HBITMAP) m_maskBitmap);
517}
518
519// Create a mask from a mono bitmap (copies the bitmap).
520bool 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
550bool 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
571bool 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
625IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
626
627bool 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
632bool 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
638bool 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
647class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
648{
649 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
650public:
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};
661IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
662
663bool 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
690class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
691{
692 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
693public:
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};
705IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
706
707bool 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
735bool 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
747void 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
760void 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
774static 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 >>
8033;
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
824static long freeDIB(LPBITMAPINFO lpDIBHeader)
825{
826
827 if (lpDIBHeader != NULL) {
828 free(lpDIBHeader);
829 }
830
831 return (0);
832}
833
834