]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/bitmap.cpp
removed duplicated friend declaration
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
CommitLineData
e9576ca5
SC
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
03e11df5 16#include "wx/wx.h"
e9576ca5
SC
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"
fec19ea9 23#include "wx/image.h"
e9576ca5 24
519cb848
SC
25extern "C"
26{
03e11df5
GD
27#ifdef __UNIX__
28 #include "xpm/xpm.h"
29#else
519cb848 30 #include "xpm.h"
03e11df5 31#endif
519cb848
SC
32} ;
33
2f1ae414 34#if !USE_SHARED_LIBRARIES
e9576ca5
SC
35IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
36IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
2f1ae414 37#endif
e9576ca5 38
03e11df5 39#ifdef __UNIX__
5fde6fcc 40 #include <ApplicationServices/ApplicationServices.h>
03e11df5
GD
41#else
42 #include <PictUtils.h>
43#endif
519cb848 44
31d30995
SC
45#include "wx/mac/uma.h"
46
519cb848
SC
47CTabHandle wxMacCreateColorTable( int numColors )
48{
49 CTabHandle newColors; /* Handle to the new color table */
03e11df5 50
519cb848
SC
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
65void wxMacDestroyColorTable( CTabHandle colors )
66{
67 DisposeHandle( (Handle) colors ) ;
68}
69
70void 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
03e11df5 78GWorldPtr wxMacCreateGWorld( int width , int height , int depth )
519cb848
SC
79{
80 OSErr err = noErr ;
81 GWorldPtr port ;
03e11df5 82 Rect rect = { 0 , 0 , height , width } ;
519cb848
SC
83
84 if ( depth < 0 )
85 {
2f1ae414 86 depth = wxDisplayDepth() ;
519cb848
SC
87 }
88
89 err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
90 if ( err == noErr )
91 {
92 return port ;
93 }
94 return NULL ;
03e11df5 95}
519cb848
SC
96
97void wxMacDestroyGWorld( GWorldPtr gw )
98{
99 if ( gw )
100 DisposeGWorld( gw ) ;
101}
102
5fde6fcc
GD
103PicHandle 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
e9576ca5
SC
194wxBitmapRefData::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;
519cb848
SC
203 m_hBitmap = NULL ;
204 m_hPict = NULL ;
205 m_bitmapType = kMacBitmapTypeUnknownType ;
e9576ca5
SC
206}
207
208wxBitmapRefData::~wxBitmapRefData()
209{
519cb848
SC
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 ;
03e11df5 233 }
519cb848
SC
234
235 if (m_bitmapMask)
236 {
237 delete m_bitmapMask;
e9576ca5 238 m_bitmapMask = NULL;
519cb848 239 }
e9576ca5
SC
240}
241
242wxList wxBitmap::sm_handlers;
243
244wxBitmap::wxBitmap()
245{
246 m_refData = NULL;
247
248 if ( wxTheBitmapList )
249 wxTheBitmapList->AddBitmap(this);
250}
251
252wxBitmap::~wxBitmap()
253{
254 if (wxTheBitmapList)
255 wxTheBitmapList->DeleteObject(this);
256}
257
258wxBitmap::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;
d2c6d549
GD
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 ) ;
519cb848 271
d2c6d549
GD
272 CGrafPtr origPort ;
273 GDHandle origDevice ;
519cb848 274
d2c6d549
GD
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 ) {
e9576ca5 320 wxTheBitmapList->AddBitmap(this);
d2c6d549 321 }
e9576ca5
SC
322}
323
324wxBitmap::wxBitmap(int w, int h, int d)
325{
326 (void)Create(w, h, d);
327
328 if ( wxTheBitmapList )
329 wxTheBitmapList->AddBitmap(this);
330}
331
332wxBitmap::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
340wxBitmap::wxBitmap(const wxString& filename, long type)
341{
342 LoadFile(filename, (int)type);
343
344 if ( wxTheBitmapList )
345 wxTheBitmapList->AddBitmap(this);
346}
347
e9576ca5
SC
348wxBitmap::wxBitmap(const char **data)
349{
350 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
351}
e9576ca5 352
03e11df5
GD
353wxBitmap::wxBitmap(char **data)
354{
355 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
356}
357
5fde6fcc
GD
358wxBitmap 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
e9576ca5
SC
447bool 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
519cb848
SC
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 ) ;
e9576ca5
SC
460 return M_BITMAPDATA->m_ok;
461}
462
5fde6fcc
GD
463int wxBitmap::GetBitmapType() const
464{
465 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType, wxT("invalid bitmap") );
466
467 return M_BITMAPDATA->m_bitmapType;
468}
469
519cb848
SC
470void 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
e9576ca5
SC
477bool 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
494bool 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
fec19ea9
VS
511wxBitmap::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
578wxImage 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
e9576ca5
SC
645bool 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
5fde6fcc
GD
658bool wxBitmap::Ok() const
659{
660 return (M_BITMAPDATA && M_BITMAPDATA->m_ok);
661}
662
663int wxBitmap::GetHeight() const
664{
665 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
666
667 return M_BITMAPDATA->m_height;
668}
669
670int wxBitmap::GetWidth() const
671{
672 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
673
674 return M_BITMAPDATA->m_width;
675}
676
677int wxBitmap::GetDepth() const
678{
679 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
680
681 return M_BITMAPDATA->m_depth;
682}
683
684int wxBitmap::GetQuality() const
685{
686 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
687
688 return M_BITMAPDATA->m_quality;
689}
690
691wxMask *wxBitmap::GetMask() const
692{
693 wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
694
695 return M_BITMAPDATA->m_bitmapMask;
696}
697
e9576ca5
SC
698void wxBitmap::SetWidth(int w)
699{
700 if (!M_BITMAPDATA)
701 m_refData = new wxBitmapRefData;
702
703 M_BITMAPDATA->m_width = w;
704}
705
706void wxBitmap::SetHeight(int h)
707{
708 if (!M_BITMAPDATA)
709 m_refData = new wxBitmapRefData;
710
711 M_BITMAPDATA->m_height = h;
712}
713
714void wxBitmap::SetDepth(int d)
715{
716 if (!M_BITMAPDATA)
717 m_refData = new wxBitmapRefData;
718
719 M_BITMAPDATA->m_depth = d;
720}
721
722void wxBitmap::SetQuality(int q)
723{
724 if (!M_BITMAPDATA)
725 m_refData = new wxBitmapRefData;
726
727 M_BITMAPDATA->m_quality = q;
728}
729
730void wxBitmap::SetOk(bool isOk)
731{
732 if (!M_BITMAPDATA)
733 m_refData = new wxBitmapRefData;
734
735 M_BITMAPDATA->m_ok = isOk;
736}
737
5fde6fcc
GD
738wxPalette *wxBitmap::GetPalette() const
739{
740 wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") );
741
742 return &M_BITMAPDATA->m_bitmapPalette;
743}
744
e9576ca5
SC
745void wxBitmap::SetPalette(const wxPalette& palette)
746{
747 if (!M_BITMAPDATA)
748 m_refData = new wxBitmapRefData;
749
750 M_BITMAPDATA->m_bitmapPalette = palette ;
751}
752
753void wxBitmap::SetMask(wxMask *mask)
754{
755 if (!M_BITMAPDATA)
756 m_refData = new wxBitmapRefData;
757
758 M_BITMAPDATA->m_bitmapMask = mask ;
759}
760
5fde6fcc
GD
761WXHBITMAP wxBitmap::GetHBITMAP() const
762{
763 wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
764
765 return M_BITMAPDATA->m_hBitmap;
766}
767
768PicHandle 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
e9576ca5
SC
860void wxBitmap::AddHandler(wxBitmapHandler *handler)
861{
862 sm_handlers.Append(handler);
863}
864
865void wxBitmap::InsertHandler(wxBitmapHandler *handler)
866{
867 sm_handlers.Insert(handler);
868}
869
870bool 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
882wxBitmapHandler *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
895wxBitmapHandler *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
909wxBitmapHandler *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
926wxMask::wxMask()
927{
e9576ca5 928 m_maskBitmap = 0;
e9576ca5
SC
929}
930
931// Construct a mask from a bitmap and a colour indicating
932// the transparent area
933wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
934{
e9576ca5 935 m_maskBitmap = 0;
e9576ca5
SC
936 Create(bitmap, colour);
937}
938
939// Construct a mask from a bitmap and a palette index indicating
940// the transparent area
941wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
942{
e9576ca5 943 m_maskBitmap = 0;
e9576ca5
SC
944 Create(bitmap, paletteIndex);
945}
946
947// Construct a mask from a mono bitmap (copies the bitmap).
948wxMask::wxMask(const wxBitmap& bitmap)
949{
e9576ca5 950 m_maskBitmap = 0;
e9576ca5
SC
951 Create(bitmap);
952}
953
954wxMask::~wxMask()
955{
8208e181
SC
956 if ( m_maskBitmap )
957 {
958 wxMacDestroyGWorld( m_maskBitmap ) ;
959 m_maskBitmap = NULL ;
960 }
e9576ca5
SC
961}
962
963// Create a mask from a mono bitmap (copies the bitmap).
964bool wxMask::Create(const wxBitmap& bitmap)
965{
5fde6fcc
GD
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;
e9576ca5
SC
992}
993
994// Create a mask from a bitmap and a palette index indicating
995// the transparent area
996bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
997{
998// TODO
5fde6fcc 999 wxCHECK_MSG( 0, false, wxT("Not implemented"));
e9576ca5
SC
1000 return FALSE;
1001}
1002
1003// Create a mask from a bitmap and a colour indicating
1004// the transparent area
1005bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
1006{
8208e181
SC
1007 if ( m_maskBitmap )
1008 {
1009 wxMacDestroyGWorld( m_maskBitmap ) ;
1010 m_maskBitmap = NULL ;
1011 }
5fde6fcc
GD
1012 wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
1013 wxT("Cannot create mask from this bitmap type (TODO)"));
8208e181
SC
1014 // other types would require a temporary bitmap. not yet implemented
1015
5fde6fcc 1016 wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap"));
8208e181 1017
5fde6fcc
GD
1018 m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 );
1019 LockPixels( GetGWorldPixMap( m_maskBitmap ) );
1020 LockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) );
1021 RGBColor maskColor = colour.GetPixel();
8208e181
SC
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 ;
5fde6fcc
GD
1027 RGBColor col;
1028 RGBColor colors[2] = {
1029 { 0xFFFF, 0xFFFF, 0xFFFF },
1030 { 0, 0, 0 }};
8208e181
SC
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 {
5fde6fcc 1037 SetGWorld( bitmap.GetHBITMAP(), NULL ) ;
8208e181
SC
1038 GetCPixel( w , h , &col ) ;
1039 SetGWorld( m_maskBitmap , NULL ) ;
5fde6fcc 1040 if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue)
8208e181
SC
1041 {
1042 SetCPixel( w , h , &colors[0] ) ;
1043 }
1044 else
1045 {
1046 SetCPixel( w , h , &colors[1] ) ;
1047 }
1048 }
1049 }
2f1ae414 1050 UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
5fde6fcc 1051 UnlockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ) ;
8208e181
SC
1052 SetGWorld( origPort , origDevice ) ;
1053
1054 return TRUE;
e9576ca5
SC
1055}
1056
5fde6fcc
GD
1057bool 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
e9576ca5
SC
1078/*
1079 * wxBitmapHandler
1080 */
1081
1082IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
1083
1084bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
1085{
1086 return FALSE;
1087}
1088
1089bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
1090 int desiredWidth, int desiredHeight)
1091{
1092 return FALSE;
1093}
1094
1095bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
1096{
1097 return FALSE;
1098}
1099
1100/*
1101 * Standard handlers
1102 */
1103
519cb848
SC
1104class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
1105{
1106 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
1107public:
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};
1118IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
1119
1120bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1121 int desiredWidth, int desiredHeight)
1122{
1123 Str255 theName ;
1124
03e11df5
GD
1125#if TARGET_CARBON
1126 c2pstrcpy( (StringPtr) theName , name ) ;
1127#else
1128 strcpy( (char *) theName , name ) ;
1129 c2pstr( (char *)theName ) ;
1130#endif
519cb848
SC
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
e9576ca5
SC
1154/* TODO: bitmap handlers, a bit like this:
1155class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1156{
1157 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1158public:
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};
1169IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1170*/
1171
519cb848
SC
1172class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
1173{
1174 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
1175public:
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};
1187IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
1188
1189bool 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
1232bool 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))
2f1ae414
SC
1244 {
1245
519cb848
SC
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)
2f1ae414 1257 return TRUE;
519cb848
SC
1258 else
1259 return FALSE;
1260 } else return FALSE;
1261 } else return FALSE;
1262#else
1263 return FALSE;
1264#endif
1265}
1266
1267
1268class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
1269{
1270 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
1271public:
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};
1281IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
1282
1283bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
1284{
a959b088
SC
1285 XImage * ximage = NULL ;
1286 XImage * xshapeimage = NULL ;
519cb848
SC
1287 int ErrorStatus;
1288 XpmAttributes xpmAttr;
1289
1290 xpmAttr.valuemask = XpmReturnInfos; // get infos back
1291 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
a959b088 1292 &ximage, &xshapeimage, &xpmAttr);
519cb848
SC
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 ;
a959b088
SC
1310 if ( xshapeimage != NULL )
1311 {
1312 wxMask* m = new wxMask() ;
1313 m->SetMaskBitmap( xshapeimage->gworldptr ) ;
1314 M_BITMAPHANDLERDATA->m_bitmapMask = m ;
1315 }
519cb848
SC
1316 return TRUE;
1317 }
1318 else
1319 {
1320 M_BITMAPHANDLERDATA->m_ok = FALSE;
1321 return FALSE;
1322 }
1323 return FALSE;
1324}
1325
1326class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1327{
1328 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1329public:
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
1341IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1342
1343bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1344 int desiredWidth, int desiredHeight)
1345{
1346 // TODO: load colourmap.
519cb848
SC
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
1353class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
1354{
1355 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
1356public:
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
1369IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
1370
1371bool 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;
519cb848
SC
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
1391bool 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
e9576ca5
SC
1404void 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
1417void wxBitmap::InitStandardHandlers()
1418{
519cb848
SC
1419 AddHandler( new wxPICTResourceHandler ) ;
1420 AddHandler( new wxICONResourceHandler ) ;
1421 AddHandler(new wxXPMFileHandler);
2f1ae414 1422 AddHandler(new wxXPMDataHandler);
519cb848
SC
1423 AddHandler(new wxBMPResourceHandler);
1424 AddHandler(new wxBMPFileHandler);
e9576ca5 1425}