]> git.saurik.com Git - wxWidgets.git/blame - src/msw/bitmap.cpp
Bugfix in GSocket_Cleanup()
[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
KB
79{
80 if (m_selectedInto)
81 {
837e5743 82 wxChar buf[200];
48c12cb1 83 wxSprintf(buf, _T("Bitmap was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) m_selectedInto);
2bda0e17
KB
84 wxFatalError(buf);
85 }
86 if (m_hBitmap)
87 {
88 DeleteObject((HBITMAP) m_hBitmap);
89 }
90 m_hBitmap = 0 ;
91
92 if (m_bitmapMask)
c9f8e0e2 93 delete m_bitmapMask;
2bda0e17 94 m_bitmapMask = NULL;
e7003166 95
2bda0e17
KB
96}
97
10fcf31a
VZ
98// ----------------------------------------------------------------------------
99// wxBitmap
100// ----------------------------------------------------------------------------
101
2bda0e17
KB
102wxList wxBitmap::sm_handlers;
103
10fcf31a 104wxBitmap::wxBitmap()
2bda0e17 105{
2bda0e17
KB
106 if ( wxTheBitmapList )
107 wxTheBitmapList->AddBitmap(this);
108}
109
10fcf31a
VZ
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()
2bda0e17
KB
136{
137 if (wxTheBitmapList)
138 wxTheBitmapList->DeleteObject(this);
139}
140
57c208c5 141bool wxBitmap::FreeResource(bool WXUNUSED(force))
2bda0e17
KB
142{
143 if ( !M_BITMAPDATA )
1d792928 144 return FALSE;
2bda0e17
KB
145
146 if (M_BITMAPDATA->m_selectedInto)
147 {
837e5743 148 wxChar buf[200];
48c12cb1 149 wxSprintf(buf, _T("Bitmap %lX was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) this, (unsigned long) M_BITMAPDATA->m_selectedInto);
2bda0e17
KB
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
debe6624 169wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
2bda0e17
KB
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
4c444f19 178 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, 1, no_bits, bits);
2bda0e17
KB
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
2fd284a4 191// Create from XPM data
03ab016d 192wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
2fd284a4
JS
193{
194 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
195}
196
debe6624 197wxBitmap::wxBitmap(int w, int h, int d)
2bda0e17
KB
198{
199 (void)Create(w, h, d);
200
201 if ( wxTheBitmapList )
202 wxTheBitmapList->AddBitmap(this);
203}
204
debe6624 205wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
2bda0e17
KB
206{
207 (void) Create(data, type, width, height, depth);
208
209 if ( wxTheBitmapList )
210 wxTheBitmapList->AddBitmap(this);
211}
212
debe6624 213wxBitmap::wxBitmap(const wxString& filename, long type)
2bda0e17
KB
214{
215 LoadFile(filename, (int)type);
216
217 if ( wxTheBitmapList )
218 wxTheBitmapList->AddBitmap(this);
219}
220
debe6624 221bool wxBitmap::Create(int w, int h, int d)
2bda0e17
KB
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 {
4c444f19 233 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, 1, d, NULL);
2bda0e17
KB
234 }
235 else
236 {
57c208c5 237 HDC dc = GetDC((HWND) NULL);
2bda0e17 238 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
57c208c5 239 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
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
debe6624 249bool wxBitmap::LoadFile(const wxString& filename, long type)
2bda0e17
KB
250{
251 UnRef();
252
253 m_refData = new wxBitmapRefData;
254
255 wxBitmapHandler *handler = FindHandler(type);
256
1d792928 257 if ( handler == NULL ) {
837e5743 258 wxLogWarning(_T("no bitmap handler for type %d defined."), type);
1d792928
VZ
259
260 return FALSE;
261 }
262
263 return handler->LoadFile(this, filename, type, -1, -1);
2bda0e17
KB
264}
265
debe6624 266bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
2bda0e17
KB
267{
268 UnRef();
269
270 m_refData = new wxBitmapRefData;
271
272 wxBitmapHandler *handler = FindHandler(type);
273
1d792928 274 if ( handler == NULL ) {
837e5743 275 wxLogWarning(_T("no bitmap handler for type %d defined."), type);
1d792928
VZ
276
277 return FALSE;
278 }
279
280 return handler->Create(this, data, type, width, height, depth);
2bda0e17
KB
281}
282
debe6624 283bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
2bda0e17
KB
284{
285 wxBitmapHandler *handler = FindHandler(type);
286
1d792928 287 if ( handler == NULL ) {
837e5743 288 wxLogWarning(_T("no bitmap handler for type %d defined."), type);
1d792928
VZ
289
290 return FALSE;
291 }
292
293 return handler->SaveFile(this, filename, type, palette);
2bda0e17
KB
294}
295
296void wxBitmap::SetWidth(int w)
297{
298 if (!M_BITMAPDATA)
b823f5a1 299 m_refData = new wxBitmapRefData;
2bda0e17
KB
300
301 M_BITMAPDATA->m_width = w;
302}
303
304void wxBitmap::SetHeight(int h)
305{
306 if (!M_BITMAPDATA)
1d792928 307 m_refData = new wxBitmapRefData;
2bda0e17
KB
308
309 M_BITMAPDATA->m_height = h;
310}
311
312void wxBitmap::SetDepth(int d)
313{
314 if (!M_BITMAPDATA)
1d792928 315 m_refData = new wxBitmapRefData;
2bda0e17
KB
316
317 M_BITMAPDATA->m_depth = d;
318}
319
320void wxBitmap::SetQuality(int q)
321{
322 if (!M_BITMAPDATA)
1d792928 323 m_refData = new wxBitmapRefData;
2bda0e17
KB
324
325 M_BITMAPDATA->m_quality = q;
326}
327
328void wxBitmap::SetOk(bool isOk)
329{
330 if (!M_BITMAPDATA)
1d792928 331 m_refData = new wxBitmapRefData;
2bda0e17
KB
332
333 M_BITMAPDATA->m_ok = isOk;
334}
335
336void wxBitmap::SetPalette(const wxPalette& palette)
337{
338 if (!M_BITMAPDATA)
1d792928 339 m_refData = new wxBitmapRefData;
2bda0e17
KB
340
341 M_BITMAPDATA->m_bitmapPalette = palette ;
342}
343
344void wxBitmap::SetMask(wxMask *mask)
345{
346 if (!M_BITMAPDATA)
1d792928 347 m_refData = new wxBitmapRefData;
2bda0e17
KB
348
349 M_BITMAPDATA->m_bitmapMask = mask ;
350}
351
352void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
353{
354 if (!M_BITMAPDATA)
1d792928 355 m_refData = new wxBitmapRefData;
2bda0e17
KB
356
357 M_BITMAPDATA->m_hBitmap = bmp;
358}
359
360void wxBitmap::AddHandler(wxBitmapHandler *handler)
361{
1d792928 362 sm_handlers.Append(handler);
2bda0e17
KB
363}
364
365void wxBitmap::InsertHandler(wxBitmapHandler *handler)
366{
1d792928 367 sm_handlers.Insert(handler);
2bda0e17
KB
368}
369
370bool wxBitmap::RemoveHandler(const wxString& name)
371{
1d792928
VZ
372 wxBitmapHandler *handler = FindHandler(name);
373 if ( handler )
374 {
375 sm_handlers.DeleteObject(handler);
376 return TRUE;
377 }
378 else
379 return FALSE;
2bda0e17
KB
380}
381
382wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
383{
1d792928
VZ
384 wxNode *node = sm_handlers.First();
385 while ( node )
386 {
387 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
ce3ed50d 388 if ( (handler->GetName().Cmp(name) == 0) )
1d792928
VZ
389 return handler;
390 node = node->Next();
391 }
392 return NULL;
2bda0e17
KB
393}
394
395wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
396{
1d792928
VZ
397 wxNode *node = sm_handlers.First();
398 while ( node )
399 {
400 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
ce3ed50d
JS
401 if ( (handler->GetExtension().Cmp(extension) == 0) &&
402 (bitmapType == -1 || (handler->GetType() == bitmapType)) )
1d792928
VZ
403 return handler;
404 node = node->Next();
405 }
406 return NULL;
2bda0e17
KB
407}
408
409wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
410{
1d792928
VZ
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;
2bda0e17
KB
420}
421
7b46ecac
JS
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());
57c208c5 435 HPALETTE hPal = (HPALETTE) NULL;
7b46ecac 436 LPBITMAPINFO lpDib;
57c208c5 437 void *lpBits = (void*) NULL;
7b46ecac 438
a367b9b3 439/*
27529614 440 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
7b46ecac
JS
441
442 tmpBitmap.SetPalette(this->GetPalette());
443 memDC.SelectObject(tmpBitmap);
444 memDC.SetPalette(this->GetPalette());
445
446 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
a367b9b3
JS
447*/
448 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
449 {
c0ed460c 450 tmpBitmap.SetPalette(* this->GetPalette());
a367b9b3 451 memDC.SelectObject(tmpBitmap);
c0ed460c 452 memDC.SetPalette(* this->GetPalette());
a367b9b3
JS
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 }
7b46ecac
JS
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
2bda0e17
KB
481/*
482 * wxMask
483 */
484
10fcf31a 485wxMask::wxMask()
2bda0e17
KB
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;
1d792928 495 Create(bitmap, colour);
2bda0e17
KB
496}
497
498// Construct a mask from a bitmap and a palette index indicating
499// the transparent area
debe6624 500wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
501{
502 m_maskBitmap = 0;
1d792928 503 Create(bitmap, paletteIndex);
2bda0e17
KB
504}
505
506// Construct a mask from a mono bitmap (copies the bitmap).
507wxMask::wxMask(const wxBitmap& bitmap)
508{
509 m_maskBitmap = 0;
1d792928 510 Create(bitmap);
2bda0e17
KB
511}
512
10fcf31a 513wxMask::~wxMask()
2bda0e17
KB
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 )
1d792928
VZ
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;
2bda0e17
KB
546}
547
548// Create a mask from a bitmap and a palette index indicating
549// the transparent area
debe6624 550bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
551{
552 if ( m_maskBitmap )
1d792928
VZ
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;
2bda0e17
KB
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 )
1d792928
VZ
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;
2bda0e17
KB
619}
620
621/*
622 * wxBitmapHandler
623 */
624
625IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
626
57c208c5 627bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
2bda0e17 628{
1d792928 629 return FALSE;
2bda0e17
KB
630}
631
57c208c5
JS
632bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
633 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17 634{
1d792928 635 return FALSE;
2bda0e17
KB
636}
637
57c208c5 638bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette))
2bda0e17 639{
1d792928 640 return FALSE;
2bda0e17
KB
641}
642
643/*
644 * Standard handlers
645 */
646
647class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
648{
649 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
650public:
10fcf31a 651 inline wxBMPResourceHandler()
2bda0e17 652 {
1d792928
VZ
653 m_name = "Windows bitmap resource";
654 m_extension = "";
655 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
2bda0e17
KB
656 };
657
debe6624 658 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
659 int desiredWidth, int desiredHeight);
660};
661IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
662
57c208c5
JS
663bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
664 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17
KB
665{
666 // TODO: load colourmap.
667 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
668 if (M_BITMAPHANDLERDATA->m_hBitmap)
669 {
c793fa87
VZ
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;
2bda0e17 682 }
1d792928
VZ
683
684 // it's probably not found
837e5743 685 wxLogError(_T("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str());
1d792928
VZ
686
687 return FALSE;
2bda0e17
KB
688}
689
690class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
691{
692 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
693public:
10fcf31a 694 inline wxBMPFileHandler()
2bda0e17 695 {
1d792928
VZ
696 m_name = "Windows bitmap file";
697 m_extension = "bmp";
698 m_type = wxBITMAP_TYPE_BMP;
2bda0e17
KB
699 };
700
debe6624 701 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17 702 int desiredWidth, int desiredHeight);
debe6624 703 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
2bda0e17
KB
704};
705IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
706
57c208c5
JS
707bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
708 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17 709{
47d67540 710#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17
KB
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)
26ac4020
JS
725 {
726 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
727 delete palette;
728 }
2bda0e17
KB
729 return success;
730#else
1d792928 731 return FALSE;
2bda0e17
KB
732#endif
733}
734
57c208c5 735bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal)
2bda0e17 736{
47d67540 737#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17
KB
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
1d792928 743 return FALSE;
2bda0e17
KB
744#endif
745}
746
10fcf31a 747void wxBitmap::CleanUpHandlers()
2bda0e17 748{
1d792928
VZ
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 }
2bda0e17
KB
758}
759
10fcf31a 760void wxBitmap::InitStandardHandlers()
2bda0e17 761{
1d792928
VZ
762 AddHandler(new wxBMPResourceHandler);
763 AddHandler(new wxBMPFileHandler);
2fd284a4
JS
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
1d792928
VZ
770 AddHandler(new wxICOResourceHandler);
771 AddHandler(new wxICOFileHandler);
7b46ecac
JS
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