]> git.saurik.com Git - wxWidgets.git/blob - src/mac/bitmap.cpp
wxFileSystem now compiles if wxUSE_HTML (required by wxHTML)
[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 /* TODO
450 m_maskBitmap = 0;
451 */
452 }
453
454 // Construct a mask from a bitmap and a colour indicating
455 // the transparent area
456 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
457 {
458 /* TODO
459 m_maskBitmap = 0;
460 */
461 Create(bitmap, colour);
462 }
463
464 // Construct a mask from a bitmap and a palette index indicating
465 // the transparent area
466 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
467 {
468 /* TODO
469 m_maskBitmap = 0;
470 */
471
472 Create(bitmap, paletteIndex);
473 }
474
475 // Construct a mask from a mono bitmap (copies the bitmap).
476 wxMask::wxMask(const wxBitmap& bitmap)
477 {
478 /* TODO
479 m_maskBitmap = 0;
480 */
481
482 Create(bitmap);
483 }
484
485 wxMask::~wxMask()
486 {
487 // TODO: delete mask bitmap
488 }
489
490 // Create a mask from a mono bitmap (copies the bitmap).
491 bool wxMask::Create(const wxBitmap& bitmap)
492 {
493 // TODO
494 return FALSE;
495 }
496
497 // Create a mask from a bitmap and a palette index indicating
498 // the transparent area
499 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
500 {
501 // TODO
502 return FALSE;
503 }
504
505 // Create a mask from a bitmap and a colour indicating
506 // the transparent area
507 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
508 {
509 // TODO
510 return FALSE;
511 }
512
513 /*
514 * wxBitmapHandler
515 */
516
517 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
518
519 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
520 {
521 return FALSE;
522 }
523
524 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
525 int desiredWidth, int desiredHeight)
526 {
527 return FALSE;
528 }
529
530 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
531 {
532 return FALSE;
533 }
534
535 /*
536 * Standard handlers
537 */
538
539 class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
540 {
541 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
542 public:
543 inline wxPICTResourceHandler()
544 {
545 m_name = "Macintosh Pict resource";
546 m_extension = "";
547 m_type = wxBITMAP_TYPE_PICT_RESOURCE;
548 };
549
550 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
551 int desiredWidth, int desiredHeight);
552 };
553 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
554
555 bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
556 int desiredWidth, int desiredHeight)
557 {
558 Str255 theName ;
559
560 strcpy( (char*) theName , name ) ;
561 c2pstr( (char*) theName ) ;
562
563 PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
564 if ( thePict )
565 {
566 PictInfo theInfo ;
567
568 GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
569 DetachResource( (Handle) thePict ) ;
570 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
571 M_BITMAPHANDLERDATA->m_hPict = thePict ;
572 M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
573 M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
574
575 M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
576 M_BITMAPHANDLERDATA->m_ok = true ;
577 M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
578 // M_BITMAPHANDLERDATA->m_bitmapPalette;
579 // M_BITMAPHANDLERDATA->m_quality;
580 return TRUE ;
581 }
582 return FALSE ;
583 }
584
585 /* TODO: bitmap handlers, a bit like this:
586 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
587 {
588 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
589 public:
590 inline wxBMPResourceHandler()
591 {
592 m_name = "Windows bitmap resource";
593 m_extension = "";
594 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
595 };
596
597 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
598 int desiredWidth, int desiredHeight);
599 };
600 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
601 */
602
603 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
604 {
605 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
606 public:
607 inline wxXPMFileHandler(void)
608 {
609 m_name = "XPM bitmap file";
610 m_extension = "xpm";
611 m_type = wxBITMAP_TYPE_XPM;
612 };
613
614 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
615 int desiredWidth = -1, int desiredHeight = -1);
616 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
617 };
618 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
619
620 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
621 int desiredWidth, int desiredHeight)
622 {
623 #if USE_XPM_IN_MSW
624 XImage *ximage;
625 XpmAttributes xpmAttr;
626 HDC dc;
627
628 M_BITMAPHANDLERDATA->m_ok = FALSE;
629 dc = CreateCompatibleDC(NULL);
630 if (dc)
631 {
632 xpmAttr.valuemask = XpmReturnPixels;
633 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
634 DeleteDC(dc);
635 if (errorStatus == XpmSuccess)
636 {
637 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
638
639 BITMAP bm;
640 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
641
642 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
643 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
644 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
645 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
646 XpmFreeAttributes(&xpmAttr);
647 XImageFree(ximage);
648
649 M_BITMAPHANDLERDATA->m_ok = TRUE;
650 return TRUE;
651 }
652 else
653 {
654 M_BITMAPHANDLERDATA->m_ok = FALSE;
655 return FALSE;
656 }
657 }
658 #endif
659
660 return FALSE;
661 }
662
663 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
664 {
665 #if USE_XPM_IN_MSW
666 HDC dc = NULL;
667
668 Visual *visual = NULL;
669 XImage ximage;
670
671 dc = CreateCompatibleDC(NULL);
672 if (dc)
673 {
674 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
675 { /* for following SetPixel */
676 /* fill the XImage struct 'by hand' */
677 ximage.width = M_BITMAPHANDLERDATA->m_width;
678 ximage.height = M_BITMAPHANDLERDATA->m_height;
679 ximage.depth = M_BITMAPHANDLERDATA->m_depth;
680 ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap;
681 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
682 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
683
684 if (dc)
685 DeleteDC(dc);
686
687 if (errorStatus == XpmSuccess)
688 return TRUE; /* no error */
689 else
690 return FALSE;
691 } else return FALSE;
692 } else return FALSE;
693 #else
694 return FALSE;
695 #endif
696 }
697
698
699 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
700 {
701 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
702 public:
703 inline wxXPMDataHandler(void)
704 {
705 m_name = "XPM bitmap data";
706 m_extension = "xpm";
707 m_type = wxBITMAP_TYPE_XPM_DATA;
708 };
709
710 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
711 };
712 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
713
714 bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
715 {
716 XImage * ximage;
717 int ErrorStatus;
718 XpmAttributes xpmAttr;
719
720 xpmAttr.valuemask = XpmReturnInfos; // get infos back
721 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
722 &ximage, (XImage **) NULL, &xpmAttr);
723
724 if (ErrorStatus == XpmSuccess)
725 {
726 M_BITMAPHANDLERDATA->m_ok = FALSE;
727 M_BITMAPHANDLERDATA->m_numColors = 0;
728 M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ;
729
730 M_BITMAPHANDLERDATA->m_width = ximage->width;
731 M_BITMAPHANDLERDATA->m_height = ximage->height;
732 M_BITMAPHANDLERDATA->m_depth = ximage->depth;
733 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
734 XpmFreeAttributes(&xpmAttr);
735 M_BITMAPHANDLERDATA->m_ok = TRUE;
736 ximage->gworldptr = NULL ;
737 XImageFree(ximage); // releases the malloc, but does not detroy
738 // the bitmap
739 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
740
741 return TRUE;
742 }
743 else
744 {
745 M_BITMAPHANDLERDATA->m_ok = FALSE;
746 return FALSE;
747 }
748 return FALSE;
749 }
750
751 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
752 {
753 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
754 public:
755 inline wxBMPResourceHandler()
756 {
757 m_name = "Windows bitmap resource";
758 m_extension = "";
759 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
760 };
761
762 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
763 int desiredWidth, int desiredHeight);
764 };
765
766 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
767
768 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
769 int desiredWidth, int desiredHeight)
770 {
771 // TODO: load colourmap.
772 /*
773 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
774 if (M_BITMAPHANDLERDATA->m_hBitmap)
775 {
776 M_BITMAPHANDLERDATA->m_ok = TRUE;
777 BITMAP bm;
778 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
779 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
780 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
781 M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
782 return TRUE;
783 }
784 */
785 // it's probably not found
786 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
787
788 return FALSE;
789 }
790
791 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
792 {
793 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
794 public:
795 inline wxBMPFileHandler(void)
796 {
797 m_name = "Windows bitmap file";
798 m_extension = "bmp";
799 m_type = wxBITMAP_TYPE_BMP;
800 };
801
802 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
803 int desiredWidth, int desiredHeight);
804 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
805 };
806
807 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
808
809 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
810 int desiredWidth, int desiredHeight)
811 {
812 #if USE_IMAGE_LOADING_IN_MSW
813 wxPalette *palette = NULL;
814 bool success = FALSE;
815 /*
816 if (type & wxBITMAP_DISCARD_COLOURMAP)
817 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
818 else
819 */
820 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
821 if (!success && palette)
822 {
823 delete palette;
824 palette = NULL;
825 }
826 if (palette)
827 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
828 return success;
829 #else
830 return FALSE;
831 #endif
832 }
833
834 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
835 {
836 #if USE_IMAGE_LOADING_IN_MSW
837 wxPalette *actualPalette = (wxPalette *)pal;
838 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
839 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
840 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
841 #else
842 return FALSE;
843 #endif
844 }
845
846
847
848 void wxBitmap::CleanUpHandlers()
849 {
850 wxNode *node = sm_handlers.First();
851 while ( node )
852 {
853 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
854 wxNode *next = node->Next();
855 delete handler;
856 delete node;
857 node = next;
858 }
859 }
860
861 void wxBitmap::InitStandardHandlers()
862 {
863 AddHandler( new wxPICTResourceHandler ) ;
864 AddHandler( new wxICONResourceHandler ) ;
865 AddHandler(new wxXPMFileHandler);
866 AddHandler(new wxXPMDataHandler);
867 AddHandler(new wxBMPResourceHandler);
868 AddHandler(new wxBMPFileHandler);
869 }