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