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