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