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