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