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