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