]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/bitmap.cpp
added calls for invalidating the dc setup on mac explicitely (needed in case of neste...
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: bitmap.cpp
3// Purpose: wxBitmap
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "bitmap.h"
14#endif
15
03e11df5 16#include "wx/wx.h"
e9576ca5
SC
17#include "wx/setup.h"
18#include "wx/utils.h"
19#include "wx/palette.h"
20#include "wx/bitmap.h"
21#include "wx/icon.h"
22#include "wx/log.h"
23
519cb848
SC
24extern "C"
25{
03e11df5
GD
26#ifdef __UNIX__
27 #include "xpm/xpm.h"
28#else
519cb848 29 #include "xpm.h"
03e11df5 30#endif
519cb848
SC
31} ;
32
2f1ae414 33#if !USE_SHARED_LIBRARIES
e9576ca5
SC
34IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
35IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
2f1ae414 36#endif
e9576ca5 37
03e11df5
GD
38#ifdef __UNIX__
39 #include <QD/PictUtils.h>
40#else
41 #include <PictUtils.h>
42#endif
519cb848
SC
43
44CTabHandle wxMacCreateColorTable( int numColors )
45{
46 CTabHandle newColors; /* Handle to the new color table */
03e11df5 47
519cb848
SC
48 /* Allocate memory for the color table */
49 newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) +
50 sizeof (ColorSpec) * (numColors - 1) );
51 if (newColors != nil)
52 {
53 /* Initialize the fields */
54 (**newColors).ctSeed = GetCTSeed();
55 (**newColors).ctFlags = 0;
56 (**newColors).ctSize = numColors - 1;
57 /* Initialize the table of colors */
58 }
59 return newColors ;
60}
61
62void wxMacDestroyColorTable( CTabHandle colors )
63{
64 DisposeHandle( (Handle) colors ) ;
65}
66
67void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue )
68{
69 (**newColors).ctTable[index].value = index;
70 (**newColors).ctTable[index].rgb.red = 0 ;// someRedValue;
71 (**newColors).ctTable[index].rgb.green = 0 ; // someGreenValue;
72 (**newColors).ctTable[index].rgb.blue = 0 ; // someBlueValue;
73}
74
03e11df5 75GWorldPtr wxMacCreateGWorld( int width , int height , int depth )
519cb848
SC
76{
77 OSErr err = noErr ;
78 GWorldPtr port ;
03e11df5 79 Rect rect = { 0 , 0 , height , width } ;
519cb848
SC
80
81 if ( depth < 0 )
82 {
2f1ae414 83 depth = wxDisplayDepth() ;
519cb848
SC
84 }
85
86 err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
87 if ( err == noErr )
88 {
89 return port ;
90 }
91 return NULL ;
03e11df5 92}
519cb848
SC
93
94void wxMacDestroyGWorld( GWorldPtr gw )
95{
96 if ( gw )
97 DisposeGWorld( gw ) ;
98}
99
e9576ca5
SC
100wxBitmapRefData::wxBitmapRefData()
101{
102 m_ok = FALSE;
103 m_width = 0;
104 m_height = 0;
105 m_depth = 0;
106 m_quality = 0;
107 m_numColors = 0;
108 m_bitmapMask = NULL;
519cb848
SC
109 m_hBitmap = NULL ;
110 m_hPict = NULL ;
111 m_bitmapType = kMacBitmapTypeUnknownType ;
e9576ca5
SC
112}
113
114wxBitmapRefData::~wxBitmapRefData()
115{
519cb848
SC
116 switch (m_bitmapType)
117 {
118 case kMacBitmapTypePict :
119 {
120 if ( m_hPict )
121 {
122 KillPicture( m_hPict ) ;
123 m_hPict = NULL ;
124 }
125 }
126 break ;
127 case kMacBitmapTypeGrafWorld :
128 {
129 if ( m_hBitmap )
130 {
131 wxMacDestroyGWorld( m_hBitmap ) ;
132 m_hBitmap = NULL ;
133 }
134 }
135 break ;
136 default :
137 // unkown type ?
138 break ;
03e11df5 139 }
519cb848
SC
140
141 if (m_bitmapMask)
142 {
143 delete m_bitmapMask;
e9576ca5 144 m_bitmapMask = NULL;
519cb848 145 }
e9576ca5
SC
146}
147
148wxList wxBitmap::sm_handlers;
149
150wxBitmap::wxBitmap()
151{
152 m_refData = NULL;
153
154 if ( wxTheBitmapList )
155 wxTheBitmapList->AddBitmap(this);
156}
157
158wxBitmap::~wxBitmap()
159{
160 if (wxTheBitmapList)
161 wxTheBitmapList->DeleteObject(this);
162}
163
164wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
165{
166 m_refData = new wxBitmapRefData;
167
168 M_BITMAPDATA->m_width = the_width ;
169 M_BITMAPDATA->m_height = the_height ;
170 M_BITMAPDATA->m_depth = no_bits ;
171 M_BITMAPDATA->m_numColors = 0;
519cb848
SC
172 if ( no_bits == 1 )
173 {
03e11df5
GD
174 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
175 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
519cb848
SC
176 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
177
178 CGrafPtr origPort ;
179 GDHandle origDevice ;
180
181 GetGWorld( &origPort , &origDevice ) ;
182 SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ;
2f1ae414
SC
183 LockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
184
519cb848
SC
185 // bits is a word aligned array
186
187 unsigned char* linestart = (unsigned char*) bits ;
188 int linesize = ( the_width / 16 ) * 2 ;
189 if ( the_width % 16 )
190 {
191 linesize += 2 ;
03e11df5 192 }
519cb848
SC
193
194 RGBColor colors[2] = {
195 { 0xFFFF , 0xFFFF , 0xFFFF } ,
196 { 0, 0 , 0 }
197 } ;
198
03e11df5 199 for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
519cb848 200 {
03e11df5 201 for ( int x = 0 ; x < the_width ; ++x )
519cb848
SC
202 {
203 int index = x / 8 ;
204 int bit = x % 8 ;
205 int mask = 1 << bit ;
206 if ( linestart[index] & mask )
207 {
208 SetCPixel( x , y , &colors[1] ) ;
209 }
210 else
211 {
212 SetCPixel( x , y , &colors[0] ) ;
213 }
214 }
215
216 }
2f1ae414 217 UnlockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
519cb848
SC
218
219 SetGWorld( origPort , origDevice ) ;
220 }
221 else
222 {
03e11df5 223 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
519cb848 224 }
e9576ca5
SC
225
226 if ( wxTheBitmapList )
227 wxTheBitmapList->AddBitmap(this);
228}
229
230wxBitmap::wxBitmap(int w, int h, int d)
231{
232 (void)Create(w, h, d);
233
234 if ( wxTheBitmapList )
235 wxTheBitmapList->AddBitmap(this);
236}
237
238wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
239{
240 (void) Create(data, type, width, height, depth);
241
242 if ( wxTheBitmapList )
243 wxTheBitmapList->AddBitmap(this);
244}
245
246wxBitmap::wxBitmap(const wxString& filename, long type)
247{
248 LoadFile(filename, (int)type);
249
250 if ( wxTheBitmapList )
251 wxTheBitmapList->AddBitmap(this);
252}
253
e9576ca5
SC
254wxBitmap::wxBitmap(const char **data)
255{
256 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
257}
e9576ca5 258
03e11df5
GD
259wxBitmap::wxBitmap(char **data)
260{
261 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
262}
263
e9576ca5
SC
264bool wxBitmap::Create(int w, int h, int d)
265{
266 UnRef();
267
268 m_refData = new wxBitmapRefData;
269
270 M_BITMAPDATA->m_width = w;
271 M_BITMAPDATA->m_height = h;
272 M_BITMAPDATA->m_depth = d;
273
519cb848
SC
274 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
275 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ;
276 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
e9576ca5
SC
277 return M_BITMAPDATA->m_ok;
278}
279
519cb848
SC
280void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
281{
282 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
283 M_BITMAPDATA->m_hBitmap = bmp ;
284 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
285}
286
e9576ca5
SC
287bool wxBitmap::LoadFile(const wxString& filename, long type)
288{
289 UnRef();
290
291 m_refData = new wxBitmapRefData;
292
293 wxBitmapHandler *handler = FindHandler(type);
294
295 if ( handler == NULL ) {
296 wxLogWarning("no bitmap handler for type %d defined.", type);
297
298 return FALSE;
299 }
300
301 return handler->LoadFile(this, filename, type, -1, -1);
302}
303
304bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
305{
306 UnRef();
307
308 m_refData = new wxBitmapRefData;
309
310 wxBitmapHandler *handler = FindHandler(type);
311
312 if ( handler == NULL ) {
313 wxLogWarning("no bitmap handler for type %d defined.", type);
314
315 return FALSE;
316 }
317
318 return handler->Create(this, data, type, width, height, depth);
319}
320
321bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
322{
323 wxBitmapHandler *handler = FindHandler(type);
324
325 if ( handler == NULL ) {
326 wxLogWarning("no bitmap handler for type %d defined.", type);
327
328 return FALSE;
329 }
330
331 return handler->SaveFile(this, filename, type, palette);
332}
333
334void wxBitmap::SetWidth(int w)
335{
336 if (!M_BITMAPDATA)
337 m_refData = new wxBitmapRefData;
338
339 M_BITMAPDATA->m_width = w;
340}
341
342void wxBitmap::SetHeight(int h)
343{
344 if (!M_BITMAPDATA)
345 m_refData = new wxBitmapRefData;
346
347 M_BITMAPDATA->m_height = h;
348}
349
350void wxBitmap::SetDepth(int d)
351{
352 if (!M_BITMAPDATA)
353 m_refData = new wxBitmapRefData;
354
355 M_BITMAPDATA->m_depth = d;
356}
357
358void wxBitmap::SetQuality(int q)
359{
360 if (!M_BITMAPDATA)
361 m_refData = new wxBitmapRefData;
362
363 M_BITMAPDATA->m_quality = q;
364}
365
366void wxBitmap::SetOk(bool isOk)
367{
368 if (!M_BITMAPDATA)
369 m_refData = new wxBitmapRefData;
370
371 M_BITMAPDATA->m_ok = isOk;
372}
373
374void wxBitmap::SetPalette(const wxPalette& palette)
375{
376 if (!M_BITMAPDATA)
377 m_refData = new wxBitmapRefData;
378
379 M_BITMAPDATA->m_bitmapPalette = palette ;
380}
381
382void wxBitmap::SetMask(wxMask *mask)
383{
384 if (!M_BITMAPDATA)
385 m_refData = new wxBitmapRefData;
386
387 M_BITMAPDATA->m_bitmapMask = mask ;
388}
389
390void wxBitmap::AddHandler(wxBitmapHandler *handler)
391{
392 sm_handlers.Append(handler);
393}
394
395void wxBitmap::InsertHandler(wxBitmapHandler *handler)
396{
397 sm_handlers.Insert(handler);
398}
399
400bool wxBitmap::RemoveHandler(const wxString& name)
401{
402 wxBitmapHandler *handler = FindHandler(name);
403 if ( handler )
404 {
405 sm_handlers.DeleteObject(handler);
406 return TRUE;
407 }
408 else
409 return FALSE;
410}
411
412wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
413{
414 wxNode *node = sm_handlers.First();
415 while ( node )
416 {
417 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
418 if ( handler->GetName() == name )
419 return handler;
420 node = node->Next();
421 }
422 return NULL;
423}
424
425wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
426{
427 wxNode *node = sm_handlers.First();
428 while ( node )
429 {
430 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
431 if ( handler->GetExtension() == extension &&
432 (bitmapType == -1 || handler->GetType() == bitmapType) )
433 return handler;
434 node = node->Next();
435 }
436 return NULL;
437}
438
439wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
440{
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;
450}
451
452/*
453 * wxMask
454 */
455
456wxMask::wxMask()
457{
e9576ca5 458 m_maskBitmap = 0;
e9576ca5
SC
459}
460
461// Construct a mask from a bitmap and a colour indicating
462// the transparent area
463wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
464{
e9576ca5 465 m_maskBitmap = 0;
e9576ca5
SC
466 Create(bitmap, colour);
467}
468
469// Construct a mask from a bitmap and a palette index indicating
470// the transparent area
471wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
472{
e9576ca5 473 m_maskBitmap = 0;
e9576ca5
SC
474 Create(bitmap, paletteIndex);
475}
476
477// Construct a mask from a mono bitmap (copies the bitmap).
478wxMask::wxMask(const wxBitmap& bitmap)
479{
e9576ca5 480 m_maskBitmap = 0;
e9576ca5
SC
481 Create(bitmap);
482}
483
484wxMask::~wxMask()
485{
8208e181
SC
486 if ( m_maskBitmap )
487 {
488 wxMacDestroyGWorld( m_maskBitmap ) ;
489 m_maskBitmap = NULL ;
490 }
e9576ca5
SC
491}
492
493// Create a mask from a mono bitmap (copies the bitmap).
494bool wxMask::Create(const wxBitmap& bitmap)
495{
496// TODO
497 return FALSE;
498}
499
500// Create a mask from a bitmap and a palette index indicating
501// the transparent area
502bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
503{
504// TODO
505 return FALSE;
506}
507
508// Create a mask from a bitmap and a colour indicating
509// the transparent area
510bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
511{
8208e181
SC
512 if ( m_maskBitmap )
513 {
514 wxMacDestroyGWorld( m_maskBitmap ) ;
515 m_maskBitmap = NULL ;
516 }
517 wxASSERT( ((wxBitmapRefData*) bitmap.GetRefData())->m_bitmapType == kMacBitmapTypeGrafWorld ) ;
518 // other types would require a temporary bitmap. not yet implemented
519
520 if (!bitmap.Ok())
521 {
522 return FALSE;
523 }
524
525 m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 ) ;
2f1ae414
SC
526 LockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
527 LockPixels( GetGWorldPixMap( (CGrafPtr) ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
8208e181
SC
528 RGBColor maskColor = colour.GetPixel() ;
529
530 // this is not very efficient, but I can't think
531 // of a better way of doing it
532 CGrafPtr origPort ;
533 GDHandle origDevice ;
534
535 GetGWorld( &origPort , &origDevice ) ;
536 for (int w = 0; w < bitmap.GetWidth(); w++)
537 {
538 for (int h = 0; h < bitmap.GetHeight(); h++)
539 {
540 RGBColor colors[2] = {
541 { 0xFFFF , 0xFFFF , 0xFFFF } ,
542 { 0, 0 , 0 }
543 } ;
544
545 SetGWorld( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap , NULL ) ;
546 RGBColor col ;
547 GetCPixel( w , h , &col ) ;
548 SetGWorld( m_maskBitmap , NULL ) ;
549 if (col.red == maskColor.red && col.blue == maskColor.blue && col.green == maskColor.green)
550 {
551 SetCPixel( w , h , &colors[0] ) ;
552 }
553 else
554 {
555 SetCPixel( w , h , &colors[1] ) ;
556 }
557 }
558 }
2f1ae414
SC
559 UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
560 UnlockPixels( GetGWorldPixMap( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
8208e181
SC
561 SetGWorld( origPort , origDevice ) ;
562
563 return TRUE;
e9576ca5
SC
564}
565
566/*
567 * wxBitmapHandler
568 */
569
570IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
571
572bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
573{
574 return FALSE;
575}
576
577bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
578 int desiredWidth, int desiredHeight)
579{
580 return FALSE;
581}
582
583bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
584{
585 return FALSE;
586}
587
588/*
589 * Standard handlers
590 */
591
519cb848
SC
592class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
593{
594 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
595public:
596 inline wxPICTResourceHandler()
597 {
598 m_name = "Macintosh Pict resource";
599 m_extension = "";
600 m_type = wxBITMAP_TYPE_PICT_RESOURCE;
601 };
602
603 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
604 int desiredWidth, int desiredHeight);
605};
606IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
607
608bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
609 int desiredWidth, int desiredHeight)
610{
611 Str255 theName ;
612
03e11df5
GD
613#if TARGET_CARBON
614 c2pstrcpy( (StringPtr) theName , name ) ;
615#else
616 strcpy( (char *) theName , name ) ;
617 c2pstr( (char *)theName ) ;
618#endif
519cb848
SC
619
620 PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
621 if ( thePict )
622 {
623 PictInfo theInfo ;
624
625 GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
626 DetachResource( (Handle) thePict ) ;
627 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
628 M_BITMAPHANDLERDATA->m_hPict = thePict ;
629 M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
630 M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
631
632 M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
633 M_BITMAPHANDLERDATA->m_ok = true ;
634 M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
635// M_BITMAPHANDLERDATA->m_bitmapPalette;
636// M_BITMAPHANDLERDATA->m_quality;
637 return TRUE ;
638 }
639 return FALSE ;
640}
641
e9576ca5
SC
642/* TODO: bitmap handlers, a bit like this:
643class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
644{
645 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
646public:
647 inline wxBMPResourceHandler()
648 {
649 m_name = "Windows bitmap resource";
650 m_extension = "";
651 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
652 };
653
654 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
655 int desiredWidth, int desiredHeight);
656};
657IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
658*/
659
519cb848
SC
660class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
661{
662 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
663public:
664 inline wxXPMFileHandler(void)
665 {
666 m_name = "XPM bitmap file";
667 m_extension = "xpm";
668 m_type = wxBITMAP_TYPE_XPM;
669 };
670
671 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
672 int desiredWidth = -1, int desiredHeight = -1);
673 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
674};
675IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
676
677bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
678 int desiredWidth, int desiredHeight)
679{
680#if USE_XPM_IN_MSW
681 XImage *ximage;
682 XpmAttributes xpmAttr;
683 HDC dc;
684
685 M_BITMAPHANDLERDATA->m_ok = FALSE;
686 dc = CreateCompatibleDC(NULL);
687 if (dc)
688 {
689 xpmAttr.valuemask = XpmReturnPixels;
690 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
691 DeleteDC(dc);
692 if (errorStatus == XpmSuccess)
693 {
694 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
695
696 BITMAP bm;
697 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
698
699 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
700 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
701 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
702 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
703 XpmFreeAttributes(&xpmAttr);
704 XImageFree(ximage);
705
706 M_BITMAPHANDLERDATA->m_ok = TRUE;
707 return TRUE;
708 }
709 else
710 {
711 M_BITMAPHANDLERDATA->m_ok = FALSE;
712 return FALSE;
713 }
714 }
715#endif
716
717 return FALSE;
718}
719
720bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
721{
722#if USE_XPM_IN_MSW
723 HDC dc = NULL;
724
725 Visual *visual = NULL;
726 XImage ximage;
727
728 dc = CreateCompatibleDC(NULL);
729 if (dc)
730 {
731 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
2f1ae414
SC
732 {
733
519cb848
SC
734 ximage.width = M_BITMAPHANDLERDATA->m_width;
735 ximage.height = M_BITMAPHANDLERDATA->m_height;
736 ximage.depth = M_BITMAPHANDLERDATA->m_depth;
737 ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap;
738 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
739 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
740
741 if (dc)
742 DeleteDC(dc);
743
744 if (errorStatus == XpmSuccess)
2f1ae414 745 return TRUE;
519cb848
SC
746 else
747 return FALSE;
748 } else return FALSE;
749 } else return FALSE;
750#else
751 return FALSE;
752#endif
753}
754
755
756class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
757{
758 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
759public:
760 inline wxXPMDataHandler(void)
761 {
762 m_name = "XPM bitmap data";
763 m_extension = "xpm";
764 m_type = wxBITMAP_TYPE_XPM_DATA;
765 };
766
767 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
768};
769IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
770
771bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
772{
a959b088
SC
773 XImage * ximage = NULL ;
774 XImage * xshapeimage = NULL ;
519cb848
SC
775 int ErrorStatus;
776 XpmAttributes xpmAttr;
777
778 xpmAttr.valuemask = XpmReturnInfos; // get infos back
779 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
a959b088 780 &ximage, &xshapeimage, &xpmAttr);
519cb848
SC
781
782 if (ErrorStatus == XpmSuccess)
783 {
784 M_BITMAPHANDLERDATA->m_ok = FALSE;
785 M_BITMAPHANDLERDATA->m_numColors = 0;
786 M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ;
787
788 M_BITMAPHANDLERDATA->m_width = ximage->width;
789 M_BITMAPHANDLERDATA->m_height = ximage->height;
790 M_BITMAPHANDLERDATA->m_depth = ximage->depth;
791 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
792 XpmFreeAttributes(&xpmAttr);
793 M_BITMAPHANDLERDATA->m_ok = TRUE;
794 ximage->gworldptr = NULL ;
795 XImageFree(ximage); // releases the malloc, but does not detroy
796 // the bitmap
797 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
a959b088
SC
798 if ( xshapeimage != NULL )
799 {
800 wxMask* m = new wxMask() ;
801 m->SetMaskBitmap( xshapeimage->gworldptr ) ;
802 M_BITMAPHANDLERDATA->m_bitmapMask = m ;
803 }
519cb848
SC
804 return TRUE;
805 }
806 else
807 {
808 M_BITMAPHANDLERDATA->m_ok = FALSE;
809 return FALSE;
810 }
811 return FALSE;
812}
813
814class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
815{
816 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
817public:
818 inline wxBMPResourceHandler()
819 {
820 m_name = "Windows bitmap resource";
821 m_extension = "";
822 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
823 };
824
825 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
826 int desiredWidth, int desiredHeight);
827};
828
829IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
830
831bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
832 int desiredWidth, int desiredHeight)
833{
834 // TODO: load colourmap.
519cb848
SC
835 // it's probably not found
836 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
837
838 return FALSE;
839}
840
841class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
842{
843 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
844public:
845 inline wxBMPFileHandler(void)
846 {
847 m_name = "Windows bitmap file";
848 m_extension = "bmp";
849 m_type = wxBITMAP_TYPE_BMP;
850 };
851
852 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
853 int desiredWidth, int desiredHeight);
854 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
855};
856
857IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
858
859bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
860 int desiredWidth, int desiredHeight)
861{
862#if USE_IMAGE_LOADING_IN_MSW
863 wxPalette *palette = NULL;
864 bool success = FALSE;
519cb848
SC
865 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
866 if (!success && palette)
867 {
868 delete palette;
869 palette = NULL;
870 }
871 if (palette)
872 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
873 return success;
874#else
875 return FALSE;
876#endif
877}
878
879bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
880{
881#if USE_IMAGE_LOADING_IN_MSW
882 wxPalette *actualPalette = (wxPalette *)pal;
883 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
884 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
885 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
886#else
887 return FALSE;
888#endif
889}
890
891
e9576ca5
SC
892void wxBitmap::CleanUpHandlers()
893{
894 wxNode *node = sm_handlers.First();
895 while ( node )
896 {
897 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
898 wxNode *next = node->Next();
899 delete handler;
900 delete node;
901 node = next;
902 }
903}
904
905void wxBitmap::InitStandardHandlers()
906{
519cb848
SC
907 AddHandler( new wxPICTResourceHandler ) ;
908 AddHandler( new wxICONResourceHandler ) ;
909 AddHandler(new wxXPMFileHandler);
2f1ae414 910 AddHandler(new wxXPMDataHandler);
519cb848
SC
911 AddHandler(new wxBMPResourceHandler);
912 AddHandler(new wxBMPFileHandler);
e9576ca5 913}