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