]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/bitmap.cpp
VTK wrapper of vtkRenderWindow for wxPython. Tested on MSW so far.
[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#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
66wxBitmapRefData::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
79wxBitmapRefData::~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
95wxList wxBitmap::sm_handlers;
96
97// this function should be called from all wxBitmap ctors
98void wxBitmap::Init()
99{
100 // m_refData = NULL; done in the base class ctor
101
102 if ( wxTheBitmapList )
103 wxTheBitmapList->AddBitmap(this);
104}
105
106bool 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
164wxBitmap::~wxBitmap()
165{
166 if (wxTheBitmapList)
167 wxTheBitmapList->DeleteObject(this);
168}
169
170bool 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
195wxBitmap::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
217wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
218{
219 Init();
220
221 (void)Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
222}
223
224wxBitmap::wxBitmap(int w, int h, int d)
225{
226 Init();
227
228 (void)Create(w, h, d);
229}
230
231wxBitmap::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
238wxBitmap::wxBitmap(const wxString& filename, long type)
239{
240 Init();
241
242 LoadFile(filename, (int)type);
243}
244
245bool 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
273bool 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
295bool 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
312bool 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
325void wxBitmap::SetWidth(int w)
326{
327 if (!M_BITMAPDATA)
328 m_refData = new wxBitmapRefData;
329
330 M_BITMAPDATA->m_width = w;
331}
332
333void wxBitmap::SetHeight(int h)
334{
335 if (!M_BITMAPDATA)
336 m_refData = new wxBitmapRefData;
337
338 M_BITMAPDATA->m_height = h;
339}
340
341void wxBitmap::SetDepth(int d)
342{
343 if (!M_BITMAPDATA)
344 m_refData = new wxBitmapRefData;
345
346 M_BITMAPDATA->m_depth = d;
347}
348
349void wxBitmap::SetQuality(int q)
350{
351 if (!M_BITMAPDATA)
352 m_refData = new wxBitmapRefData;
353
354 M_BITMAPDATA->m_quality = q;
355}
356
357void wxBitmap::SetOk(bool isOk)
358{
359 if (!M_BITMAPDATA)
360 m_refData = new wxBitmapRefData;
361
362 M_BITMAPDATA->m_ok = isOk;
363}
364
365void wxBitmap::SetPalette(const wxPalette& palette)
366{
367 if (!M_BITMAPDATA)
368 m_refData = new wxBitmapRefData;
369
370 M_BITMAPDATA->m_bitmapPalette = palette ;
371}
372
373void wxBitmap::SetMask(wxMask *mask)
374{
375 if (!M_BITMAPDATA)
376 m_refData = new wxBitmapRefData;
377
378 M_BITMAPDATA->m_bitmapMask = mask ;
379}
380
381void 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
390void wxBitmap::AddHandler(wxBitmapHandler *handler)
391{
392 sm_handlers.Append(handler);
393}
394
395void wxBitmap::InsertHandler(wxBitmapHandler *handler)
396{
397 sm_handlers.Insert(handler);
398}
399
400bool 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
412wxBitmapHandler *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
425wxBitmapHandler *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
439wxBitmapHandler *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
453static long createDIB(long xSize, long ySize, long bitsPerPixel,
454 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
455static 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>
461wxBitmap 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
515wxMask::wxMask()
516{
517 m_maskBitmap = 0;
518}
519
520// Construct a mask from a bitmap and a colour indicating
521// the transparent area
522wxMask::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
530wxMask::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).
537wxMask::wxMask(const wxBitmap& bitmap)
538{
539 m_maskBitmap = 0;
540 Create(bitmap);
541}
542
543wxMask::~wxMask()
544{
545 if ( m_maskBitmap )
546 ::DeleteObject((HBITMAP) m_maskBitmap);
547}
548
549// Create a mask from a mono bitmap (copies the bitmap).
550bool 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
580bool 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
601bool 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
655IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
656
657bool 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
662bool 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
668bool 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
677class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
678{
679 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
680public:
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};
691IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
692
693bool 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
720class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
721{
722 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
723public:
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};
735IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
736
737bool 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
765bool 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
777void 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
790void 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
804static 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 >>
8333;
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
854static long freeDIB(LPBITMAPINFO lpDIBHeader)
855{
856
857 if (lpDIBHeader != NULL) {
858 free(lpDIBHeader);
859 }
860
861 return (0);
862}
863
864