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