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