]> git.saurik.com Git - wxWidgets.git/blame - src/mac/bitmap.cpp
fixed incorrect GetTextExtent for wxTELETYPE font
[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
16#include "wx/setup.h"
17#include "wx/utils.h"
18#include "wx/palette.h"
19#include "wx/bitmap.h"
20#include "wx/icon.h"
21#include "wx/log.h"
22
519cb848
SC
23extern "C"
24{
25 #include "xpm.h"
26} ;
27
2f1ae414 28#if !USE_SHARED_LIBRARIES
e9576ca5
SC
29IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
30IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
2f1ae414 31#endif
e9576ca5 32
519cb848
SC
33#include <PictUtils.h>
34
35CTabHandle wxMacCreateColorTable( int numColors )
36{
37 CTabHandle newColors; /* Handle to the new color table */
38 short index; /* Index into the table of colors */
39 /* Allocate memory for the color table */
40 newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) +
41 sizeof (ColorSpec) * (numColors - 1) );
42 if (newColors != nil)
43 {
44 /* Initialize the fields */
45 (**newColors).ctSeed = GetCTSeed();
46 (**newColors).ctFlags = 0;
47 (**newColors).ctSize = numColors - 1;
48 /* Initialize the table of colors */
49 }
50 return newColors ;
51}
52
53void wxMacDestroyColorTable( CTabHandle colors )
54{
55 DisposeHandle( (Handle) colors ) ;
56}
57
58void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue )
59{
60 (**newColors).ctTable[index].value = index;
61 (**newColors).ctTable[index].rgb.red = 0 ;// someRedValue;
62 (**newColors).ctTable[index].rgb.green = 0 ; // someGreenValue;
63 (**newColors).ctTable[index].rgb.blue = 0 ; // someBlueValue;
64}
65
66GWorldPtr wxMacCreateGWorld( int height , int width , int depth )
67{
68 OSErr err = noErr ;
69 GWorldPtr port ;
70 Rect rect = { 0 , 0 , width , height } ;
71
72 if ( depth < 0 )
73 {
2f1ae414 74 depth = wxDisplayDepth() ;
519cb848
SC
75 }
76
77 err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
78 if ( err == noErr )
79 {
80 return port ;
81 }
82 return NULL ;
83}
84
85void wxMacDestroyGWorld( GWorldPtr gw )
86{
87 if ( gw )
88 DisposeGWorld( gw ) ;
89}
90
e9576ca5
SC
91wxBitmapRefData::wxBitmapRefData()
92{
93 m_ok = FALSE;
94 m_width = 0;
95 m_height = 0;
96 m_depth = 0;
97 m_quality = 0;
98 m_numColors = 0;
99 m_bitmapMask = NULL;
519cb848
SC
100 m_hBitmap = NULL ;
101 m_hPict = NULL ;
102 m_bitmapType = kMacBitmapTypeUnknownType ;
e9576ca5
SC
103}
104
105wxBitmapRefData::~wxBitmapRefData()
106{
519cb848
SC
107 switch (m_bitmapType)
108 {
109 case kMacBitmapTypePict :
110 {
111 if ( m_hPict )
112 {
113 KillPicture( m_hPict ) ;
114 m_hPict = NULL ;
115 }
116 }
117 break ;
118 case kMacBitmapTypeGrafWorld :
119 {
120 if ( m_hBitmap )
121 {
122 wxMacDestroyGWorld( m_hBitmap ) ;
123 m_hBitmap = NULL ;
124 }
125 }
126 break ;
127 default :
128 // unkown type ?
129 break ;
130 } ;
131
132 if (m_bitmapMask)
133 {
134 delete m_bitmapMask;
e9576ca5 135 m_bitmapMask = NULL;
519cb848 136 }
e9576ca5
SC
137}
138
139wxList wxBitmap::sm_handlers;
140
141wxBitmap::wxBitmap()
142{
143 m_refData = NULL;
144
145 if ( wxTheBitmapList )
146 wxTheBitmapList->AddBitmap(this);
147}
148
149wxBitmap::~wxBitmap()
150{
151 if (wxTheBitmapList)
152 wxTheBitmapList->DeleteObject(this);
153}
154
155wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
156{
157 m_refData = new wxBitmapRefData;
158
159 M_BITMAPDATA->m_width = the_width ;
160 M_BITMAPDATA->m_height = the_height ;
161 M_BITMAPDATA->m_depth = no_bits ;
162 M_BITMAPDATA->m_numColors = 0;
519cb848
SC
163 if ( no_bits == 1 )
164 {
165 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
166 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
167 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
168
169 CGrafPtr origPort ;
170 GDHandle origDevice ;
171
172 GetGWorld( &origPort , &origDevice ) ;
173 SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ;
2f1ae414
SC
174 LockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
175
519cb848
SC
176 // bits is a word aligned array
177
178 unsigned char* linestart = (unsigned char*) bits ;
179 int linesize = ( the_width / 16 ) * 2 ;
180 if ( the_width % 16 )
181 {
182 linesize += 2 ;
183 } ;
184
185 RGBColor colors[2] = {
186 { 0xFFFF , 0xFFFF , 0xFFFF } ,
187 { 0, 0 , 0 }
188 } ;
189
190 for( int y = 0 ; y < the_height ; ++y , linestart += linesize )
191 {
192 for( int x = 0 ; x < the_width ; ++x )
193 {
194 int index = x / 8 ;
195 int bit = x % 8 ;
196 int mask = 1 << bit ;
197 if ( linestart[index] & mask )
198 {
199 SetCPixel( x , y , &colors[1] ) ;
200 }
201 else
202 {
203 SetCPixel( x , y , &colors[0] ) ;
204 }
205 }
206
207 }
2f1ae414 208 UnlockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
519cb848
SC
209
210 SetGWorld( origPort , origDevice ) ;
211 }
212 else
213 {
214 //multicolor BITMAPs not yet implemented
215 }
e9576ca5
SC
216
217 if ( wxTheBitmapList )
218 wxTheBitmapList->AddBitmap(this);
219}
220
221wxBitmap::wxBitmap(int w, int h, int d)
222{
223 (void)Create(w, h, d);
224
225 if ( wxTheBitmapList )
226 wxTheBitmapList->AddBitmap(this);
227}
228
229wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
230{
231 (void) Create(data, type, width, height, depth);
232
233 if ( wxTheBitmapList )
234 wxTheBitmapList->AddBitmap(this);
235}
236
237wxBitmap::wxBitmap(const wxString& filename, long type)
238{
239 LoadFile(filename, (int)type);
240
241 if ( wxTheBitmapList )
242 wxTheBitmapList->AddBitmap(this);
243}
244
e9576ca5
SC
245wxBitmap::wxBitmap(const char **data)
246{
247 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
248}
e9576ca5
SC
249
250bool wxBitmap::Create(int w, int h, int d)
251{
252 UnRef();
253
254 m_refData = new wxBitmapRefData;
255
256 M_BITMAPDATA->m_width = w;
257 M_BITMAPDATA->m_height = h;
258 M_BITMAPDATA->m_depth = d;
259
519cb848
SC
260 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
261 M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ;
262 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
e9576ca5
SC
263 return M_BITMAPDATA->m_ok;
264}
265
519cb848
SC
266void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
267{
268 M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
269 M_BITMAPDATA->m_hBitmap = bmp ;
270 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ;
271}
272
e9576ca5
SC
273bool wxBitmap::LoadFile(const wxString& filename, long type)
274{
275 UnRef();
276
277 m_refData = new wxBitmapRefData;
278
279 wxBitmapHandler *handler = FindHandler(type);
280
281 if ( handler == NULL ) {
282 wxLogWarning("no bitmap handler for type %d defined.", type);
283
284 return FALSE;
285 }
286
287 return handler->LoadFile(this, filename, type, -1, -1);
288}
289
290bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
291{
292 UnRef();
293
294 m_refData = new wxBitmapRefData;
295
296 wxBitmapHandler *handler = FindHandler(type);
297
298 if ( handler == NULL ) {
299 wxLogWarning("no bitmap handler for type %d defined.", type);
300
301 return FALSE;
302 }
303
304 return handler->Create(this, data, type, width, height, depth);
305}
306
307bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
308{
309 wxBitmapHandler *handler = FindHandler(type);
310
311 if ( handler == NULL ) {
312 wxLogWarning("no bitmap handler for type %d defined.", type);
313
314 return FALSE;
315 }
316
317 return handler->SaveFile(this, filename, type, palette);
318}
319
320void wxBitmap::SetWidth(int w)
321{
322 if (!M_BITMAPDATA)
323 m_refData = new wxBitmapRefData;
324
325 M_BITMAPDATA->m_width = w;
326}
327
328void wxBitmap::SetHeight(int h)
329{
330 if (!M_BITMAPDATA)
331 m_refData = new wxBitmapRefData;
332
333 M_BITMAPDATA->m_height = h;
334}
335
336void wxBitmap::SetDepth(int d)
337{
338 if (!M_BITMAPDATA)
339 m_refData = new wxBitmapRefData;
340
341 M_BITMAPDATA->m_depth = d;
342}
343
344void wxBitmap::SetQuality(int q)
345{
346 if (!M_BITMAPDATA)
347 m_refData = new wxBitmapRefData;
348
349 M_BITMAPDATA->m_quality = q;
350}
351
352void wxBitmap::SetOk(bool isOk)
353{
354 if (!M_BITMAPDATA)
355 m_refData = new wxBitmapRefData;
356
357 M_BITMAPDATA->m_ok = isOk;
358}
359
360void wxBitmap::SetPalette(const wxPalette& palette)
361{
362 if (!M_BITMAPDATA)
363 m_refData = new wxBitmapRefData;
364
365 M_BITMAPDATA->m_bitmapPalette = palette ;
366}
367
368void wxBitmap::SetMask(wxMask *mask)
369{
370 if (!M_BITMAPDATA)
371 m_refData = new wxBitmapRefData;
372
373 M_BITMAPDATA->m_bitmapMask = mask ;
374}
375
376void wxBitmap::AddHandler(wxBitmapHandler *handler)
377{
378 sm_handlers.Append(handler);
379}
380
381void wxBitmap::InsertHandler(wxBitmapHandler *handler)
382{
383 sm_handlers.Insert(handler);
384}
385
386bool wxBitmap::RemoveHandler(const wxString& name)
387{
388 wxBitmapHandler *handler = FindHandler(name);
389 if ( handler )
390 {
391 sm_handlers.DeleteObject(handler);
392 return TRUE;
393 }
394 else
395 return FALSE;
396}
397
398wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
399{
400 wxNode *node = sm_handlers.First();
401 while ( node )
402 {
403 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
404 if ( handler->GetName() == name )
405 return handler;
406 node = node->Next();
407 }
408 return NULL;
409}
410
411wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
412{
413 wxNode *node = sm_handlers.First();
414 while ( node )
415 {
416 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
417 if ( handler->GetExtension() == extension &&
418 (bitmapType == -1 || handler->GetType() == bitmapType) )
419 return handler;
420 node = node->Next();
421 }
422 return NULL;
423}
424
425wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
426{
427 wxNode *node = sm_handlers.First();
428 while ( node )
429 {
430 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
431 if (handler->GetType() == bitmapType)
432 return handler;
433 node = node->Next();
434 }
435 return NULL;
436}
437
438/*
439 * wxMask
440 */
441
442wxMask::wxMask()
443{
e9576ca5 444 m_maskBitmap = 0;
e9576ca5
SC
445}
446
447// Construct a mask from a bitmap and a colour indicating
448// the transparent area
449wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
450{
e9576ca5 451 m_maskBitmap = 0;
e9576ca5
SC
452 Create(bitmap, colour);
453}
454
455// Construct a mask from a bitmap and a palette index indicating
456// the transparent area
457wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
458{
e9576ca5 459 m_maskBitmap = 0;
e9576ca5
SC
460 Create(bitmap, paletteIndex);
461}
462
463// Construct a mask from a mono bitmap (copies the bitmap).
464wxMask::wxMask(const wxBitmap& bitmap)
465{
e9576ca5 466 m_maskBitmap = 0;
e9576ca5
SC
467 Create(bitmap);
468}
469
470wxMask::~wxMask()
471{
8208e181
SC
472 if ( m_maskBitmap )
473 {
474 wxMacDestroyGWorld( m_maskBitmap ) ;
475 m_maskBitmap = NULL ;
476 }
e9576ca5
SC
477}
478
479// Create a mask from a mono bitmap (copies the bitmap).
480bool wxMask::Create(const wxBitmap& bitmap)
481{
482// TODO
483 return FALSE;
484}
485
486// Create a mask from a bitmap and a palette index indicating
487// the transparent area
488bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
489{
490// TODO
491 return FALSE;
492}
493
494// Create a mask from a bitmap and a colour indicating
495// the transparent area
496bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
497{
8208e181
SC
498 if ( m_maskBitmap )
499 {
500 wxMacDestroyGWorld( m_maskBitmap ) ;
501 m_maskBitmap = NULL ;
502 }
503 wxASSERT( ((wxBitmapRefData*) bitmap.GetRefData())->m_bitmapType == kMacBitmapTypeGrafWorld ) ;
504 // other types would require a temporary bitmap. not yet implemented
505
506 if (!bitmap.Ok())
507 {
508 return FALSE;
509 }
510
511 m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 ) ;
2f1ae414
SC
512 LockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
513 LockPixels( GetGWorldPixMap( (CGrafPtr) ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
8208e181
SC
514 RGBColor maskColor = colour.GetPixel() ;
515
516 // this is not very efficient, but I can't think
517 // of a better way of doing it
518 CGrafPtr origPort ;
519 GDHandle origDevice ;
520
521 GetGWorld( &origPort , &origDevice ) ;
522 for (int w = 0; w < bitmap.GetWidth(); w++)
523 {
524 for (int h = 0; h < bitmap.GetHeight(); h++)
525 {
526 RGBColor colors[2] = {
527 { 0xFFFF , 0xFFFF , 0xFFFF } ,
528 { 0, 0 , 0 }
529 } ;
530
531 SetGWorld( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap , NULL ) ;
532 RGBColor col ;
533 GetCPixel( w , h , &col ) ;
534 SetGWorld( m_maskBitmap , NULL ) ;
535 if (col.red == maskColor.red && col.blue == maskColor.blue && col.green == maskColor.green)
536 {
537 SetCPixel( w , h , &colors[0] ) ;
538 }
539 else
540 {
541 SetCPixel( w , h , &colors[1] ) ;
542 }
543 }
544 }
2f1ae414
SC
545 UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
546 UnlockPixels( GetGWorldPixMap( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
8208e181
SC
547 SetGWorld( origPort , origDevice ) ;
548
549 return TRUE;
e9576ca5
SC
550}
551
552/*
553 * wxBitmapHandler
554 */
555
556IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
557
558bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
559{
560 return FALSE;
561}
562
563bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
564 int desiredWidth, int desiredHeight)
565{
566 return FALSE;
567}
568
569bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
570{
571 return FALSE;
572}
573
574/*
575 * Standard handlers
576 */
577
519cb848
SC
578class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
579{
580 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
581public:
582 inline wxPICTResourceHandler()
583 {
584 m_name = "Macintosh Pict resource";
585 m_extension = "";
586 m_type = wxBITMAP_TYPE_PICT_RESOURCE;
587 };
588
589 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
590 int desiredWidth, int desiredHeight);
591};
592IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
593
594bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
595 int desiredWidth, int desiredHeight)
596{
597 Str255 theName ;
598
599 strcpy( (char*) theName , name ) ;
600 c2pstr( (char*) theName ) ;
601
602 PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
603 if ( thePict )
604 {
605 PictInfo theInfo ;
606
607 GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
608 DetachResource( (Handle) thePict ) ;
609 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
610 M_BITMAPHANDLERDATA->m_hPict = thePict ;
611 M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
612 M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
613
614 M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
615 M_BITMAPHANDLERDATA->m_ok = true ;
616 M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
617// M_BITMAPHANDLERDATA->m_bitmapPalette;
618// M_BITMAPHANDLERDATA->m_quality;
619 return TRUE ;
620 }
621 return FALSE ;
622}
623
e9576ca5
SC
624/* TODO: bitmap handlers, a bit like this:
625class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
626{
627 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
628public:
629 inline wxBMPResourceHandler()
630 {
631 m_name = "Windows bitmap resource";
632 m_extension = "";
633 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
634 };
635
636 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
637 int desiredWidth, int desiredHeight);
638};
639IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
640*/
641
519cb848
SC
642class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
643{
644 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
645public:
646 inline wxXPMFileHandler(void)
647 {
648 m_name = "XPM bitmap file";
649 m_extension = "xpm";
650 m_type = wxBITMAP_TYPE_XPM;
651 };
652
653 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
654 int desiredWidth = -1, int desiredHeight = -1);
655 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
656};
657IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
658
659bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
660 int desiredWidth, int desiredHeight)
661{
662#if USE_XPM_IN_MSW
663 XImage *ximage;
664 XpmAttributes xpmAttr;
665 HDC dc;
666
667 M_BITMAPHANDLERDATA->m_ok = FALSE;
668 dc = CreateCompatibleDC(NULL);
669 if (dc)
670 {
671 xpmAttr.valuemask = XpmReturnPixels;
672 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
673 DeleteDC(dc);
674 if (errorStatus == XpmSuccess)
675 {
676 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
677
678 BITMAP bm;
679 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
680
681 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
682 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
683 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
684 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
685 XpmFreeAttributes(&xpmAttr);
686 XImageFree(ximage);
687
688 M_BITMAPHANDLERDATA->m_ok = TRUE;
689 return TRUE;
690 }
691 else
692 {
693 M_BITMAPHANDLERDATA->m_ok = FALSE;
694 return FALSE;
695 }
696 }
697#endif
698
699 return FALSE;
700}
701
702bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
703{
704#if USE_XPM_IN_MSW
705 HDC dc = NULL;
706
707 Visual *visual = NULL;
708 XImage ximage;
709
710 dc = CreateCompatibleDC(NULL);
711 if (dc)
712 {
713 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
2f1ae414
SC
714 {
715
519cb848
SC
716 ximage.width = M_BITMAPHANDLERDATA->m_width;
717 ximage.height = M_BITMAPHANDLERDATA->m_height;
718 ximage.depth = M_BITMAPHANDLERDATA->m_depth;
719 ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap;
720 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
721 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
722
723 if (dc)
724 DeleteDC(dc);
725
726 if (errorStatus == XpmSuccess)
2f1ae414 727 return TRUE;
519cb848
SC
728 else
729 return FALSE;
730 } else return FALSE;
731 } else return FALSE;
732#else
733 return FALSE;
734#endif
735}
736
737
738class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
739{
740 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
741public:
742 inline wxXPMDataHandler(void)
743 {
744 m_name = "XPM bitmap data";
745 m_extension = "xpm";
746 m_type = wxBITMAP_TYPE_XPM_DATA;
747 };
748
749 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
750};
751IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
752
753bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
754{
a959b088
SC
755 XImage * ximage = NULL ;
756 XImage * xshapeimage = NULL ;
519cb848
SC
757 int ErrorStatus;
758 XpmAttributes xpmAttr;
759
760 xpmAttr.valuemask = XpmReturnInfos; // get infos back
761 ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data,
a959b088 762 &ximage, &xshapeimage, &xpmAttr);
519cb848
SC
763
764 if (ErrorStatus == XpmSuccess)
765 {
766 M_BITMAPHANDLERDATA->m_ok = FALSE;
767 M_BITMAPHANDLERDATA->m_numColors = 0;
768 M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ;
769
770 M_BITMAPHANDLERDATA->m_width = ximage->width;
771 M_BITMAPHANDLERDATA->m_height = ximage->height;
772 M_BITMAPHANDLERDATA->m_depth = ximage->depth;
773 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
774 XpmFreeAttributes(&xpmAttr);
775 M_BITMAPHANDLERDATA->m_ok = TRUE;
776 ximage->gworldptr = NULL ;
777 XImageFree(ximage); // releases the malloc, but does not detroy
778 // the bitmap
779 M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
a959b088
SC
780 if ( xshapeimage != NULL )
781 {
782 wxMask* m = new wxMask() ;
783 m->SetMaskBitmap( xshapeimage->gworldptr ) ;
784 M_BITMAPHANDLERDATA->m_bitmapMask = m ;
785 }
519cb848
SC
786 return TRUE;
787 }
788 else
789 {
790 M_BITMAPHANDLERDATA->m_ok = FALSE;
791 return FALSE;
792 }
793 return FALSE;
794}
795
796class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
797{
798 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
799public:
800 inline wxBMPResourceHandler()
801 {
802 m_name = "Windows bitmap resource";
803 m_extension = "";
804 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
805 };
806
807 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
808 int desiredWidth, int desiredHeight);
809};
810
811IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
812
813bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
814 int desiredWidth, int desiredHeight)
815{
816 // TODO: load colourmap.
519cb848
SC
817 // it's probably not found
818 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
819
820 return FALSE;
821}
822
823class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
824{
825 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
826public:
827 inline wxBMPFileHandler(void)
828 {
829 m_name = "Windows bitmap file";
830 m_extension = "bmp";
831 m_type = wxBITMAP_TYPE_BMP;
832 };
833
834 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
835 int desiredWidth, int desiredHeight);
836 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
837};
838
839IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
840
841bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
842 int desiredWidth, int desiredHeight)
843{
844#if USE_IMAGE_LOADING_IN_MSW
845 wxPalette *palette = NULL;
846 bool success = FALSE;
519cb848
SC
847 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
848 if (!success && palette)
849 {
850 delete palette;
851 palette = NULL;
852 }
853 if (palette)
854 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
855 return success;
856#else
857 return FALSE;
858#endif
859}
860
861bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
862{
863#if USE_IMAGE_LOADING_IN_MSW
864 wxPalette *actualPalette = (wxPalette *)pal;
865 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
866 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
867 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
868#else
869 return FALSE;
870#endif
871}
872
873
e9576ca5
SC
874void wxBitmap::CleanUpHandlers()
875{
876 wxNode *node = sm_handlers.First();
877 while ( node )
878 {
879 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
880 wxNode *next = node->Next();
881 delete handler;
882 delete node;
883 node = next;
884 }
885}
886
887void wxBitmap::InitStandardHandlers()
888{
519cb848
SC
889 AddHandler( new wxPICTResourceHandler ) ;
890 AddHandler( new wxICONResourceHandler ) ;
891 AddHandler(new wxXPMFileHandler);
2f1ae414 892 AddHandler(new wxXPMDataHandler);
519cb848
SC
893 AddHandler(new wxBMPResourceHandler);
894 AddHandler(new wxBMPFileHandler);
e9576ca5 895}