]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/bitmap.cpp
corrected the invalidation when resizing windows (was only invalidating the client...
[wxWidgets.git] / src / mac / carbon / 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/wx.h"
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
24 extern "C"
25 {
26 #ifdef __UNIX__
27 #include "xpm/xpm.h"
28 #else
29 #include "xpm.h"
30 #endif
31 } ;
32
33 #if !USE_SHARED_LIBRARIES
34 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
35 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
36 #endif
37
38 #ifdef __UNIX__
39 #include <QD/PictUtils.h>
40 #else
41 #include <PictUtils.h>
42 #endif
43
44 CTabHandle wxMacCreateColorTable( int numColors )
45 {
46 CTabHandle newColors; /* Handle to the new color table */
47
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
62 void wxMacDestroyColorTable( CTabHandle colors )
63 {
64 DisposeHandle( (Handle) colors ) ;
65 }
66
67 void 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
75 GWorldPtr wxMacCreateGWorld( int width , int height , int depth )
76 {
77 OSErr err = noErr ;
78 GWorldPtr port ;
79 Rect rect = { 0 , 0 , height , width } ;
80
81 if ( depth < 0 )
82 {
83 depth = wxDisplayDepth() ;
84 }
85
86 err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
87 if ( err == noErr )
88 {
89 return port ;
90 }
91 return NULL ;
92 }
93
94 void wxMacDestroyGWorld( GWorldPtr gw )
95 {
96 if ( gw )
97 DisposeGWorld( gw ) ;
98 }
99
100 wxBitmapRefData::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;
109 m_hBitmap = NULL ;
110 m_hPict = NULL ;
111 m_bitmapType = kMacBitmapTypeUnknownType ;
112 }
113
114 wxBitmapRefData::~wxBitmapRefData()
115 {
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 ;
139 }
140
141 if (m_bitmapMask)
142 {
143 delete m_bitmapMask;
144 m_bitmapMask = NULL;
145 }
146 }
147
148 wxList wxBitmap::sm_handlers;
149
150 wxBitmap::wxBitmap()
151 {
152 m_refData = NULL;
153
154 if ( wxTheBitmapList )
155 wxTheBitmapList->AddBitmap(this);
156 }
157
158 wxBitmap::~wxBitmap()
159 {
160 if (wxTheBitmapList)
161 wxTheBitmapList->DeleteObject(this);
162 }
163
164 wxBitmap::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;
172 if ( no_bits == 1 )
173 {
174 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
175 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
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 ) ;
183 LockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
184
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 ;
192 }
193
194 RGBColor colors[2] = {
195 { 0xFFFF , 0xFFFF , 0xFFFF } ,
196 { 0, 0 , 0 }
197 } ;
198
199 for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
200 {
201 for ( int x = 0 ; x < the_width ; ++x )
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 }
217 UnlockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
218
219 SetGWorld( origPort , origDevice ) ;
220 }
221 else
222 {
223 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
224 }
225
226 if ( wxTheBitmapList )
227 wxTheBitmapList->AddBitmap(this);
228 }
229
230 wxBitmap::wxBitmap(int w, int h, int d)
231 {
232 (void)Create(w, h, d);
233
234 if ( wxTheBitmapList )
235 wxTheBitmapList->AddBitmap(this);
236 }
237
238 wxBitmap::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
246 wxBitmap::wxBitmap(const wxString& filename, long type)
247 {
248 LoadFile(filename, (int)type);
249
250 if ( wxTheBitmapList )
251 wxTheBitmapList->AddBitmap(this);
252 }
253
254 wxBitmap::wxBitmap(const char **data)
255 {
256 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
257 }
258
259 wxBitmap::wxBitmap(char **data)
260 {
261 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
262 }
263
264 bool 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
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 ) ;
277 return M_BITMAPDATA->m_ok;
278 }
279
280 void 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
287 bool 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
304 bool 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
321 bool 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
334 void wxBitmap::SetWidth(int w)
335 {
336 if (!M_BITMAPDATA)
337 m_refData = new wxBitmapRefData;
338
339 M_BITMAPDATA->m_width = w;
340 }
341
342 void wxBitmap::SetHeight(int h)
343 {
344 if (!M_BITMAPDATA)
345 m_refData = new wxBitmapRefData;
346
347 M_BITMAPDATA->m_height = h;
348 }
349
350 void wxBitmap::SetDepth(int d)
351 {
352 if (!M_BITMAPDATA)
353 m_refData = new wxBitmapRefData;
354
355 M_BITMAPDATA->m_depth = d;
356 }
357
358 void wxBitmap::SetQuality(int q)
359 {
360 if (!M_BITMAPDATA)
361 m_refData = new wxBitmapRefData;
362
363 M_BITMAPDATA->m_quality = q;
364 }
365
366 void wxBitmap::SetOk(bool isOk)
367 {
368 if (!M_BITMAPDATA)
369 m_refData = new wxBitmapRefData;
370
371 M_BITMAPDATA->m_ok = isOk;
372 }
373
374 void wxBitmap::SetPalette(const wxPalette& palette)
375 {
376 if (!M_BITMAPDATA)
377 m_refData = new wxBitmapRefData;
378
379 M_BITMAPDATA->m_bitmapPalette = palette ;
380 }
381
382 void wxBitmap::SetMask(wxMask *mask)
383 {
384 if (!M_BITMAPDATA)
385 m_refData = new wxBitmapRefData;
386
387 M_BITMAPDATA->m_bitmapMask = mask ;
388 }
389
390 void wxBitmap::AddHandler(wxBitmapHandler *handler)
391 {
392 sm_handlers.Append(handler);
393 }
394
395 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
396 {
397 sm_handlers.Insert(handler);
398 }
399
400 bool 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
412 wxBitmapHandler *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
425 wxBitmapHandler *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
439 wxBitmapHandler *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
456 wxMask::wxMask()
457 {
458 m_maskBitmap = 0;
459 }
460
461 // Construct a mask from a bitmap and a colour indicating
462 // the transparent area
463 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
464 {
465 m_maskBitmap = 0;
466 Create(bitmap, colour);
467 }
468
469 // Construct a mask from a bitmap and a palette index indicating
470 // the transparent area
471 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
472 {
473 m_maskBitmap = 0;
474 Create(bitmap, paletteIndex);
475 }
476
477 // Construct a mask from a mono bitmap (copies the bitmap).
478 wxMask::wxMask(const wxBitmap& bitmap)
479 {
480 m_maskBitmap = 0;
481 Create(bitmap);
482 }
483
484 wxMask::~wxMask()
485 {
486 if ( m_maskBitmap )
487 {
488 wxMacDestroyGWorld( m_maskBitmap ) ;
489 m_maskBitmap = NULL ;
490 }
491 }
492
493 // Create a mask from a mono bitmap (copies the bitmap).
494 bool 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
502 bool 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
510 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
511 {
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 ) ;
526 LockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
527 LockPixels( GetGWorldPixMap( (CGrafPtr) ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
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 }
559 UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
560 UnlockPixels( GetGWorldPixMap( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
561 SetGWorld( origPort , origDevice ) ;
562
563 return TRUE;
564 }
565
566 /*
567 * wxBitmapHandler
568 */
569
570 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
571
572 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
573 {
574 return FALSE;
575 }
576
577 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
578 int desiredWidth, int desiredHeight)
579 {
580 return FALSE;
581 }
582
583 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
584 {
585 return FALSE;
586 }
587
588 /*
589 * Standard handlers
590 */
591
592 class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
593 {
594 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
595 public:
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 };
606 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
607
608 bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
609 int desiredWidth, int desiredHeight)
610 {
611 Str255 theName ;
612
613 #if TARGET_CARBON
614 c2pstrcpy( (StringPtr) theName , name ) ;
615 #else
616 strcpy( (char *) theName , name ) ;
617 c2pstr( (char *)theName ) ;
618 #endif
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
642 /* TODO: bitmap handlers, a bit like this:
643 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
644 {
645 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
646 public:
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 };
657 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
658 */
659
660 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
661 {
662 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
663 public:
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 };
675 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
676
677 bool 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
720 bool 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))
732 {
733
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)
745 return TRUE;
746 else
747 return FALSE;
748 } else return FALSE;
749 } else return FALSE;
750 #else
751 return FALSE;
752 #endif
753 }
754
755
756 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
757 {
758 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
759 public:
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 };
769 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
770
771 bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
772 {
773 XImage * ximage = NULL ;
774 XImage * xshapeimage = NULL ;
775 int ErrorStatus;
776 XpmAttributes xpmAttr;
777
778 xpmAttr.valuemask = XpmReturnInfos; // get infos back
779 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
780 &ximage, &xshapeimage, &xpmAttr);
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 ;
798 if ( xshapeimage != NULL )
799 {
800 wxMask* m = new wxMask() ;
801 m->SetMaskBitmap( xshapeimage->gworldptr ) ;
802 M_BITMAPHANDLERDATA->m_bitmapMask = m ;
803 }
804 return TRUE;
805 }
806 else
807 {
808 M_BITMAPHANDLERDATA->m_ok = FALSE;
809 return FALSE;
810 }
811 return FALSE;
812 }
813
814 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
815 {
816 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
817 public:
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
829 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
830
831 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
832 int desiredWidth, int desiredHeight)
833 {
834 // TODO: load colourmap.
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
841 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
842 {
843 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
844 public:
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
857 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
858
859 bool 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;
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
879 bool 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
892 void 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
905 void wxBitmap::InitStandardHandlers()
906 {
907 AddHandler( new wxPICTResourceHandler ) ;
908 AddHandler( new wxICONResourceHandler ) ;
909 AddHandler(new wxXPMFileHandler);
910 AddHandler(new wxXPMDataHandler);
911 AddHandler(new wxBMPResourceHandler);
912 AddHandler(new wxBMPFileHandler);
913 }