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