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