]> git.saurik.com Git - wxWidgets.git/blob - src/mac/bitmap.cpp
Got rid of some wierd VisualAge debug nonsense that had appeared in this after the...
[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/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 #include "wx/image.h"
24
25 extern "C"
26 {
27 #ifdef __UNIX__
28 #include "xpm/xpm.h"
29 #else
30 #include "xpm.h"
31 #endif
32 } ;
33
34 #if !USE_SHARED_LIBRARIES
35 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
36 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
37 #endif
38
39 #ifdef __UNIX__
40 #include <ApplicationServices/ApplicationServices.h>
41 #else
42 #include <PictUtils.h>
43 #endif
44
45 #include "wx/mac/uma.h"
46
47 CTabHandle wxMacCreateColorTable( int numColors )
48 {
49 CTabHandle newColors; /* Handle to the new color table */
50
51 /* Allocate memory for the color table */
52 newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) +
53 sizeof (ColorSpec) * (numColors - 1) );
54 if (newColors != nil)
55 {
56 /* Initialize the fields */
57 (**newColors).ctSeed = GetCTSeed();
58 (**newColors).ctFlags = 0;
59 (**newColors).ctSize = numColors - 1;
60 /* Initialize the table of colors */
61 }
62 return newColors ;
63 }
64
65 void wxMacDestroyColorTable( CTabHandle colors )
66 {
67 DisposeHandle( (Handle) colors ) ;
68 }
69
70 void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue )
71 {
72 (**newColors).ctTable[index].value = index;
73 (**newColors).ctTable[index].rgb.red = 0 ;// someRedValue;
74 (**newColors).ctTable[index].rgb.green = 0 ; // someGreenValue;
75 (**newColors).ctTable[index].rgb.blue = 0 ; // someBlueValue;
76 }
77
78 GWorldPtr wxMacCreateGWorld( int width , int height , int depth )
79 {
80 OSErr err = noErr ;
81 GWorldPtr port ;
82 Rect rect = { 0 , 0 , height , width } ;
83
84 if ( depth < 0 )
85 {
86 depth = wxDisplayDepth() ;
87 }
88
89 err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
90 if ( err == noErr )
91 {
92 return port ;
93 }
94 return NULL ;
95 }
96
97 void wxMacDestroyGWorld( GWorldPtr gw )
98 {
99 if ( gw )
100 DisposeGWorld( gw ) ;
101 }
102
103 PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask)
104 {
105 CGrafPtr origPort ;
106 GDHandle origDev ;
107
108 PicHandle pict; // this is the Picture we give back
109
110 RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ;
111 RGBColor white = { 0xffff ,0xffff , 0xffff } ;
112 RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ;
113
114 unsigned char *maskimage = NULL ;
115 Rect portRect ;
116 GetPortBounds( wp , &portRect ) ;
117 int width = portRect.right - portRect.left ;
118 int height = portRect.bottom - portRect.top ;
119
120 LockPixels( GetGWorldPixMap( wp ) ) ;
121 GetGWorld( &origPort , &origDev ) ;
122
123 if ( mask )
124 {
125 maskimage = (unsigned char*) malloc( width * height ) ;
126 SetGWorld( mask , NULL ) ;
127 LockPixels( GetGWorldPixMap( mask ) ) ;
128 for ( int y = 0 ; y < height ; y++ )
129 {
130 for( int x = 0 ; x < width ; x++ )
131 {
132 RGBColor col ;
133
134 GetCPixel( x + portRect.left , y + portRect.top , &col ) ;
135 maskimage[y*width + x] = ( col.red == 0 ) ; // for monochrome masks
136 }
137 }
138 UnlockPixels( GetGWorldPixMap( mask ) ) ;
139 }
140
141 SetGWorld( wp , NULL ) ;
142
143 pict = OpenPicture(&portRect); // open a picture, this disables drawing
144 if(!pict)
145 return NULL;
146
147 if ( maskimage )
148 {
149 RGBForeColor( &black ) ;
150 RGBBackColor( &white ) ;
151 PenMode(transparent);
152
153 for ( int y = 0 ; y < height ; ++y )
154 {
155 for( int x = 0 ; x < width ; ++x )
156 {
157 if ( maskimage[y*width + x] )
158 {
159 RGBColor col ;
160
161 GetCPixel( x + portRect.left , y + portRect.top , &col ) ;
162 SetCPixel( x + portRect.left , y + portRect.top , &col ) ;
163 }
164 else {
165 // With transparency set this sets a blank pixel not a white one
166 SetCPixel( x + portRect.left , y + portRect.top , &white);
167 }
168 }
169 }
170 free( maskimage ) ;
171 maskimage = NULL ;
172 }
173 else
174 {
175 RGBBackColor( &gray ) ;
176 EraseRect(&portRect);
177 RGBForeColor( &black ) ;
178 RGBBackColor( &white ) ;
179
180 CopyBits(GetPortBitMapForCopyBits(wp), /* src PixMap - we copy image over
181 * itself - */
182 GetPortBitMapForCopyBits(wp), // dst PixMap - no drawing occurs
183 &portRect, // srcRect - it will be recorded and compressed -
184 &portRect, // dstRect - into the picture that is open -
185 srcCopy,NULL); // copyMode and no clip region
186 }
187 ClosePicture(); // We are done recording the picture
188 UnlockPixels( GetGWorldPixMap( wp ) ) ;
189 SetGWorld( origPort , origDev ) ;
190
191 return pict; // return our groovy pict handle
192 }
193
194 wxBitmapRefData::wxBitmapRefData()
195 {
196 m_ok = FALSE;
197 m_width = 0;
198 m_height = 0;
199 m_depth = 0;
200 m_quality = 0;
201 m_numColors = 0;
202 m_bitmapMask = NULL;
203 m_hBitmap = NULL ;
204 m_hPict = NULL ;
205 m_bitmapType = kMacBitmapTypeUnknownType ;
206 }
207
208 wxBitmapRefData::~wxBitmapRefData()
209 {
210 switch (m_bitmapType)
211 {
212 case kMacBitmapTypePict :
213 {
214 if ( m_hPict )
215 {
216 KillPicture( m_hPict ) ;
217 m_hPict = NULL ;
218 }
219 }
220 break ;
221 case kMacBitmapTypeGrafWorld :
222 {
223 if ( m_hBitmap )
224 {
225 wxMacDestroyGWorld( m_hBitmap ) ;
226 m_hBitmap = NULL ;
227 }
228 }
229 break ;
230 default :
231 // unkown type ?
232 break ;
233 }
234
235 if (m_bitmapMask)
236 {
237 delete m_bitmapMask;
238 m_bitmapMask = NULL;
239 }
240 }
241
242 wxList wxBitmap::sm_handlers;
243
244 wxBitmap::wxBitmap()
245 {
246 m_refData = NULL;
247
248 if ( wxTheBitmapList )
249 wxTheBitmapList->AddBitmap(this);
250 }
251
252 wxBitmap::~wxBitmap()
253 {
254 if (wxTheBitmapList)
255 wxTheBitmapList->DeleteObject(this);
256 }
257
258 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
259 {
260 m_refData = new wxBitmapRefData;
261
262 M_BITMAPDATA->m_width = the_width ;
263 M_BITMAPDATA->m_height = the_height ;
264 M_BITMAPDATA->m_depth = no_bits ;
265 M_BITMAPDATA->m_numColors = 0;
266 if ( no_bits == 1 )
267 {
268 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
269 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
270 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
271
272 CGrafPtr origPort ;
273 GDHandle origDevice ;
274
275 GetGWorld( &origPort , &origDevice ) ;
276 SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ;
277 LockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ;
278
279 #ifdef __UNIX__
280 // bits is a word aligned array?? Don't think so
281 // bits is a char array on MAC OS X however using the benefit of the
282 // doubt I replaced references to 16 with sizeof(unsigned char)*8
283 unsigned char* linestart = (unsigned char*) bits ;
284 int linesize = ( the_width / (sizeof(unsigned char) * 8)) ;
285 if ( the_width % (sizeof(unsigned char) * 8) ) {
286 linesize += sizeof(unsigned char);
287 }
288 #else
289 // bits is a word aligned array
290
291 unsigned char* linestart = (unsigned char*) bits ;
292 int linesize = ( the_width / 16 ) * 2 ;
293 if ( the_width % 16 )
294 {
295 linesize += 2 ;
296 }
297 #endif
298
299 RGBColor colors[2] = {
300 { 0xFFFF , 0xFFFF , 0xFFFF } ,
301 { 0, 0 , 0 }
302 } ;
303
304 for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
305 {
306 for ( int x = 0 ; x < the_width ; ++x )
307 {
308 int index = x / 8 ;
309 int bit = x % 8 ;
310 int mask = 1 << bit ;
311 if ( linestart[index] & mask )
312 {
313 SetCPixel( x , y , &colors[1] ) ;
314 }
315 else
316 {
317 SetCPixel( x , y , &colors[0] ) ;
318 }
319 }
320
321 }
322 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ;
323
324 SetGWorld( origPort , origDevice ) ;
325 }
326 else
327 {
328 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
329 }
330
331 if ( wxTheBitmapList )
332 wxTheBitmapList->AddBitmap(this);
333 }
334
335 wxBitmap::wxBitmap(int w, int h, int d)
336 {
337 (void)Create(w, h, d);
338
339 if ( wxTheBitmapList )
340 wxTheBitmapList->AddBitmap(this);
341 }
342
343 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
344 {
345 (void) Create(data, type, width, height, depth);
346
347 if ( wxTheBitmapList )
348 wxTheBitmapList->AddBitmap(this);
349 }
350
351 wxBitmap::wxBitmap(const wxString& filename, long type)
352 {
353 LoadFile(filename, (int)type);
354
355 if ( wxTheBitmapList )
356 wxTheBitmapList->AddBitmap(this);
357 }
358
359 wxBitmap::wxBitmap(const char **data)
360 {
361 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
362 }
363
364 wxBitmap::wxBitmap(char **data)
365 {
366 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
367 }
368
369 wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
370 {
371 wxCHECK_MSG( Ok() &&
372 (rect.x >= 0) && (rect.y >= 0) &&
373 (rect.x+rect.width <= GetWidth()) &&
374 (rect.y+rect.height <= GetHeight()),
375 wxNullBitmap, wxT("invalid bitmap or bitmap region") );
376
377
378 wxBitmap ret( rect.width, rect.height, GetDepth() );
379 wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
380
381 WXHBITMAP origPort;
382 GDHandle origDevice;
383
384 GetGWorld( &origPort, &origDevice );
385
386 // Update the subbitmaps reference data
387 wxBitmapRefData *ref = (wxBitmapRefData *)ret.GetRefData();
388
389 ref->m_numColors = M_BITMAPDATA->m_numColors;
390 ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette;
391 ref->m_bitmapType = M_BITMAPDATA->m_bitmapType;
392
393 // Copy sub region of this bitmap
394 if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict)
395 {
396 printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
397 }
398 else if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypeGrafWorld)
399 {
400 // Copy mask
401 if(GetMask())
402 {
403 WXHBITMAP submask, mask;
404 RGBColor color;
405
406 mask = GetMask()->GetMaskBitmap();
407 submask = wxMacCreateGWorld(rect.width, rect.height, 1);
408 LockPixels(GetGWorldPixMap(mask));
409 LockPixels(GetGWorldPixMap(submask));
410
411 for(int yy = 0; yy < rect.height; yy++)
412 {
413 for(int xx = 0; xx < rect.width; xx++)
414 {
415 SetGWorld(mask, NULL);
416 GetCPixel(rect.x + xx, rect.y + yy, &color);
417 SetGWorld(submask, NULL);
418 SetCPixel(xx,yy, &color);
419 }
420 }
421 UnlockPixels(GetGWorldPixMap(mask));
422 UnlockPixels(GetGWorldPixMap(submask));
423 ref->m_bitmapMask = new wxMask;
424 ref->m_bitmapMask->SetMaskBitmap(submask);
425 }
426
427 // Copy bitmap
428 if(GetHBITMAP())
429 {
430 WXHBITMAP subbitmap, bitmap;
431 RGBColor color;
432
433 bitmap = GetHBITMAP();
434 subbitmap = wxMacCreateGWorld(rect.width, rect.height, GetDepth());
435 LockPixels(GetGWorldPixMap(bitmap));
436 LockPixels(GetGWorldPixMap(subbitmap));
437
438 for(int yy = 0; yy < rect.height; yy++)
439 {
440 for(int xx = 0; xx < rect.width; xx++)
441 {
442 SetGWorld(bitmap, NULL);
443 GetCPixel(rect.x + xx, rect.y + yy, &color);
444 SetGWorld(subbitmap, NULL);
445 SetCPixel(xx, yy, &color);
446 }
447 }
448 UnlockPixels(GetGWorldPixMap(bitmap));
449 UnlockPixels(GetGWorldPixMap(subbitmap));
450 ret.SetHBITMAP(subbitmap);
451 }
452 }
453 SetGWorld( origPort, origDevice );
454
455 return ret;
456 }
457
458 bool wxBitmap::Create(int w, int h, int d)
459 {
460 UnRef();
461
462 m_refData = new wxBitmapRefData;
463
464 M_BITMAPDATA->m_width = w;
465 M_BITMAPDATA->m_height = h;
466 M_BITMAPDATA->m_depth = d;
467
468 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
469 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ;
470 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
471 return M_BITMAPDATA->m_ok;
472 }
473
474 int wxBitmap::GetBitmapType() const
475 {
476 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType, wxT("invalid bitmap") );
477
478 return M_BITMAPDATA->m_bitmapType;
479 }
480
481 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
482 {
483 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
484 M_BITMAPDATA->m_hBitmap = bmp ;
485 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
486 }
487
488 bool wxBitmap::LoadFile(const wxString& filename, long type)
489 {
490 UnRef();
491
492 m_refData = new wxBitmapRefData;
493
494 wxBitmapHandler *handler = FindHandler(type);
495
496 if ( handler == NULL ) {
497 wxLogWarning("no bitmap handler for type %d defined.", type);
498
499 return FALSE;
500 }
501
502 return handler->LoadFile(this, filename, type, -1, -1);
503 }
504
505 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
506 {
507 UnRef();
508
509 m_refData = new wxBitmapRefData;
510
511 wxBitmapHandler *handler = FindHandler(type);
512
513 if ( handler == NULL ) {
514 wxLogWarning("no bitmap handler for type %d defined.", type);
515
516 return FALSE;
517 }
518
519 return handler->Create(this, data, type, width, height, depth);
520 }
521
522 wxBitmap::wxBitmap(const wxImage& image, int depth)
523 {
524 wxCHECK_RET( image.Ok(), wxT("invalid image") )
525 wxCHECK_RET( depth == -1, wxT("invalid bitmap depth") )
526
527 m_refData = new wxBitmapRefData();
528
529 if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
530
531 // width and height of the device-dependent bitmap
532 int width = image.GetWidth();
533 int height = image.GetHeight();
534
535 // Create picture
536
537 Create( width , height , wxDisplayDepth() ) ;
538 wxBitmap maskBitmap( width, height, 1);
539
540 CGrafPtr origPort ;
541 GDHandle origDevice ;
542
543 LockPixels( GetGWorldPixMap(GetHBITMAP()) );
544 LockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) );
545
546 GetGWorld( &origPort , &origDevice ) ;
547 SetGWorld( GetHBITMAP() , NULL ) ;
548
549 // Render image
550 wxColour rgb, maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
551 RGBColor color;
552 RGBColor white = { 0xffff, 0xffff, 0xffff };
553 RGBColor black = { 0 , 0 , 0 };
554
555 register unsigned char* data = image.GetData();
556
557 int index = 0;
558 for (int y = 0; y < height; y++)
559 {
560 for (int x = 0; x < width; x++)
561 {
562 rgb.Set(data[index++], data[index++], data[index++]);
563 color = rgb.GetPixel();
564 SetCPixel( x , y , &color ) ;
565 if (image.HasMask())
566 {
567 SetGWorld(maskBitmap.GetHBITMAP(), NULL);
568 if (rgb == maskcolor) {
569 SetCPixel(x,y, &white);
570 }
571 else {
572 SetCPixel(x,y, &black);
573 }
574 SetGWorld(GetHBITMAP(), NULL);
575 }
576 }
577 } // for height
578
579 // Create mask
580 if ( image.HasMask() ) {
581 wxMask *mask = new wxMask( maskBitmap );
582 }
583
584 UnlockPixels( GetGWorldPixMap(GetHBITMAP()) );
585 UnlockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) );
586 SetGWorld( origPort, origDevice );
587 }
588
589 wxImage wxBitmap::ConvertToImage() const
590 {
591 wxImage image;
592
593 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
594
595 // create an wxImage object
596 int width = GetWidth();
597 int height = GetHeight();
598 image.Create( width, height );
599
600 unsigned char *data = image.GetData();
601
602 wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") );
603
604 WXHBITMAP origPort;
605 GDHandle origDevice;
606 int index;
607 RGBColor color;
608 // background color set to RGB(16,16,16) in consistent with wxGTK
609 unsigned char mask_r=16, mask_g=16, mask_b=16;
610 SInt16 r,g,b;
611 wxMask *mask = GetMask();
612
613 GetGWorld( &origPort, &origDevice );
614 LockPixels(GetGWorldPixMap(GetHBITMAP()));
615 SetGWorld( GetHBITMAP(), NULL);
616
617 // Copy data into image
618 index = 0;
619 for (int yy = 0; yy < height; yy++)
620 {
621 for (int xx = 0; xx < width; xx++)
622 {
623 GetCPixel(xx,yy, &color);
624 r = ((color.red ) >> 8);
625 g = ((color.green ) >> 8);
626 b = ((color.blue ) >> 8);
627 data[index ] = r;
628 data[index + 1] = g;
629 data[index + 2] = b;
630 if (mask)
631 {
632 if (mask->PointMasked(xx,yy))
633 {
634 data[index ] = mask_r;
635 data[index + 1] = mask_g;
636 data[index + 2] = mask_b;
637 }
638 }
639 index += 3;
640 }
641 }
642 if (mask)
643 {
644 image.SetMaskColour( mask_r, mask_g, mask_b );
645 image.SetMask( true );
646 }
647
648 // Free resources
649 UnlockPixels(GetGWorldPixMap(GetHBITMAP()));
650 SetGWorld(origPort, origDevice);
651
652 return image;
653 }
654
655
656 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
657 {
658 wxBitmapHandler *handler = FindHandler(type);
659
660 if ( handler == NULL ) {
661 wxLogWarning("no bitmap handler for type %d defined.", type);
662
663 return FALSE;
664 }
665
666 return handler->SaveFile(this, filename, type, palette);
667 }
668
669 bool wxBitmap::Ok() const
670 {
671 return (M_BITMAPDATA && M_BITMAPDATA->m_ok);
672 }
673
674 int wxBitmap::GetHeight() const
675 {
676 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
677
678 return M_BITMAPDATA->m_height;
679 }
680
681 int wxBitmap::GetWidth() const
682 {
683 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
684
685 return M_BITMAPDATA->m_width;
686 }
687
688 int wxBitmap::GetDepth() const
689 {
690 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
691
692 return M_BITMAPDATA->m_depth;
693 }
694
695 int wxBitmap::GetQuality() const
696 {
697 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
698
699 return M_BITMAPDATA->m_quality;
700 }
701
702 wxMask *wxBitmap::GetMask() const
703 {
704 wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
705
706 return M_BITMAPDATA->m_bitmapMask;
707 }
708
709 void wxBitmap::SetWidth(int w)
710 {
711 if (!M_BITMAPDATA)
712 m_refData = new wxBitmapRefData;
713
714 M_BITMAPDATA->m_width = w;
715 }
716
717 void wxBitmap::SetHeight(int h)
718 {
719 if (!M_BITMAPDATA)
720 m_refData = new wxBitmapRefData;
721
722 M_BITMAPDATA->m_height = h;
723 }
724
725 void wxBitmap::SetDepth(int d)
726 {
727 if (!M_BITMAPDATA)
728 m_refData = new wxBitmapRefData;
729
730 M_BITMAPDATA->m_depth = d;
731 }
732
733 void wxBitmap::SetQuality(int q)
734 {
735 if (!M_BITMAPDATA)
736 m_refData = new wxBitmapRefData;
737
738 M_BITMAPDATA->m_quality = q;
739 }
740
741 void wxBitmap::SetOk(bool isOk)
742 {
743 if (!M_BITMAPDATA)
744 m_refData = new wxBitmapRefData;
745
746 M_BITMAPDATA->m_ok = isOk;
747 }
748
749 wxPalette *wxBitmap::GetPalette() const
750 {
751 wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") );
752
753 return &M_BITMAPDATA->m_bitmapPalette;
754 }
755
756 void wxBitmap::SetPalette(const wxPalette& palette)
757 {
758 if (!M_BITMAPDATA)
759 m_refData = new wxBitmapRefData;
760
761 M_BITMAPDATA->m_bitmapPalette = palette ;
762 }
763
764 void wxBitmap::SetMask(wxMask *mask)
765 {
766 if (!M_BITMAPDATA)
767 m_refData = new wxBitmapRefData;
768
769 M_BITMAPDATA->m_bitmapMask = mask ;
770 }
771
772 WXHBITMAP wxBitmap::GetHBITMAP() const
773 {
774 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
775
776 return M_BITMAPDATA->m_hBitmap;
777 }
778
779 PicHandle wxBitmap::GetPict() const
780 {
781 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
782
783 PicHandle picture; // This is the returned picture
784
785 // If bitmap already in Pict format return pointer
786 if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) {
787 return M_BITMAPDATA->m_hPict;
788 }
789 else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) {
790 // Invalid bitmap
791 return NULL;
792 }
793
794 RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ;
795 RGBColor white = { 0xffff ,0xffff , 0xffff } ;
796 RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ;
797 CGrafPtr origPort;
798 GDHandle origDev ;
799 wxMask *mask;
800 Rect portRect ;
801
802 GetPortBounds( GetHBITMAP() , &portRect ) ;
803 int width = portRect.right - portRect.left ;
804 int height = portRect.bottom - portRect.top ;
805
806 LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
807 GetGWorld( &origPort , &origDev ) ;
808
809 mask = GetMask();
810
811 SetGWorld( GetHBITMAP() , NULL ) ;
812
813 picture = OpenPicture(&portRect); // open a picture, this disables drawing
814 if(!picture) {
815 return NULL;
816 }
817
818 if( mask )
819 {
820 #ifdef __UNIX__
821 RGBColor trans = white;
822 #else
823 RGBBackColor( &gray );
824 EraseRect( &portRect );
825 RGBColor trans = gray;
826 #endif
827 RGBForeColor( &black ) ;
828 RGBBackColor( &white ) ;
829 PenMode(transparent);
830
831 for ( int y = 0 ; y < height ; ++y )
832 {
833 for( int x = 0 ; x < width ; ++x )
834 {
835 if ( !mask->PointMasked(x,y) )
836 {
837 RGBColor col ;
838
839 GetCPixel( x + portRect.left , y + portRect.top , &col ) ;
840 SetCPixel( x + portRect.left , y + portRect.top , &col ) ;
841 }
842 else {
843 // With transparency this sets a blank pixel
844 SetCPixel( x + portRect.left , y + portRect.top , &trans);
845 }
846 }
847 }
848 }
849 else
850 {
851 RGBBackColor( &gray ) ;
852 EraseRect(&portRect);
853 RGBForeColor( &black ) ;
854 RGBBackColor( &white ) ;
855
856 CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),
857 // src PixMap - we copy image over itself -
858 GetPortBitMapForCopyBits(GetHBITMAP()),
859 // dst PixMap - no drawing occurs
860 &portRect, // srcRect - it will be recorded and compressed -
861 &portRect, // dstRect - into the picture that is open -
862 srcCopy,NULL); // copyMode and no clip region
863 }
864 ClosePicture(); // We are done recording the picture
865 UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
866 SetGWorld( origPort , origDev ) ;
867
868 return picture; // return our groovy pict handle
869 }
870
871 void wxBitmap::AddHandler(wxBitmapHandler *handler)
872 {
873 sm_handlers.Append(handler);
874 }
875
876 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
877 {
878 sm_handlers.Insert(handler);
879 }
880
881 bool wxBitmap::RemoveHandler(const wxString& name)
882 {
883 wxBitmapHandler *handler = FindHandler(name);
884 if ( handler )
885 {
886 sm_handlers.DeleteObject(handler);
887 return TRUE;
888 }
889 else
890 return FALSE;
891 }
892
893 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
894 {
895 wxNode *node = sm_handlers.First();
896 while ( node )
897 {
898 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
899 if ( handler->GetName() == name )
900 return handler;
901 node = node->Next();
902 }
903 return NULL;
904 }
905
906 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
907 {
908 wxNode *node = sm_handlers.First();
909 while ( node )
910 {
911 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
912 if ( handler->GetExtension() == extension &&
913 (bitmapType == -1 || handler->GetType() == bitmapType) )
914 return handler;
915 node = node->Next();
916 }
917 return NULL;
918 }
919
920 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
921 {
922 wxNode *node = sm_handlers.First();
923 while ( node )
924 {
925 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
926 if (handler->GetType() == bitmapType)
927 return handler;
928 node = node->Next();
929 }
930 return NULL;
931 }
932
933 /*
934 * wxMask
935 */
936
937 wxMask::wxMask()
938 {
939 m_maskBitmap = 0;
940 }
941
942 // Construct a mask from a bitmap and a colour indicating
943 // the transparent area
944 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
945 {
946 m_maskBitmap = 0;
947 Create(bitmap, colour);
948 }
949
950 // Construct a mask from a bitmap and a palette index indicating
951 // the transparent area
952 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
953 {
954 m_maskBitmap = 0;
955 Create(bitmap, paletteIndex);
956 }
957
958 // Construct a mask from a mono bitmap (copies the bitmap).
959 wxMask::wxMask(const wxBitmap& bitmap)
960 {
961 m_maskBitmap = 0;
962 Create(bitmap);
963 }
964
965 wxMask::~wxMask()
966 {
967 if ( m_maskBitmap )
968 {
969 wxMacDestroyGWorld( m_maskBitmap ) ;
970 m_maskBitmap = NULL ;
971 }
972 }
973
974 // Create a mask from a mono bitmap (copies the bitmap).
975 bool wxMask::Create(const wxBitmap& bitmap)
976 {
977 if ( m_maskBitmap )
978 {
979 wxMacDestroyGWorld( m_maskBitmap ) ;
980 m_maskBitmap = NULL ;
981 }
982 wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
983 wxT("Cannot create mask from this bitmap type (TODO)"));
984 // other types would require a temporary bitmap. not yet implemented
985
986 wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap"));
987
988 wxCHECK_MSG(bitmap.GetDepth() == 1, false,
989 wxT("Cannot create mask from colour bitmap"));
990
991 m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), 1);
992 Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
993
994 LockPixels( GetGWorldPixMap(m_maskBitmap) );
995 LockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) );
996 CopyBits(GetPortBitMapForCopyBits(bitmap.GetHBITMAP()),
997 GetPortBitMapForCopyBits(m_maskBitmap),
998 &rect, &rect, srcCopy, 0);
999 UnlockPixels( GetGWorldPixMap(m_maskBitmap) );
1000 UnlockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) );
1001
1002 return FALSE;
1003 }
1004
1005 // Create a mask from a bitmap and a palette index indicating
1006 // the transparent area
1007 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
1008 {
1009 // TODO
1010 wxCHECK_MSG( 0, false, wxT("Not implemented"));
1011 return FALSE;
1012 }
1013
1014 // Create a mask from a bitmap and a colour indicating
1015 // the transparent area
1016 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
1017 {
1018 if ( m_maskBitmap )
1019 {
1020 wxMacDestroyGWorld( m_maskBitmap ) ;
1021 m_maskBitmap = NULL ;
1022 }
1023 wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
1024 wxT("Cannot create mask from this bitmap type (TODO)"));
1025 // other types would require a temporary bitmap. not yet implemented
1026
1027 wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap"));
1028
1029 m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 );
1030 LockPixels( GetGWorldPixMap( m_maskBitmap ) );
1031 LockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) );
1032 RGBColor maskColor = colour.GetPixel();
1033
1034 // this is not very efficient, but I can't think
1035 // of a better way of doing it
1036 CGrafPtr origPort ;
1037 GDHandle origDevice ;
1038 RGBColor col;
1039 RGBColor colors[2] = {
1040 { 0xFFFF, 0xFFFF, 0xFFFF },
1041 { 0, 0, 0 }};
1042
1043 GetGWorld( &origPort , &origDevice ) ;
1044 for (int w = 0; w < bitmap.GetWidth(); w++)
1045 {
1046 for (int h = 0; h < bitmap.GetHeight(); h++)
1047 {
1048 SetGWorld( bitmap.GetHBITMAP(), NULL ) ;
1049 GetCPixel( w , h , &col ) ;
1050 SetGWorld( m_maskBitmap , NULL ) ;
1051 if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue)
1052 {
1053 SetCPixel( w , h , &colors[0] ) ;
1054 }
1055 else
1056 {
1057 SetCPixel( w , h , &colors[1] ) ;
1058 }
1059 }
1060 }
1061 UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
1062 UnlockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ) ;
1063 SetGWorld( origPort , origDevice ) ;
1064
1065 return TRUE;
1066 }
1067
1068 bool wxMask::PointMasked(int x, int y)
1069 {
1070 WXHBITMAP origPort;
1071 GDHandle origDevice;
1072 RGBColor color;
1073 bool masked = true;
1074
1075 GetGWorld( &origPort, &origDevice);
1076
1077 //Set port to mask and see if it masked (1) or not ( 0 )
1078 SetGWorld(m_maskBitmap, NULL);
1079 LockPixels(GetGWorldPixMap(m_maskBitmap));
1080 GetCPixel(x,y, &color);
1081 masked = !(color.red == 0 && color.green == 0 && color.blue == 0);
1082 UnlockPixels(GetGWorldPixMap(m_maskBitmap));
1083
1084 SetGWorld( origPort, origDevice);
1085
1086 return masked;
1087 }
1088
1089 /*
1090 * wxBitmapHandler
1091 */
1092
1093 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
1094
1095 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
1096 {
1097 return FALSE;
1098 }
1099
1100 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
1101 int desiredWidth, int desiredHeight)
1102 {
1103 return FALSE;
1104 }
1105
1106 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
1107 {
1108 return FALSE;
1109 }
1110
1111 /*
1112 * Standard handlers
1113 */
1114
1115 class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
1116 {
1117 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
1118 public:
1119 inline wxPICTResourceHandler()
1120 {
1121 m_name = "Macintosh Pict resource";
1122 m_extension = "";
1123 m_type = wxBITMAP_TYPE_PICT_RESOURCE;
1124 };
1125
1126 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1127 int desiredWidth, int desiredHeight);
1128 };
1129 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
1130
1131 bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1132 int desiredWidth, int desiredHeight)
1133 {
1134 Str255 theName ;
1135
1136 #if TARGET_CARBON
1137 c2pstrcpy( (StringPtr) theName , name ) ;
1138 #else
1139 strcpy( (char *) theName , name ) ;
1140 c2pstr( (char *)theName ) ;
1141 #endif
1142
1143 PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
1144 if ( thePict )
1145 {
1146 PictInfo theInfo ;
1147
1148 GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
1149 DetachResource( (Handle) thePict ) ;
1150 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
1151 M_BITMAPHANDLERDATA->m_hPict = thePict ;
1152 M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
1153 M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
1154
1155 M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
1156 M_BITMAPHANDLERDATA->m_ok = true ;
1157 M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
1158 // M_BITMAPHANDLERDATA->m_bitmapPalette;
1159 // M_BITMAPHANDLERDATA->m_quality;
1160 return TRUE ;
1161 }
1162 return FALSE ;
1163 }
1164
1165 /* TODO: bitmap handlers, a bit like this:
1166 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1167 {
1168 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1169 public:
1170 inline wxBMPResourceHandler()
1171 {
1172 m_name = "Windows bitmap resource";
1173 m_extension = "";
1174 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
1175 };
1176
1177 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1178 int desiredWidth, int desiredHeight);
1179 };
1180 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1181 */
1182
1183 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
1184 {
1185 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
1186 public:
1187 inline wxXPMFileHandler(void)
1188 {
1189 m_name = "XPM bitmap file";
1190 m_extension = "xpm";
1191 m_type = wxBITMAP_TYPE_XPM;
1192 };
1193
1194 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1195 int desiredWidth = -1, int desiredHeight = -1);
1196 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
1197 };
1198 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
1199
1200 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1201 int desiredWidth, int desiredHeight)
1202 {
1203 #if USE_XPM_IN_MSW
1204 XImage *ximage;
1205 XpmAttributes xpmAttr;
1206 HDC dc;
1207
1208 M_BITMAPHANDLERDATA->m_ok = FALSE;
1209 dc = CreateCompatibleDC(NULL);
1210 if (dc)
1211 {
1212 xpmAttr.valuemask = XpmReturnPixels;
1213 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
1214 DeleteDC(dc);
1215 if (errorStatus == XpmSuccess)
1216 {
1217 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
1218
1219 BITMAP bm;
1220 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
1221
1222 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
1223 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
1224 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
1225 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
1226 XpmFreeAttributes(&xpmAttr);
1227 XImageFree(ximage);
1228
1229 M_BITMAPHANDLERDATA->m_ok = TRUE;
1230 return TRUE;
1231 }
1232 else
1233 {
1234 M_BITMAPHANDLERDATA->m_ok = FALSE;
1235 return FALSE;
1236 }
1237 }
1238 #endif
1239
1240 return FALSE;
1241 }
1242
1243 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
1244 {
1245 #if USE_XPM_IN_MSW
1246 HDC dc = NULL;
1247
1248 Visual *visual = NULL;
1249 XImage ximage;
1250
1251 dc = CreateCompatibleDC(NULL);
1252 if (dc)
1253 {
1254 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
1255 {
1256
1257 ximage.width = M_BITMAPHANDLERDATA->m_width;
1258 ximage.height = M_BITMAPHANDLERDATA->m_height;
1259 ximage.depth = M_BITMAPHANDLERDATA->m_depth;
1260 ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap;
1261 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
1262 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
1263
1264 if (dc)
1265 DeleteDC(dc);
1266
1267 if (errorStatus == XpmSuccess)
1268 return TRUE;
1269 else
1270 return FALSE;
1271 } else return FALSE;
1272 } else return FALSE;
1273 #else
1274 return FALSE;
1275 #endif
1276 }
1277
1278
1279 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
1280 {
1281 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
1282 public:
1283 inline wxXPMDataHandler(void)
1284 {
1285 m_name = "XPM bitmap data";
1286 m_extension = "xpm";
1287 m_type = wxBITMAP_TYPE_XPM_DATA;
1288 };
1289
1290 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
1291 };
1292 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
1293
1294 bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
1295 {
1296 XImage * ximage = NULL ;
1297 XImage * xshapeimage = NULL ;
1298 int ErrorStatus;
1299 XpmAttributes xpmAttr;
1300
1301 xpmAttr.valuemask = XpmReturnInfos; // get infos back
1302 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
1303 &ximage, &xshapeimage, &xpmAttr);
1304
1305 if (ErrorStatus == XpmSuccess)
1306 {
1307 M_BITMAPHANDLERDATA->m_ok = FALSE;
1308 M_BITMAPHANDLERDATA->m_numColors = 0;
1309 M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ;
1310
1311 M_BITMAPHANDLERDATA->m_width = ximage->width;
1312 M_BITMAPHANDLERDATA->m_height = ximage->height;
1313 M_BITMAPHANDLERDATA->m_depth = ximage->depth;
1314 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
1315 XpmFreeAttributes(&xpmAttr);
1316 M_BITMAPHANDLERDATA->m_ok = TRUE;
1317 ximage->gworldptr = NULL ;
1318 XImageFree(ximage); // releases the malloc, but does not detroy
1319 // the bitmap
1320 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
1321 if ( xshapeimage != NULL )
1322 {
1323 wxMask* m = new wxMask() ;
1324 m->SetMaskBitmap( xshapeimage->gworldptr ) ;
1325 M_BITMAPHANDLERDATA->m_bitmapMask = m ;
1326 }
1327 return TRUE;
1328 }
1329 else
1330 {
1331 M_BITMAPHANDLERDATA->m_ok = FALSE;
1332 return FALSE;
1333 }
1334 return FALSE;
1335 }
1336
1337 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1338 {
1339 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1340 public:
1341 inline wxBMPResourceHandler()
1342 {
1343 m_name = "Windows bitmap resource";
1344 m_extension = "";
1345 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
1346 };
1347
1348 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1349 int desiredWidth, int desiredHeight);
1350 };
1351
1352 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1353
1354 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1355 int desiredWidth, int desiredHeight)
1356 {
1357 // TODO: load colourmap.
1358 // it's probably not found
1359 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
1360
1361 return FALSE;
1362 }
1363
1364 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
1365 {
1366 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
1367 public:
1368 inline wxBMPFileHandler(void)
1369 {
1370 m_name = "Windows bitmap file";
1371 m_extension = "bmp";
1372 m_type = wxBITMAP_TYPE_BMP;
1373 };
1374
1375 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1376 int desiredWidth, int desiredHeight);
1377 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
1378 };
1379
1380 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
1381
1382 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1383 int desiredWidth, int desiredHeight)
1384 {
1385 #if USE_IMAGE_LOADING_IN_MSW
1386 wxPalette *palette = NULL;
1387 bool success = FALSE;
1388 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
1389 if (!success && palette)
1390 {
1391 delete palette;
1392 palette = NULL;
1393 }
1394 if (palette)
1395 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
1396 return success;
1397 #else
1398 return FALSE;
1399 #endif
1400 }
1401
1402 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
1403 {
1404 #if USE_IMAGE_LOADING_IN_MSW
1405 wxPalette *actualPalette = (wxPalette *)pal;
1406 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
1407 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
1408 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
1409 #else
1410 return FALSE;
1411 #endif
1412 }
1413
1414
1415 void wxBitmap::CleanUpHandlers()
1416 {
1417 wxNode *node = sm_handlers.First();
1418 while ( node )
1419 {
1420 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
1421 wxNode *next = node->Next();
1422 delete handler;
1423 delete node;
1424 node = next;
1425 }
1426 }
1427
1428 void wxBitmap::InitStandardHandlers()
1429 {
1430 AddHandler( new wxPICTResourceHandler ) ;
1431 AddHandler( new wxICONResourceHandler ) ;
1432 AddHandler(new wxXPMFileHandler);
1433 AddHandler(new wxXPMDataHandler);
1434 AddHandler(new wxBMPResourceHandler);
1435 AddHandler(new wxBMPFileHandler);
1436 }