]> git.saurik.com Git - wxWidgets.git/blame - src/msw/bitmap.cpp
VTK wrapper of vtkRenderWindow for wxPython. Tested on MSW so far.
[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 46#include "wx/msw/dib.h"
b75dd496 47#include "wx/image.h"
2bda0e17 48
10fcf31a
VZ
49// ----------------------------------------------------------------------------
50// macros
51// ----------------------------------------------------------------------------
52
2bda0e17 53#if !USE_SHARED_LIBRARIES
10fcf31a
VZ
54 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
55 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
2bda0e17
KB
56#endif
57
10fcf31a
VZ
58// ============================================================================
59// implementation
60// ============================================================================
61
62// ----------------------------------------------------------------------------
63// wxBitmapRefData
64// ----------------------------------------------------------------------------
65
66wxBitmapRefData::wxBitmapRefData()
2bda0e17
KB
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
10fcf31a 79wxBitmapRefData::~wxBitmapRefData()
2bda0e17 80{
d59ceba5
VZ
81 wxASSERT_MSG( !m_selectedInto,
82 wxT("deleting bitmap still selected into wxMemoryDC") );
2bda0e17 83
d59ceba5
VZ
84 if ( m_hBitmap)
85 DeleteObject((HBITMAP) m_hBitmap);
e7003166 86
d59ceba5
VZ
87 if ( m_bitmapMask )
88 delete m_bitmapMask;
2bda0e17
KB
89}
90
10fcf31a
VZ
91// ----------------------------------------------------------------------------
92// wxBitmap
93// ----------------------------------------------------------------------------
94
2bda0e17
KB
95wxList wxBitmap::sm_handlers;
96
4fe5383d
VZ
97// this function should be called from all wxBitmap ctors
98void wxBitmap::Init()
2bda0e17 99{
4fe5383d 100 // m_refData = NULL; done in the base class ctor
2bda0e17 101
07cf98cb
VZ
102 if ( wxTheBitmapList )
103 wxTheBitmapList->AddBitmap(this);
4fe5383d
VZ
104}
105
106bool wxBitmap::CopyFromIcon(const wxIcon& icon)
107{
108 UnRef();
07cf98cb
VZ
109
110 if ( !icon.Ok() )
4fe5383d 111 return FALSE;
07cf98cb
VZ
112
113 int width = icon.GetWidth(),
114 height = icon.GetHeight();
115
4fe5383d
VZ
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);
07cf98cb
VZ
126 HBITMAP hbmpOld = (HBITMAP)::SelectObject(hdc, hbitmap);
127
07cf98cb 128 ::DrawIcon(hdc, 0, 0, hicon);
07cf98cb
VZ
129
130 ::SelectObject(hdc, hbmpOld);
131 ::DeleteDC(hdc);
4fe5383d
VZ
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
222594ea
VZ
144 wxMask *mask = new wxMask;
145 mask->SetMaskBitmap((WXHBITMAP)iconInfo.hbmMask);
4fe5383d 146#endif // Win16/32
07cf98cb
VZ
147
148 m_refData = new wxBitmapRefData;
4fe5383d 149
07cf98cb
VZ
150 M_BITMAPDATA->m_width = width;
151 M_BITMAPDATA->m_height = height;
152 M_BITMAPDATA->m_depth = wxDisplayDepth();
07cf98cb
VZ
153
154 M_BITMAPDATA->m_hBitmap = (WXHBITMAP)hbitmap;
155 M_BITMAPDATA->m_ok = TRUE;
10fcf31a 156
222594ea
VZ
157#ifndef __WIN16__
158 SetMask(mask);
159#endif // !Win16
160
4fe5383d 161 return TRUE;
10fcf31a
VZ
162}
163
164wxBitmap::~wxBitmap()
2bda0e17
KB
165{
166 if (wxTheBitmapList)
167 wxTheBitmapList->DeleteObject(this);
168}
169
57c208c5 170bool wxBitmap::FreeResource(bool WXUNUSED(force))
2bda0e17
KB
171{
172 if ( !M_BITMAPDATA )
4fe5383d 173 return FALSE;
2bda0e17 174
d59ceba5
VZ
175 wxASSERT_MSG( !M_BITMAPDATA->m_selectedInto,
176 wxT("freeing bitmap still selected into wxMemoryDC") );
177
2bda0e17
KB
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
debe6624 195wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
2bda0e17 196{
4fe5383d 197 Init();
2bda0e17 198
4fe5383d 199 m_refData = new wxBitmapRefData;
2bda0e17 200
4fe5383d
VZ
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;
2bda0e17 205
4fe5383d 206 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, 1, no_bits, bits);
2bda0e17 207
4fe5383d
VZ
208 if (M_BITMAPDATA->m_hBitmap)
209 M_BITMAPDATA->m_ok = TRUE;
210 else
211 M_BITMAPDATA->m_ok = FALSE;
2bda0e17 212
4fe5383d 213 M_BITMAPDATA->m_selectedInto = NULL;
2bda0e17
KB
214}
215
2fd284a4 216// Create from XPM data
03ab016d 217wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
2fd284a4 218{
4fe5383d
VZ
219 Init();
220
221 (void)Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
2fd284a4
JS
222}
223
debe6624 224wxBitmap::wxBitmap(int w, int h, int d)
2bda0e17 225{
4fe5383d 226 Init();
2bda0e17 227
4fe5383d 228 (void)Create(w, h, d);
2bda0e17
KB
229}
230
debe6624 231wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
2bda0e17 232{
4fe5383d 233 Init();
2bda0e17 234
4fe5383d 235 (void) Create(data, type, width, height, depth);
2bda0e17
KB
236}
237
debe6624 238wxBitmap::wxBitmap(const wxString& filename, long type)
2bda0e17 239{
4fe5383d 240 Init();
2bda0e17 241
4fe5383d 242 LoadFile(filename, (int)type);
2bda0e17
KB
243}
244
debe6624 245bool wxBitmap::Create(int w, int h, int d)
2bda0e17
KB
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 {
4c444f19 257 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, 1, d, NULL);
2bda0e17
KB
258 }
259 else
260 {
57c208c5 261 HDC dc = GetDC((HWND) NULL);
2bda0e17 262 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
57c208c5 263 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
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
debe6624 273bool wxBitmap::LoadFile(const wxString& filename, long type)
2bda0e17
KB
274{
275 UnRef();
276
277 m_refData = new wxBitmapRefData;
278
279 wxBitmapHandler *handler = FindHandler(type);
280
1d792928 281 if ( handler == NULL ) {
b75dd496
VS
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;
1d792928
VZ
290 }
291
292 return handler->LoadFile(this, filename, type, -1, -1);
2bda0e17
KB
293}
294
debe6624 295bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
2bda0e17
KB
296{
297 UnRef();
298
299 m_refData = new wxBitmapRefData;
300
301 wxBitmapHandler *handler = FindHandler(type);
302
1d792928 303 if ( handler == NULL ) {
223d09f6 304 wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
1d792928
VZ
305
306 return FALSE;
307 }
308
309 return handler->Create(this, data, type, width, height, depth);
2bda0e17
KB
310}
311
debe6624 312bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
2bda0e17
KB
313{
314 wxBitmapHandler *handler = FindHandler(type);
315
b75dd496
VS
316 if ( handler == NULL ) { // try wxImage
317 wxImage image( *this );
318 if (image.Ok()) return image.SaveFile( filename, type );
319 else return FALSE;
1d792928
VZ
320 }
321
322 return handler->SaveFile(this, filename, type, palette);
2bda0e17
KB
323}
324
325void wxBitmap::SetWidth(int w)
326{
327 if (!M_BITMAPDATA)
b823f5a1 328 m_refData = new wxBitmapRefData;
2bda0e17
KB
329
330 M_BITMAPDATA->m_width = w;
331}
332
333void wxBitmap::SetHeight(int h)
334{
335 if (!M_BITMAPDATA)
1d792928 336 m_refData = new wxBitmapRefData;
2bda0e17
KB
337
338 M_BITMAPDATA->m_height = h;
339}
340
341void wxBitmap::SetDepth(int d)
342{
343 if (!M_BITMAPDATA)
1d792928 344 m_refData = new wxBitmapRefData;
2bda0e17
KB
345
346 M_BITMAPDATA->m_depth = d;
347}
348
349void wxBitmap::SetQuality(int q)
350{
351 if (!M_BITMAPDATA)
1d792928 352 m_refData = new wxBitmapRefData;
2bda0e17
KB
353
354 M_BITMAPDATA->m_quality = q;
355}
356
357void wxBitmap::SetOk(bool isOk)
358{
359 if (!M_BITMAPDATA)
1d792928 360 m_refData = new wxBitmapRefData;
2bda0e17
KB
361
362 M_BITMAPDATA->m_ok = isOk;
363}
364
365void wxBitmap::SetPalette(const wxPalette& palette)
366{
367 if (!M_BITMAPDATA)
1d792928 368 m_refData = new wxBitmapRefData;
2bda0e17
KB
369
370 M_BITMAPDATA->m_bitmapPalette = palette ;
371}
372
373void wxBitmap::SetMask(wxMask *mask)
374{
375 if (!M_BITMAPDATA)
1d792928 376 m_refData = new wxBitmapRefData;
2bda0e17
KB
377
378 M_BITMAPDATA->m_bitmapMask = mask ;
379}
380
381void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
382{
383 if (!M_BITMAPDATA)
228de783 384 m_refData = new wxBitmapRefData;
2bda0e17
KB
385
386 M_BITMAPDATA->m_hBitmap = bmp;
228de783 387 M_BITMAPDATA->m_ok = bmp != 0;
2bda0e17
KB
388}
389
390void wxBitmap::AddHandler(wxBitmapHandler *handler)
391{
1d792928 392 sm_handlers.Append(handler);
2bda0e17
KB
393}
394
395void wxBitmap::InsertHandler(wxBitmapHandler *handler)
396{
1d792928 397 sm_handlers.Insert(handler);
2bda0e17
KB
398}
399
400bool wxBitmap::RemoveHandler(const wxString& name)
401{
1d792928
VZ
402 wxBitmapHandler *handler = FindHandler(name);
403 if ( handler )
404 {
405 sm_handlers.DeleteObject(handler);
406 return TRUE;
407 }
408 else
409 return FALSE;
2bda0e17
KB
410}
411
412wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
413{
1d792928
VZ
414 wxNode *node = sm_handlers.First();
415 while ( node )
416 {
417 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
ce3ed50d 418 if ( (handler->GetName().Cmp(name) == 0) )
1d792928
VZ
419 return handler;
420 node = node->Next();
421 }
422 return NULL;
2bda0e17
KB
423}
424
425wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
426{
1d792928
VZ
427 wxNode *node = sm_handlers.First();
428 while ( node )
429 {
430 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
ce3ed50d
JS
431 if ( (handler->GetExtension().Cmp(extension) == 0) &&
432 (bitmapType == -1 || (handler->GetType() == bitmapType)) )
1d792928
VZ
433 return handler;
434 node = node->Next();
435 }
436 return NULL;
2bda0e17
KB
437}
438
439wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
440{
1d792928
VZ
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;
2bda0e17
KB
450}
451
7b46ecac
JS
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());
57c208c5 465 HPALETTE hPal = (HPALETTE) NULL;
7b46ecac 466 LPBITMAPINFO lpDib;
57c208c5 467 void *lpBits = (void*) NULL;
7b46ecac 468
a367b9b3 469/*
27529614 470 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
7b46ecac
JS
471
472 tmpBitmap.SetPalette(this->GetPalette());
473 memDC.SelectObject(tmpBitmap);
474 memDC.SetPalette(this->GetPalette());
475
476 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
a367b9b3
JS
477*/
478 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
479 {
c0ed460c 480 tmpBitmap.SetPalette(* this->GetPalette());
a367b9b3 481 memDC.SelectObject(tmpBitmap);
c0ed460c 482 memDC.SetPalette(* this->GetPalette());
a367b9b3
JS
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 }
7b46ecac
JS
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
2bda0e17
KB
511/*
512 * wxMask
513 */
514
10fcf31a 515wxMask::wxMask()
2bda0e17
KB
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;
1d792928 525 Create(bitmap, colour);
2bda0e17
KB
526}
527
528// Construct a mask from a bitmap and a palette index indicating
529// the transparent area
debe6624 530wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
531{
532 m_maskBitmap = 0;
1d792928 533 Create(bitmap, paletteIndex);
2bda0e17
KB
534}
535
536// Construct a mask from a mono bitmap (copies the bitmap).
537wxMask::wxMask(const wxBitmap& bitmap)
538{
539 m_maskBitmap = 0;
1d792928 540 Create(bitmap);
2bda0e17
KB
541}
542
10fcf31a 543wxMask::~wxMask()
2bda0e17
KB
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 )
1d792928
VZ
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;
2bda0e17
KB
576}
577
578// Create a mask from a bitmap and a palette index indicating
579// the transparent area
debe6624 580bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
581{
582 if ( m_maskBitmap )
1d792928
VZ
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;
2bda0e17
KB
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 )
1d792928
VZ
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;
2bda0e17
KB
649}
650
651/*
652 * wxBitmapHandler
653 */
654
655IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
656
57c208c5 657bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
2bda0e17 658{
1d792928 659 return FALSE;
2bda0e17
KB
660}
661
57c208c5
JS
662bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
663 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17 664{
1d792928 665 return FALSE;
2bda0e17
KB
666}
667
57c208c5 668bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette))
2bda0e17 669{
1d792928 670 return FALSE;
2bda0e17
KB
671}
672
673/*
674 * Standard handlers
675 */
676
677class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
678{
679 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
680public:
10fcf31a 681 inline wxBMPResourceHandler()
2bda0e17 682 {
1d792928
VZ
683 m_name = "Windows bitmap resource";
684 m_extension = "";
685 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
2bda0e17
KB
686 };
687
debe6624 688 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
689 int desiredWidth, int desiredHeight);
690};
691IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
692
57c208c5
JS
693bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
694 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17
KB
695{
696 // TODO: load colourmap.
697 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
698 if (M_BITMAPHANDLERDATA->m_hBitmap)
699 {
c793fa87
VZ
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;
2bda0e17 712 }
1d792928
VZ
713
714 // it's probably not found
223d09f6 715 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str());
1d792928
VZ
716
717 return FALSE;
2bda0e17
KB
718}
719
720class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
721{
722 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
723public:
10fcf31a 724 inline wxBMPFileHandler()
2bda0e17 725 {
1d792928
VZ
726 m_name = "Windows bitmap file";
727 m_extension = "bmp";
728 m_type = wxBITMAP_TYPE_BMP;
2bda0e17
KB
729 };
730
debe6624 731 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17 732 int desiredWidth, int desiredHeight);
debe6624 733 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
2bda0e17
KB
734};
735IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
736
57c208c5
JS
737bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
738 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
2bda0e17 739{
47d67540 740#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17
KB
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)
26ac4020
JS
755 {
756 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
757 delete palette;
758 }
2bda0e17
KB
759 return success;
760#else
1d792928 761 return FALSE;
2bda0e17
KB
762#endif
763}
764
57c208c5 765bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal)
2bda0e17 766{
47d67540 767#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17
KB
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
1d792928 773 return FALSE;
2bda0e17
KB
774#endif
775}
776
10fcf31a 777void wxBitmap::CleanUpHandlers()
2bda0e17 778{
1d792928
VZ
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 }
2bda0e17
KB
788}
789
10fcf31a 790void wxBitmap::InitStandardHandlers()
2bda0e17 791{
1d792928
VZ
792 AddHandler(new wxBMPResourceHandler);
793 AddHandler(new wxBMPFileHandler);
2fd284a4
JS
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
1d792928
VZ
800 AddHandler(new wxICOResourceHandler);
801 AddHandler(new wxICOFileHandler);
7b46ecac
JS
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