1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
19 #include "wx/palette.h"
20 #include "wx/bitmap.h"
24 #include "wx/xpmdecod.h"
28 #ifdef OBSOLETE_XPM_DATA_HANDLER
33 #if !USE_SHARED_LIBRARIES
34 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
35 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
39 #include <ApplicationServices/ApplicationServices.h>
41 #include <PictUtils.h>
44 #include "wx/mac/uma.h"
46 CTabHandle
wxMacCreateColorTable( int numColors
)
48 CTabHandle newColors
; /* Handle to the new color table */
50 /* Allocate memory for the color table */
51 newColors
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) +
52 sizeof (ColorSpec
) * (numColors
- 1) );
55 /* Initialize the fields */
56 (**newColors
).ctSeed
= GetCTSeed();
57 (**newColors
).ctFlags
= 0;
58 (**newColors
).ctSize
= numColors
- 1;
59 /* Initialize the table of colors */
64 void wxMacDestroyColorTable( CTabHandle colors
)
66 DisposeHandle( (Handle
) colors
) ;
69 void wxMacSetColorTableEntry( CTabHandle newColors
, int index
, int red
, int green
, int blue
)
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;
77 GWorldPtr
wxMacCreateGWorld( int width
, int height
, int depth
)
81 Rect rect
= { 0 , 0 , height
, width
} ;
85 depth
= wxDisplayDepth() ;
88 err
= NewGWorld( &port
, depth
, &rect
, NULL
, NULL
, 0 ) ;
96 void wxMacDestroyGWorld( GWorldPtr gw
)
102 PicHandle
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
)
107 PicHandle pict
; // this is the Picture we give back
109 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
110 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
111 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
113 unsigned char *maskimage
= NULL
;
115 GetPortBounds( wp
, &portRect
) ;
116 int width
= portRect
.right
- portRect
.left
;
117 int height
= portRect
.bottom
- portRect
.top
;
119 LockPixels( GetGWorldPixMap( wp
) ) ;
120 GetGWorld( &origPort
, &origDev
) ;
124 maskimage
= (unsigned char*) malloc( width
* height
) ;
125 SetGWorld( mask
, NULL
) ;
126 LockPixels( GetGWorldPixMap( mask
) ) ;
127 for ( int y
= 0 ; y
< height
; y
++ )
129 for( int x
= 0 ; x
< width
; x
++ )
133 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
134 maskimage
[y
*width
+ x
] = ( col
.red
== 0 ) ; // for monochrome masks
137 UnlockPixels( GetGWorldPixMap( mask
) ) ;
140 SetGWorld( wp
, NULL
) ;
142 pict
= OpenPicture(&portRect
); // open a picture, this disables drawing
148 RGBForeColor( &black
) ;
149 RGBBackColor( &white
) ;
150 PenMode(transparent
);
152 for ( int y
= 0 ; y
< height
; ++y
)
154 for( int x
= 0 ; x
< width
; ++x
)
156 if ( maskimage
[y
*width
+ x
] )
160 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
161 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
164 // With transparency set this sets a blank pixel not a white one
165 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &white
);
174 RGBBackColor( &gray
) ;
175 EraseRect(&portRect
);
176 RGBForeColor( &black
) ;
177 RGBBackColor( &white
) ;
179 CopyBits(GetPortBitMapForCopyBits(wp
), /* src PixMap - we copy image over
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
186 ClosePicture(); // We are done recording the picture
187 UnlockPixels( GetGWorldPixMap( wp
) ) ;
188 SetGWorld( origPort
, origDev
) ;
190 return pict
; // return our groovy pict handle
193 wxBitmapRefData::wxBitmapRefData()
205 m_bitmapType
= kMacBitmapTypeUnknownType
;
208 wxBitmapRefData::~wxBitmapRefData()
210 switch (m_bitmapType
)
212 case kMacBitmapTypePict
:
216 KillPicture( m_hPict
) ;
221 case kMacBitmapTypeGrafWorld
:
225 wxMacDestroyGWorld( m_hBitmap
) ;
230 case kMacBitmapTypeIcon
:
233 DisposeCIcon( m_hIcon
) ;
249 wxList
wxBitmap::sm_handlers
;
255 if ( wxTheBitmapList
)
256 wxTheBitmapList
->AddBitmap(this);
259 wxBitmap::~wxBitmap()
262 wxTheBitmapList
->DeleteObject(this);
265 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
267 m_refData
= new wxBitmapRefData
;
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;
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
) ;
280 GDHandle origDevice
;
282 GetGWorld( &origPort
, &origDevice
) ;
283 SetGWorld( M_BITMAPDATA
->m_hBitmap
, NULL
) ;
284 LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
286 // bits is a char array
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);
294 RGBColor colors
[2] = {
295 { 0xFFFF , 0xFFFF , 0xFFFF } ,
299 for ( int y
= 0 ; y
< the_height
; ++y
, linestart
+= linesize
)
301 for ( int x
= 0 ; x
< the_width
; ++x
)
305 int mask
= 1 << bit
;
306 if ( linestart
[index
] & mask
)
308 SetCPixel( x
, y
, &colors
[1] ) ;
312 SetCPixel( x
, y
, &colors
[0] ) ;
316 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
318 SetGWorld( origPort
, origDevice
) ;
322 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
325 if ( wxTheBitmapList
) {
326 wxTheBitmapList
->AddBitmap(this);
330 wxBitmap::wxBitmap(int w
, int h
, int d
)
332 (void)Create(w
, h
, d
);
334 if ( wxTheBitmapList
)
335 wxTheBitmapList
->AddBitmap(this);
338 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
340 (void) Create(data
, type
, width
, height
, depth
);
342 if ( wxTheBitmapList
)
343 wxTheBitmapList
->AddBitmap(this);
346 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
348 LoadFile(filename
, (int)type
);
350 if ( wxTheBitmapList
)
351 wxTheBitmapList
->AddBitmap(this);
354 bool wxBitmap::CreateFromXpm(const char **bits
)
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);
365 wxBitmap::wxBitmap(const char **bits
)
367 #ifdef OBSOLETE_XPM_DATA_HANDLER
368 (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
370 (void) CreateFromXpm(bits
);
374 wxBitmap::wxBitmap(char **bits
)
376 #ifdef OBSOLETE_XPM_DATA_HANDLER
377 (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
379 (void) CreateFromXpm((const char **)bits
);
383 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
&rect
) const
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") );
392 wxBitmap
ret( rect
.width
, rect
.height
, GetDepth() );
393 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
398 GetGWorld( &origPort
, &origDevice
);
400 // Update the subbitmaps reference data
401 wxBitmapRefData
*ref
= (wxBitmapRefData
*)ret
.GetRefData();
403 ref
->m_numColors
= M_BITMAPDATA
->m_numColors
;
404 ref
->m_bitmapPalette
= M_BITMAPDATA
->m_bitmapPalette
;
405 ref
->m_bitmapType
= M_BITMAPDATA
->m_bitmapType
;
407 // Copy sub region of this bitmap
408 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
)
410 printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
412 else if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
417 WXHBITMAP submask
, mask
;
420 mask
= GetMask()->GetMaskBitmap();
421 submask
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1);
422 LockPixels(GetGWorldPixMap(mask
));
423 LockPixels(GetGWorldPixMap(submask
));
425 for(int yy
= 0; yy
< rect
.height
; yy
++)
427 for(int xx
= 0; xx
< rect
.width
; xx
++)
429 SetGWorld(mask
, NULL
);
430 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
431 SetGWorld(submask
, NULL
);
432 SetCPixel(xx
,yy
, &color
);
435 UnlockPixels(GetGWorldPixMap(mask
));
436 UnlockPixels(GetGWorldPixMap(submask
));
437 ref
->m_bitmapMask
= new wxMask
;
438 ref
->m_bitmapMask
->SetMaskBitmap(submask
);
444 WXHBITMAP subbitmap
, bitmap
;
447 bitmap
= GetHBITMAP();
448 subbitmap
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth());
449 LockPixels(GetGWorldPixMap(bitmap
));
450 LockPixels(GetGWorldPixMap(subbitmap
));
452 for(int yy
= 0; yy
< rect
.height
; yy
++)
454 for(int xx
= 0; xx
< rect
.width
; xx
++)
456 SetGWorld(bitmap
, NULL
);
457 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
458 SetGWorld(subbitmap
, NULL
);
459 SetCPixel(xx
, yy
, &color
);
462 UnlockPixels(GetGWorldPixMap(bitmap
));
463 UnlockPixels(GetGWorldPixMap(subbitmap
));
464 ret
.SetHBITMAP(subbitmap
);
467 SetGWorld( origPort
, origDevice
);
472 bool wxBitmap::Create(int w
, int h
, int d
)
476 m_refData
= new wxBitmapRefData
;
478 M_BITMAPDATA
->m_width
= w
;
479 M_BITMAPDATA
->m_height
= h
;
480 M_BITMAPDATA
->m_depth
= d
;
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
) ;
485 return M_BITMAPDATA
->m_ok
;
488 int wxBitmap::GetBitmapType() const
490 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") );
492 return M_BITMAPDATA
->m_bitmapType
;
495 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
497 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
498 M_BITMAPDATA
->m_hBitmap
= bmp
;
499 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
502 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
506 m_refData
= new wxBitmapRefData
;
508 wxBitmapHandler
*handler
= FindHandler(type
);
510 if ( handler
== NULL
) {
511 wxLogWarning("no bitmap handler for type %d defined.", type
);
516 return handler
->LoadFile(this, filename
, type
, -1, -1);
519 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
523 m_refData
= new wxBitmapRefData
;
525 wxBitmapHandler
*handler
= FindHandler(type
);
527 if ( handler
== NULL
) {
528 wxLogWarning("no bitmap handler for type %d defined.", type
);
533 return handler
->Create(this, data
, type
, width
, height
, depth
);
536 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
538 wxCHECK_RET( image
.Ok(), wxT("invalid image") )
539 wxCHECK_RET( depth
== -1, wxT("invalid bitmap depth") )
541 m_refData
= new wxBitmapRefData();
543 if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
545 // width and height of the device-dependent bitmap
546 int width
= image
.GetWidth();
547 int height
= image
.GetHeight();
551 Create( width
, height
, wxDisplayDepth() ) ;
552 wxBitmap
maskBitmap( width
, height
, 1);
555 GDHandle origDevice
;
557 LockPixels( GetGWorldPixMap(GetHBITMAP()) );
558 LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
560 GetGWorld( &origPort
, &origDevice
) ;
561 SetGWorld( GetHBITMAP() , NULL
) ;
564 wxColour rgb
, maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue());
566 RGBColor white
= { 0xffff, 0xffff, 0xffff };
567 RGBColor black
= { 0 , 0 , 0 };
569 register unsigned char* data
= image
.GetData();
572 for (int y
= 0; y
< height
; y
++)
574 for (int x
= 0; x
< width
; x
++)
576 rgb
.Set(data
[index
++], data
[index
++], data
[index
++]);
577 color
= rgb
.GetPixel();
578 SetCPixel( x
, y
, &color
) ;
581 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
);
582 if (rgb
== maskcolor
) {
583 SetCPixel(x
,y
, &white
);
586 SetCPixel(x
,y
, &black
);
588 SetGWorld(GetHBITMAP(), NULL
);
594 if ( image
.HasMask() ) {
595 // SetMask(new wxMask( maskBitmap ));
598 UnlockPixels( GetGWorldPixMap(GetHBITMAP()) );
599 UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
600 SetGWorld( origPort
, origDevice
);
603 wxImage
wxBitmap::ConvertToImage() const
607 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
609 // create an wxImage object
610 int width
= GetWidth();
611 int height
= GetHeight();
612 image
.Create( width
, height
);
614 unsigned char *data
= image
.GetData();
616 wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") );
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;
625 wxMask
*mask
= GetMask();
627 GetGWorld( &origPort
, &origDevice
);
628 LockPixels(GetGWorldPixMap(GetHBITMAP()));
629 SetGWorld( GetHBITMAP(), NULL
);
631 // Copy data into image
633 for (int yy
= 0; yy
< height
; yy
++)
635 for (int xx
= 0; xx
< width
; xx
++)
637 GetCPixel(xx
,yy
, &color
);
638 r
= ((color
.red
) >> 8);
639 g
= ((color
.green
) >> 8);
640 b
= ((color
.blue
) >> 8);
646 if (mask
->PointMasked(xx
,yy
))
648 data
[index
] = mask_r
;
649 data
[index
+ 1] = mask_g
;
650 data
[index
+ 2] = mask_b
;
658 image
.SetMaskColour( mask_r
, mask_g
, mask_b
);
659 image
.SetMask( true );
663 UnlockPixels(GetGWorldPixMap(GetHBITMAP()));
664 SetGWorld(origPort
, origDevice
);
670 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
672 wxBitmapHandler
*handler
= FindHandler(type
);
674 if ( handler
== NULL
) {
675 wxLogWarning("no bitmap handler for type %d defined.", type
);
680 return handler
->SaveFile(this, filename
, type
, palette
);
683 bool wxBitmap::Ok() const
685 return (M_BITMAPDATA
&& M_BITMAPDATA
->m_ok
);
688 int wxBitmap::GetHeight() const
690 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
692 return M_BITMAPDATA
->m_height
;
695 int wxBitmap::GetWidth() const
697 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
699 return M_BITMAPDATA
->m_width
;
702 int wxBitmap::GetDepth() const
704 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
706 return M_BITMAPDATA
->m_depth
;
709 int wxBitmap::GetQuality() const
711 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
713 return M_BITMAPDATA
->m_quality
;
716 wxMask
*wxBitmap::GetMask() const
718 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
720 return M_BITMAPDATA
->m_bitmapMask
;
723 void wxBitmap::SetWidth(int w
)
726 m_refData
= new wxBitmapRefData
;
728 M_BITMAPDATA
->m_width
= w
;
731 void wxBitmap::SetHeight(int h
)
734 m_refData
= new wxBitmapRefData
;
736 M_BITMAPDATA
->m_height
= h
;
739 void wxBitmap::SetDepth(int d
)
742 m_refData
= new wxBitmapRefData
;
744 M_BITMAPDATA
->m_depth
= d
;
747 void wxBitmap::SetQuality(int q
)
750 m_refData
= new wxBitmapRefData
;
752 M_BITMAPDATA
->m_quality
= q
;
755 void wxBitmap::SetOk(bool isOk
)
758 m_refData
= new wxBitmapRefData
;
760 M_BITMAPDATA
->m_ok
= isOk
;
763 wxPalette
*wxBitmap::GetPalette() const
765 wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap GetPalette()") );
767 return &M_BITMAPDATA
->m_bitmapPalette
;
770 void wxBitmap::SetPalette(const wxPalette
& palette
)
773 m_refData
= new wxBitmapRefData
;
775 M_BITMAPDATA
->m_bitmapPalette
= palette
;
778 void wxBitmap::SetMask(wxMask
*mask
)
781 m_refData
= new wxBitmapRefData
;
783 M_BITMAPDATA
->m_bitmapMask
= mask
;
786 WXHBITMAP
wxBitmap::GetHBITMAP() const
788 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
790 return M_BITMAPDATA
->m_hBitmap
;
793 PicHandle
wxBitmap::GetPict() const
795 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
797 PicHandle picture
; // This is the returned picture
799 // If bitmap already in Pict format return pointer
800 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
) {
801 return M_BITMAPDATA
->m_hPict
;
803 else if(M_BITMAPDATA
->m_bitmapType
!= kMacBitmapTypeGrafWorld
) {
808 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
809 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
810 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
816 GetPortBounds( GetHBITMAP() , &portRect
) ;
817 int width
= portRect
.right
- portRect
.left
;
818 int height
= portRect
.bottom
- portRect
.top
;
820 LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
821 GetGWorld( &origPort
, &origDev
) ;
825 SetGWorld( GetHBITMAP() , NULL
) ;
827 picture
= OpenPicture(&portRect
); // open a picture, this disables drawing
835 RGBColor trans
= white
;
837 RGBBackColor( &gray
);
838 EraseRect( &portRect
);
839 RGBColor trans
= gray
;
841 RGBForeColor( &black
) ;
842 RGBBackColor( &white
) ;
843 PenMode(transparent
);
845 for ( int y
= 0 ; y
< height
; ++y
)
847 for( int x
= 0 ; x
< width
; ++x
)
849 if ( !mask
->PointMasked(x
,y
) )
853 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
854 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
857 // With transparency this sets a blank pixel
858 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &trans
);
865 RGBBackColor( &gray
) ;
866 EraseRect(&portRect
);
867 RGBForeColor( &black
) ;
868 RGBBackColor( &white
) ;
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
878 ClosePicture(); // We are done recording the picture
879 UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
880 SetGWorld( origPort
, origDev
) ;
882 return picture
; // return our groovy pict handle
885 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
887 sm_handlers
.Append(handler
);
890 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
892 sm_handlers
.Insert(handler
);
895 bool wxBitmap::RemoveHandler(const wxString
& name
)
897 wxBitmapHandler
*handler
= FindHandler(name
);
900 sm_handlers
.DeleteObject(handler
);
907 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
909 wxNode
*node
= sm_handlers
.First();
912 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
913 if ( handler
->GetName() == name
)
920 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
922 wxNode
*node
= sm_handlers
.First();
925 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
926 if ( handler
->GetExtension() == extension
&&
927 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
934 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
936 wxNode
*node
= sm_handlers
.First();
939 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
940 if (handler
->GetType() == bitmapType
)
956 // Construct a mask from a bitmap and a colour indicating
957 // the transparent area
958 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
961 Create(bitmap
, colour
);
964 // Construct a mask from a bitmap and a palette index indicating
965 // the transparent area
966 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
969 Create(bitmap
, paletteIndex
);
972 // Construct a mask from a mono bitmap (copies the bitmap).
973 wxMask::wxMask(const wxBitmap
& bitmap
)
983 wxMacDestroyGWorld( m_maskBitmap
) ;
984 m_maskBitmap
= NULL
;
988 // Create a mask from a mono bitmap (copies the bitmap).
989 bool wxMask::Create(const wxBitmap
& bitmap
)
993 wxMacDestroyGWorld( m_maskBitmap
) ;
994 m_maskBitmap
= NULL
;
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
1000 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap"));
1002 wxCHECK_MSG(bitmap
.GetDepth() == 1, false,
1003 wxT("Cannot create mask from colour bitmap"));
1005 m_maskBitmap
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1);
1006 Rect rect
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() };
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()) );
1019 // Create a mask from a bitmap and a palette index indicating
1020 // the transparent area
1021 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
1024 wxCHECK_MSG( 0, false, wxT("Not implemented"));
1028 // Create a mask from a bitmap and a colour indicating
1029 // the transparent area
1030 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
1034 wxMacDestroyGWorld( m_maskBitmap
) ;
1035 m_maskBitmap
= NULL
;
1037 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1038 wxT("Cannot create mask from this bitmap type (TODO)"));
1039 // other types would require a temporary bitmap. not yet implemented
1041 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap"));
1043 m_maskBitmap
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );
1044 LockPixels( GetGWorldPixMap( m_maskBitmap
) );
1045 LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) );
1046 RGBColor maskColor
= colour
.GetPixel();
1048 // this is not very efficient, but I can't think
1049 // of a better way of doing it
1051 GDHandle origDevice
;
1053 RGBColor colors
[2] = {
1054 { 0xFFFF, 0xFFFF, 0xFFFF },
1057 GetGWorld( &origPort
, &origDevice
) ;
1058 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
1060 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
1062 SetGWorld( bitmap
.GetHBITMAP(), NULL
) ;
1063 GetCPixel( w
, h
, &col
) ;
1064 SetGWorld( m_maskBitmap
, NULL
) ;
1065 if (col
.red
== maskColor
.red
&& col
.green
== maskColor
.green
&& col
.blue
== maskColor
.blue
)
1067 SetCPixel( w
, h
, &colors
[0] ) ;
1071 SetCPixel( w
, h
, &colors
[1] ) ;
1075 UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap
) ) ;
1076 UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ;
1077 SetGWorld( origPort
, origDevice
) ;
1082 bool wxMask::PointMasked(int x
, int y
)
1085 GDHandle origDevice
;
1089 GetGWorld( &origPort
, &origDevice
);
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
));
1098 SetGWorld( origPort
, origDevice
);
1107 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
1109 bool wxBitmapHandler::Create(wxBitmap
*bitmap
, void *data
, long type
, int width
, int height
, int depth
)
1114 bool wxBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long type
,
1115 int desiredWidth
, int desiredHeight
)
1120 bool wxBitmapHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1129 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
1131 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
)
1133 inline wxPICTResourceHandler()
1135 m_name
= "Macintosh Pict resource";
1137 m_type
= wxBITMAP_TYPE_PICT_RESOURCE
;
1140 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1141 int desiredWidth
, int desiredHeight
);
1143 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
)
1145 bool wxPICTResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1146 int desiredWidth
, int desiredHeight
)
1151 c2pstrcpy( (StringPtr
) theName
, name
) ;
1153 strcpy( (char *) theName
, name
) ;
1154 c2pstr( (char *)theName
) ;
1157 PicHandle thePict
= (PicHandle
) GetNamedResource( 'PICT' , theName
) ;
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
;
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;
1179 /* TODO: bitmap handlers, a bit like this:
1180 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1182 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1184 inline wxBMPResourceHandler()
1186 m_name = "Windows bitmap resource";
1188 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
1191 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1192 int desiredWidth, int desiredHeight);
1194 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1197 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
1199 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
1201 inline wxXPMFileHandler(void)
1203 m_name
= "XPM bitmap file";
1204 m_extension
= "xpm";
1205 m_type
= wxBITMAP_TYPE_XPM
;
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
);
1212 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
1214 bool wxXPMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1215 int desiredWidth
, int desiredHeight
)
1219 XpmAttributes xpmAttr
;
1222 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1223 dc
= CreateCompatibleDC(NULL
);
1226 xpmAttr
.valuemask
= XpmReturnPixels
;
1227 int errorStatus
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage
**) NULL
, &xpmAttr
);
1229 if (errorStatus
== XpmSuccess
)
1231 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ximage
->bitmap
;
1234 GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
);
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
);
1243 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
1248 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1257 bool wxXPMFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1262 Visual
*visual
= NULL
;
1265 dc
= CreateCompatibleDC(NULL
);
1268 if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
))
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
);
1281 if (errorStatus
== XpmSuccess
)
1285 } else return FALSE
;
1286 } else return FALSE
;
1292 #ifdef OBSOLETE_XPM_DATA_HANDLER
1293 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
1295 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
1297 inline wxXPMDataHandler(void)
1299 m_name
= "XPM bitmap data";
1300 m_extension
= "xpm";
1301 m_type
= wxBITMAP_TYPE_XPM_DATA
;
1304 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
1306 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
1308 bool wxXPMDataHandler::Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
)
1310 XImage
* ximage
= NULL
;
1311 XImage
* xshapeimage
= NULL
;
1313 XpmAttributes xpmAttr
;
1315 xpmAttr
.valuemask
= XpmReturnInfos
; // get infos back
1316 ErrorStatus
= XpmCreateImageFromData( GetMainDevice() , (char **)data
,
1317 &ximage
, &xshapeimage
, &xpmAttr
);
1319 if (ErrorStatus
== XpmSuccess
)
1321 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1322 M_BITMAPHANDLERDATA
->m_numColors
= 0;
1323 M_BITMAPHANDLERDATA
->m_hBitmap
= ximage
->gworldptr
;
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
;
1329 XpmFreeAttributes(&xpmAttr
);
1330 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
1331 ximage
->gworldptr
= NULL
;
1332 XImageFree(ximage
); // releases the malloc, but does not detroy
1334 M_BITMAPHANDLERDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
1335 if ( xshapeimage
!= NULL
)
1337 wxMask
* m
= new wxMask() ;
1338 m
->SetMaskBitmap( xshapeimage
->gworldptr
) ;
1339 M_BITMAPHANDLERDATA
->m_bitmapMask
= m
;
1345 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1352 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
1354 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
1356 inline wxBMPResourceHandler()
1358 m_name
= "Windows bitmap resource";
1360 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
1363 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1364 int desiredWidth
, int desiredHeight
);
1367 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
1369 bool wxBMPResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1370 int desiredWidth
, int desiredHeight
)
1372 // TODO: load colourmap.
1373 // it's probably not found
1374 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str());
1379 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
1381 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
)
1383 inline wxBMPFileHandler(void)
1385 m_name
= "Windows bitmap file";
1386 m_extension
= "bmp";
1387 m_type
= wxBITMAP_TYPE_BMP
;
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
);
1395 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
)
1397 bool wxBMPFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1398 int desiredWidth
, int desiredHeight
)
1400 #if USE_IMAGE_LOADING_IN_MSW
1401 wxPalette
*palette
= NULL
;
1402 bool success
= FALSE
;
1403 success
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0);
1404 if (!success
&& palette
)
1410 M_BITMAPHANDLERDATA
->m_bitmapPalette
= *palette
;
1417 bool wxBMPFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*pal
)
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);
1430 void wxBitmap::CleanUpHandlers()
1432 wxNode
*node
= sm_handlers
.First();
1435 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
1436 wxNode
*next
= node
->Next();
1443 void wxBitmap::InitStandardHandlers()
1445 AddHandler(new wxPICTResourceHandler
) ;
1446 AddHandler(new wxICONResourceHandler
) ;
1447 AddHandler(new wxXPMFileHandler
);
1448 #ifdef OBSOLETE_XPM_DATA_HANDLER
1449 AddHandler(new wxXPMDataHandler
);
1451 AddHandler(new wxBMPResourceHandler
);
1452 AddHandler(new wxBMPFileHandler
);