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()
204 m_bitmapType
= kMacBitmapTypeUnknownType
;
207 wxBitmapRefData::~wxBitmapRefData()
209 switch (m_bitmapType
)
211 case kMacBitmapTypePict
:
215 KillPicture( m_hPict
) ;
220 case kMacBitmapTypeGrafWorld
:
224 wxMacDestroyGWorld( m_hBitmap
) ;
241 wxList
wxBitmap::sm_handlers
;
247 if ( wxTheBitmapList
)
248 wxTheBitmapList
->AddBitmap(this);
251 wxBitmap::~wxBitmap()
254 wxTheBitmapList
->DeleteObject(this);
257 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
259 m_refData
= new wxBitmapRefData
;
261 M_BITMAPDATA
->m_width
= the_width
;
262 M_BITMAPDATA
->m_height
= the_height
;
263 M_BITMAPDATA
->m_depth
= no_bits
;
264 M_BITMAPDATA
->m_numColors
= 0;
267 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
268 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( the_width
, the_height
, no_bits
) ;
269 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
272 GDHandle origDevice
;
274 GetGWorld( &origPort
, &origDevice
) ;
275 SetGWorld( M_BITMAPDATA
->m_hBitmap
, NULL
) ;
276 LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
278 // bits is a char array
280 unsigned char* linestart
= (unsigned char*) bits
;
281 int linesize
= ( the_width
/ (sizeof(unsigned char) * 8)) ;
282 if ( the_width
% (sizeof(unsigned char) * 8) ) {
283 linesize
+= sizeof(unsigned char);
286 RGBColor colors
[2] = {
287 { 0xFFFF , 0xFFFF , 0xFFFF } ,
291 for ( int y
= 0 ; y
< the_height
; ++y
, linestart
+= linesize
)
293 for ( int x
= 0 ; x
< the_width
; ++x
)
297 int mask
= 1 << bit
;
298 if ( linestart
[index
] & mask
)
300 SetCPixel( x
, y
, &colors
[1] ) ;
304 SetCPixel( x
, y
, &colors
[0] ) ;
308 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
310 SetGWorld( origPort
, origDevice
) ;
314 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
317 if ( wxTheBitmapList
) {
318 wxTheBitmapList
->AddBitmap(this);
322 wxBitmap::wxBitmap(int w
, int h
, int d
)
324 (void)Create(w
, h
, d
);
326 if ( wxTheBitmapList
)
327 wxTheBitmapList
->AddBitmap(this);
330 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
332 (void) Create(data
, type
, width
, height
, depth
);
334 if ( wxTheBitmapList
)
335 wxTheBitmapList
->AddBitmap(this);
338 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
340 LoadFile(filename
, (int)type
);
342 if ( wxTheBitmapList
)
343 wxTheBitmapList
->AddBitmap(this);
346 bool wxBitmap::CreateFromXpm(const char **bits
)
348 wxCHECK_MSG( bits
!= NULL
, FALSE
, wxT("invalid bitmap data") )
349 wxXPMDecoder decoder
;
350 wxImage img
= decoder
.ReadData(bits
);
351 wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") )
352 *this = wxBitmap(img
);
353 if ( wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
357 wxBitmap::wxBitmap(const char **bits
)
359 #ifdef OBSOLETE_XPM_DATA_HANDLER
360 (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
362 (void) CreateFromXpm(bits
);
366 wxBitmap::wxBitmap(char **bits
)
368 #ifdef OBSOLETE_XPM_DATA_HANDLER
369 (void) Create((void *)bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
371 (void) CreateFromXpm((const char **)bits
);
375 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
&rect
) const
378 (rect
.x
>= 0) && (rect
.y
>= 0) &&
379 (rect
.x
+rect
.width
<= GetWidth()) &&
380 (rect
.y
+rect
.height
<= GetHeight()),
381 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
384 wxBitmap
ret( rect
.width
, rect
.height
, GetDepth() );
385 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
390 GetGWorld( &origPort
, &origDevice
);
392 // Update the subbitmaps reference data
393 wxBitmapRefData
*ref
= (wxBitmapRefData
*)ret
.GetRefData();
395 ref
->m_numColors
= M_BITMAPDATA
->m_numColors
;
396 ref
->m_bitmapPalette
= M_BITMAPDATA
->m_bitmapPalette
;
397 ref
->m_bitmapType
= M_BITMAPDATA
->m_bitmapType
;
399 // Copy sub region of this bitmap
400 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
)
402 printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
404 else if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
409 WXHBITMAP submask
, mask
;
412 mask
= GetMask()->GetMaskBitmap();
413 submask
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1);
414 LockPixels(GetGWorldPixMap(mask
));
415 LockPixels(GetGWorldPixMap(submask
));
417 for(int yy
= 0; yy
< rect
.height
; yy
++)
419 for(int xx
= 0; xx
< rect
.width
; xx
++)
421 SetGWorld(mask
, NULL
);
422 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
423 SetGWorld(submask
, NULL
);
424 SetCPixel(xx
,yy
, &color
);
427 UnlockPixels(GetGWorldPixMap(mask
));
428 UnlockPixels(GetGWorldPixMap(submask
));
429 ref
->m_bitmapMask
= new wxMask
;
430 ref
->m_bitmapMask
->SetMaskBitmap(submask
);
436 WXHBITMAP subbitmap
, bitmap
;
439 bitmap
= GetHBITMAP();
440 subbitmap
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth());
441 LockPixels(GetGWorldPixMap(bitmap
));
442 LockPixels(GetGWorldPixMap(subbitmap
));
444 for(int yy
= 0; yy
< rect
.height
; yy
++)
446 for(int xx
= 0; xx
< rect
.width
; xx
++)
448 SetGWorld(bitmap
, NULL
);
449 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
450 SetGWorld(subbitmap
, NULL
);
451 SetCPixel(xx
, yy
, &color
);
454 UnlockPixels(GetGWorldPixMap(bitmap
));
455 UnlockPixels(GetGWorldPixMap(subbitmap
));
456 ret
.SetHBITMAP(subbitmap
);
459 SetGWorld( origPort
, origDevice
);
464 bool wxBitmap::Create(int w
, int h
, int d
)
468 m_refData
= new wxBitmapRefData
;
470 M_BITMAPDATA
->m_width
= w
;
471 M_BITMAPDATA
->m_height
= h
;
472 M_BITMAPDATA
->m_depth
= d
;
474 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
475 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( w
, h
, d
) ;
476 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
477 return M_BITMAPDATA
->m_ok
;
480 int wxBitmap::GetBitmapType() const
482 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") );
484 return M_BITMAPDATA
->m_bitmapType
;
487 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
489 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
490 M_BITMAPDATA
->m_hBitmap
= bmp
;
491 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
494 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
498 m_refData
= new wxBitmapRefData
;
500 wxBitmapHandler
*handler
= FindHandler(type
);
502 if ( handler
== NULL
) {
503 wxLogWarning("no bitmap handler for type %d defined.", type
);
508 return handler
->LoadFile(this, filename
, type
, -1, -1);
511 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
515 m_refData
= new wxBitmapRefData
;
517 wxBitmapHandler
*handler
= FindHandler(type
);
519 if ( handler
== NULL
) {
520 wxLogWarning("no bitmap handler for type %d defined.", type
);
525 return handler
->Create(this, data
, type
, width
, height
, depth
);
528 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
530 wxCHECK_RET( image
.Ok(), wxT("invalid image") )
531 wxCHECK_RET( depth
== -1, wxT("invalid bitmap depth") )
533 m_refData
= new wxBitmapRefData();
535 if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
537 // width and height of the device-dependent bitmap
538 int width
= image
.GetWidth();
539 int height
= image
.GetHeight();
543 Create( width
, height
, wxDisplayDepth() ) ;
544 wxBitmap
maskBitmap( width
, height
, 1);
547 GDHandle origDevice
;
549 LockPixels( GetGWorldPixMap(GetHBITMAP()) );
550 LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
552 GetGWorld( &origPort
, &origDevice
) ;
553 SetGWorld( GetHBITMAP() , NULL
) ;
556 wxColour rgb
, maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue());
558 RGBColor white
= { 0xffff, 0xffff, 0xffff };
559 RGBColor black
= { 0 , 0 , 0 };
561 register unsigned char* data
= image
.GetData();
564 for (int y
= 0; y
< height
; y
++)
566 for (int x
= 0; x
< width
; x
++)
568 rgb
.Set(data
[index
++], data
[index
++], data
[index
++]);
569 color
= rgb
.GetPixel();
570 SetCPixel( x
, y
, &color
) ;
573 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
);
574 if (rgb
== maskcolor
) {
575 SetCPixel(x
,y
, &white
);
578 SetCPixel(x
,y
, &black
);
580 SetGWorld(GetHBITMAP(), NULL
);
586 if ( image
.HasMask() ) {
587 // SetMask(new wxMask( maskBitmap ));
590 UnlockPixels( GetGWorldPixMap(GetHBITMAP()) );
591 UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
592 SetGWorld( origPort
, origDevice
);
595 wxImage
wxBitmap::ConvertToImage() const
599 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
601 // create an wxImage object
602 int width
= GetWidth();
603 int height
= GetHeight();
604 image
.Create( width
, height
);
606 unsigned char *data
= image
.GetData();
608 wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") );
614 // background color set to RGB(16,16,16) in consistent with wxGTK
615 unsigned char mask_r
=16, mask_g
=16, mask_b
=16;
617 wxMask
*mask
= GetMask();
619 GetGWorld( &origPort
, &origDevice
);
620 LockPixels(GetGWorldPixMap(GetHBITMAP()));
621 SetGWorld( GetHBITMAP(), NULL
);
623 // Copy data into image
625 for (int yy
= 0; yy
< height
; yy
++)
627 for (int xx
= 0; xx
< width
; xx
++)
629 GetCPixel(xx
,yy
, &color
);
630 r
= ((color
.red
) >> 8);
631 g
= ((color
.green
) >> 8);
632 b
= ((color
.blue
) >> 8);
638 if (mask
->PointMasked(xx
,yy
))
640 data
[index
] = mask_r
;
641 data
[index
+ 1] = mask_g
;
642 data
[index
+ 2] = mask_b
;
650 image
.SetMaskColour( mask_r
, mask_g
, mask_b
);
651 image
.SetMask( true );
655 UnlockPixels(GetGWorldPixMap(GetHBITMAP()));
656 SetGWorld(origPort
, origDevice
);
662 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
664 wxBitmapHandler
*handler
= FindHandler(type
);
666 if ( handler
== NULL
) {
667 wxLogWarning("no bitmap handler for type %d defined.", type
);
672 return handler
->SaveFile(this, filename
, type
, palette
);
675 bool wxBitmap::Ok() const
677 return (M_BITMAPDATA
&& M_BITMAPDATA
->m_ok
);
680 int wxBitmap::GetHeight() const
682 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
684 return M_BITMAPDATA
->m_height
;
687 int wxBitmap::GetWidth() const
689 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
691 return M_BITMAPDATA
->m_width
;
694 int wxBitmap::GetDepth() const
696 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
698 return M_BITMAPDATA
->m_depth
;
701 int wxBitmap::GetQuality() const
703 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
705 return M_BITMAPDATA
->m_quality
;
708 wxMask
*wxBitmap::GetMask() const
710 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
712 return M_BITMAPDATA
->m_bitmapMask
;
715 void wxBitmap::SetWidth(int w
)
718 m_refData
= new wxBitmapRefData
;
720 M_BITMAPDATA
->m_width
= w
;
723 void wxBitmap::SetHeight(int h
)
726 m_refData
= new wxBitmapRefData
;
728 M_BITMAPDATA
->m_height
= h
;
731 void wxBitmap::SetDepth(int d
)
734 m_refData
= new wxBitmapRefData
;
736 M_BITMAPDATA
->m_depth
= d
;
739 void wxBitmap::SetQuality(int q
)
742 m_refData
= new wxBitmapRefData
;
744 M_BITMAPDATA
->m_quality
= q
;
747 void wxBitmap::SetOk(bool isOk
)
750 m_refData
= new wxBitmapRefData
;
752 M_BITMAPDATA
->m_ok
= isOk
;
755 wxPalette
*wxBitmap::GetPalette() const
757 wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap GetPalette()") );
759 return &M_BITMAPDATA
->m_bitmapPalette
;
762 void wxBitmap::SetPalette(const wxPalette
& palette
)
765 m_refData
= new wxBitmapRefData
;
767 M_BITMAPDATA
->m_bitmapPalette
= palette
;
770 void wxBitmap::SetMask(wxMask
*mask
)
773 m_refData
= new wxBitmapRefData
;
775 M_BITMAPDATA
->m_bitmapMask
= mask
;
778 WXHBITMAP
wxBitmap::GetHBITMAP() const
780 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
782 return M_BITMAPDATA
->m_hBitmap
;
785 PicHandle
wxBitmap::GetPict() const
787 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
789 PicHandle picture
; // This is the returned picture
791 // If bitmap already in Pict format return pointer
792 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
) {
793 return M_BITMAPDATA
->m_hPict
;
795 else if(M_BITMAPDATA
->m_bitmapType
!= kMacBitmapTypeGrafWorld
) {
800 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
801 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
802 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
808 GetPortBounds( GetHBITMAP() , &portRect
) ;
809 int width
= portRect
.right
- portRect
.left
;
810 int height
= portRect
.bottom
- portRect
.top
;
812 LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
813 GetGWorld( &origPort
, &origDev
) ;
817 SetGWorld( GetHBITMAP() , NULL
) ;
819 picture
= OpenPicture(&portRect
); // open a picture, this disables drawing
827 RGBColor trans
= white
;
829 RGBBackColor( &gray
);
830 EraseRect( &portRect
);
831 RGBColor trans
= gray
;
833 RGBForeColor( &black
) ;
834 RGBBackColor( &white
) ;
835 PenMode(transparent
);
837 for ( int y
= 0 ; y
< height
; ++y
)
839 for( int x
= 0 ; x
< width
; ++x
)
841 if ( !mask
->PointMasked(x
,y
) )
845 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
846 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
849 // With transparency this sets a blank pixel
850 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &trans
);
857 RGBBackColor( &gray
) ;
858 EraseRect(&portRect
);
859 RGBForeColor( &black
) ;
860 RGBBackColor( &white
) ;
862 CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),
863 // src PixMap - we copy image over itself -
864 GetPortBitMapForCopyBits(GetHBITMAP()),
865 // dst PixMap - no drawing occurs
866 &portRect
, // srcRect - it will be recorded and compressed -
867 &portRect
, // dstRect - into the picture that is open -
868 srcCopy
,NULL
); // copyMode and no clip region
870 ClosePicture(); // We are done recording the picture
871 UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
872 SetGWorld( origPort
, origDev
) ;
874 return picture
; // return our groovy pict handle
877 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
879 sm_handlers
.Append(handler
);
882 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
884 sm_handlers
.Insert(handler
);
887 bool wxBitmap::RemoveHandler(const wxString
& name
)
889 wxBitmapHandler
*handler
= FindHandler(name
);
892 sm_handlers
.DeleteObject(handler
);
899 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
901 wxNode
*node
= sm_handlers
.First();
904 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
905 if ( handler
->GetName() == name
)
912 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
914 wxNode
*node
= sm_handlers
.First();
917 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
918 if ( handler
->GetExtension() == extension
&&
919 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
926 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
928 wxNode
*node
= sm_handlers
.First();
931 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
932 if (handler
->GetType() == bitmapType
)
948 // Construct a mask from a bitmap and a colour indicating
949 // the transparent area
950 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
953 Create(bitmap
, colour
);
956 // Construct a mask from a bitmap and a palette index indicating
957 // the transparent area
958 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
961 Create(bitmap
, paletteIndex
);
964 // Construct a mask from a mono bitmap (copies the bitmap).
965 wxMask::wxMask(const wxBitmap
& bitmap
)
975 wxMacDestroyGWorld( m_maskBitmap
) ;
976 m_maskBitmap
= NULL
;
980 // Create a mask from a mono bitmap (copies the bitmap).
981 bool wxMask::Create(const wxBitmap
& bitmap
)
985 wxMacDestroyGWorld( m_maskBitmap
) ;
986 m_maskBitmap
= NULL
;
988 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
989 wxT("Cannot create mask from this bitmap type (TODO)"));
990 // other types would require a temporary bitmap. not yet implemented
992 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap"));
994 wxCHECK_MSG(bitmap
.GetDepth() == 1, false,
995 wxT("Cannot create mask from colour bitmap"));
997 m_maskBitmap
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1);
998 Rect rect
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() };
1000 LockPixels( GetGWorldPixMap(m_maskBitmap
) );
1001 LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1002 CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()),
1003 GetPortBitMapForCopyBits(m_maskBitmap
),
1004 &rect
, &rect
, srcCopy
, 0);
1005 UnlockPixels( GetGWorldPixMap(m_maskBitmap
) );
1006 UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1011 // Create a mask from a bitmap and a palette index indicating
1012 // the transparent area
1013 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
1016 wxCHECK_MSG( 0, false, wxT("Not implemented"));
1020 // Create a mask from a bitmap and a colour indicating
1021 // the transparent area
1022 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
1026 wxMacDestroyGWorld( m_maskBitmap
) ;
1027 m_maskBitmap
= NULL
;
1029 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1030 wxT("Cannot create mask from this bitmap type (TODO)"));
1031 // other types would require a temporary bitmap. not yet implemented
1033 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap"));
1035 m_maskBitmap
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );
1036 LockPixels( GetGWorldPixMap( m_maskBitmap
) );
1037 LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) );
1038 RGBColor maskColor
= colour
.GetPixel();
1040 // this is not very efficient, but I can't think
1041 // of a better way of doing it
1043 GDHandle origDevice
;
1045 RGBColor colors
[2] = {
1046 { 0xFFFF, 0xFFFF, 0xFFFF },
1049 GetGWorld( &origPort
, &origDevice
) ;
1050 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
1052 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
1054 SetGWorld( bitmap
.GetHBITMAP(), NULL
) ;
1055 GetCPixel( w
, h
, &col
) ;
1056 SetGWorld( m_maskBitmap
, NULL
) ;
1057 if (col
.red
== maskColor
.red
&& col
.green
== maskColor
.green
&& col
.blue
== maskColor
.blue
)
1059 SetCPixel( w
, h
, &colors
[0] ) ;
1063 SetCPixel( w
, h
, &colors
[1] ) ;
1067 UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap
) ) ;
1068 UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ;
1069 SetGWorld( origPort
, origDevice
) ;
1074 bool wxMask::PointMasked(int x
, int y
)
1077 GDHandle origDevice
;
1081 GetGWorld( &origPort
, &origDevice
);
1083 //Set port to mask and see if it masked (1) or not ( 0 )
1084 SetGWorld(m_maskBitmap
, NULL
);
1085 LockPixels(GetGWorldPixMap(m_maskBitmap
));
1086 GetCPixel(x
,y
, &color
);
1087 masked
= !(color
.red
== 0 && color
.green
== 0 && color
.blue
== 0);
1088 UnlockPixels(GetGWorldPixMap(m_maskBitmap
));
1090 SetGWorld( origPort
, origDevice
);
1099 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
1101 bool wxBitmapHandler::Create(wxBitmap
*bitmap
, void *data
, long type
, int width
, int height
, int depth
)
1106 bool wxBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long type
,
1107 int desiredWidth
, int desiredHeight
)
1112 bool wxBitmapHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1121 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
1123 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
)
1125 inline wxPICTResourceHandler()
1127 m_name
= "Macintosh Pict resource";
1129 m_type
= wxBITMAP_TYPE_PICT_RESOURCE
;
1132 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1133 int desiredWidth
, int desiredHeight
);
1135 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
)
1137 bool wxPICTResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1138 int desiredWidth
, int desiredHeight
)
1143 c2pstrcpy( (StringPtr
) theName
, name
) ;
1145 strcpy( (char *) theName
, name
) ;
1146 c2pstr( (char *)theName
) ;
1149 PicHandle thePict
= (PicHandle
) GetNamedResource( 'PICT' , theName
) ;
1154 GetPictInfo( thePict
, &theInfo
, 0 , 0 , systemMethod
, 0 ) ;
1155 DetachResource( (Handle
) thePict
) ;
1156 M_BITMAPHANDLERDATA
->m_bitmapType
= kMacBitmapTypePict
;
1157 M_BITMAPHANDLERDATA
->m_hPict
= thePict
;
1158 M_BITMAPHANDLERDATA
->m_width
= theInfo
.sourceRect
.right
- theInfo
.sourceRect
.left
;
1159 M_BITMAPHANDLERDATA
->m_height
= theInfo
.sourceRect
.bottom
- theInfo
.sourceRect
.top
;
1161 M_BITMAPHANDLERDATA
->m_depth
= theInfo
.depth
;
1162 M_BITMAPHANDLERDATA
->m_ok
= true ;
1163 M_BITMAPHANDLERDATA
->m_numColors
= theInfo
.uniqueColors
;
1164 // M_BITMAPHANDLERDATA->m_bitmapPalette;
1165 // M_BITMAPHANDLERDATA->m_quality;
1171 /* TODO: bitmap handlers, a bit like this:
1172 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
1174 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
1176 inline wxBMPResourceHandler()
1178 m_name = "Windows bitmap resource";
1180 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
1183 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
1184 int desiredWidth, int desiredHeight);
1186 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
1189 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
1191 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
1193 inline wxXPMFileHandler(void)
1195 m_name
= "XPM bitmap file";
1196 m_extension
= "xpm";
1197 m_type
= wxBITMAP_TYPE_XPM
;
1200 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1201 int desiredWidth
= -1, int desiredHeight
= -1);
1202 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
1204 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
1206 bool wxXPMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1207 int desiredWidth
, int desiredHeight
)
1211 XpmAttributes xpmAttr
;
1214 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1215 dc
= CreateCompatibleDC(NULL
);
1218 xpmAttr
.valuemask
= XpmReturnPixels
;
1219 int errorStatus
= XpmReadFileToImage(&dc
, WXSTRINGCAST name
, &ximage
, (XImage
**) NULL
, &xpmAttr
);
1221 if (errorStatus
== XpmSuccess
)
1223 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ximage
->bitmap
;
1226 GetObject((HBITMAP
)M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(bm
), (LPSTR
) & bm
);
1228 M_BITMAPHANDLERDATA
->m_width
= (bm
.bmWidth
);
1229 M_BITMAPHANDLERDATA
->m_height
= (bm
.bmHeight
);
1230 M_BITMAPHANDLERDATA
->m_depth
= (bm
.bmPlanes
* bm
.bmBitsPixel
);
1231 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
1232 XpmFreeAttributes(&xpmAttr
);
1235 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
1240 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1249 bool wxXPMFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1254 Visual
*visual
= NULL
;
1257 dc
= CreateCompatibleDC(NULL
);
1260 if (SelectObject(dc
, (HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
))
1263 ximage
.width
= M_BITMAPHANDLERDATA
->m_width
;
1264 ximage
.height
= M_BITMAPHANDLERDATA
->m_height
;
1265 ximage
.depth
= M_BITMAPHANDLERDATA
->m_depth
;
1266 ximage
.bitmap
= (void *)M_BITMAPHANDLERDATA
->m_hBitmap
;
1267 int errorStatus
= XpmWriteFileFromImage(&dc
, WXSTRINGCAST name
,
1268 &ximage
, (XImage
*) NULL
, (XpmAttributes
*) NULL
);
1273 if (errorStatus
== XpmSuccess
)
1277 } else return FALSE
;
1278 } else return FALSE
;
1284 #ifdef OBSOLETE_XPM_DATA_HANDLER
1285 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
1287 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
1289 inline wxXPMDataHandler(void)
1291 m_name
= "XPM bitmap data";
1292 m_extension
= "xpm";
1293 m_type
= wxBITMAP_TYPE_XPM_DATA
;
1296 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
1298 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
1300 bool wxXPMDataHandler::Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
)
1302 XImage
* ximage
= NULL
;
1303 XImage
* xshapeimage
= NULL
;
1305 XpmAttributes xpmAttr
;
1307 xpmAttr
.valuemask
= XpmReturnInfos
; // get infos back
1308 ErrorStatus
= XpmCreateImageFromData( GetMainDevice() , (char **)data
,
1309 &ximage
, &xshapeimage
, &xpmAttr
);
1311 if (ErrorStatus
== XpmSuccess
)
1313 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1314 M_BITMAPHANDLERDATA
->m_numColors
= 0;
1315 M_BITMAPHANDLERDATA
->m_hBitmap
= ximage
->gworldptr
;
1317 M_BITMAPHANDLERDATA
->m_width
= ximage
->width
;
1318 M_BITMAPHANDLERDATA
->m_height
= ximage
->height
;
1319 M_BITMAPHANDLERDATA
->m_depth
= ximage
->depth
;
1320 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
1321 XpmFreeAttributes(&xpmAttr
);
1322 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
1323 ximage
->gworldptr
= NULL
;
1324 XImageFree(ximage
); // releases the malloc, but does not detroy
1326 M_BITMAPHANDLERDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
1327 if ( xshapeimage
!= NULL
)
1329 wxMask
* m
= new wxMask() ;
1330 m
->SetMaskBitmap( xshapeimage
->gworldptr
) ;
1331 M_BITMAPHANDLERDATA
->m_bitmapMask
= m
;
1337 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
1344 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
1346 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
1348 inline wxBMPResourceHandler()
1350 m_name
= "Windows bitmap resource";
1352 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
1355 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1356 int desiredWidth
, int desiredHeight
);
1359 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
1361 bool wxBMPResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1362 int desiredWidth
, int desiredHeight
)
1364 // TODO: load colourmap.
1365 // it's probably not found
1366 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name
.c_str());
1371 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
1373 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
)
1375 inline wxBMPFileHandler(void)
1377 m_name
= "Windows bitmap file";
1378 m_extension
= "bmp";
1379 m_type
= wxBITMAP_TYPE_BMP
;
1382 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1383 int desiredWidth
, int desiredHeight
);
1384 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
1387 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
)
1389 bool wxBMPFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1390 int desiredWidth
, int desiredHeight
)
1392 #if USE_IMAGE_LOADING_IN_MSW
1393 wxPalette
*palette
= NULL
;
1394 bool success
= FALSE
;
1395 success
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0);
1396 if (!success
&& palette
)
1402 M_BITMAPHANDLERDATA
->m_bitmapPalette
= *palette
;
1409 bool wxBMPFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*pal
)
1411 #if USE_IMAGE_LOADING_IN_MSW
1412 wxPalette
*actualPalette
= (wxPalette
*)pal
;
1413 if (!actualPalette
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull()))
1414 actualPalette
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
);
1415 return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0);
1422 void wxBitmap::CleanUpHandlers()
1424 wxNode
*node
= sm_handlers
.First();
1427 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
1428 wxNode
*next
= node
->Next();
1435 void wxBitmap::InitStandardHandlers()
1437 AddHandler(new wxPICTResourceHandler
) ;
1438 AddHandler(new wxICONResourceHandler
) ;
1439 AddHandler(new wxXPMFileHandler
);
1440 #ifdef OBSOLETE_XPM_DATA_HANDLER
1441 AddHandler(new wxXPMDataHandler
);
1443 AddHandler(new wxBMPResourceHandler
);
1444 AddHandler(new wxBMPFileHandler
);