1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmapbase.h"
14 #pragma implementation "bitmap.h"
19 #include "wx/bitmap.h"
23 #include "wx/xpmdecod.h"
25 #if !USE_SHARED_LIBRARIES
26 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
27 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
28 IMPLEMENT_ABSTRACT_CLASS(wxBitmapBase
, wxGDIObject
)
29 IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandlerBase
, wxObject
)
33 #include <ApplicationServices/ApplicationServices.h>
35 #include <PictUtils.h>
38 #include "wx/mac/uma.h"
40 CTabHandle
wxMacCreateColorTable( int numColors
)
42 CTabHandle newColors
; /* Handle to the new color table */
44 /* Allocate memory for the color table */
45 newColors
= (CTabHandle
)NewHandleClear( sizeof (ColorTable
) +
46 sizeof (ColorSpec
) * (numColors
- 1) );
49 /* Initialize the fields */
50 (**newColors
).ctSeed
= GetCTSeed();
51 (**newColors
).ctFlags
= 0;
52 (**newColors
).ctSize
= numColors
- 1;
53 /* Initialize the table of colors */
58 void wxMacDestroyColorTable( CTabHandle colors
)
60 DisposeHandle( (Handle
) colors
) ;
63 void wxMacSetColorTableEntry( CTabHandle newColors
, int index
, int red
, int green
, int blue
)
65 (**newColors
).ctTable
[index
].value
= index
;
66 (**newColors
).ctTable
[index
].rgb
.red
= 0 ;// someRedValue;
67 (**newColors
).ctTable
[index
].rgb
.green
= 0 ; // someGreenValue;
68 (**newColors
).ctTable
[index
].rgb
.blue
= 0 ; // someBlueValue;
71 GWorldPtr
wxMacCreateGWorld( int width
, int height
, int depth
)
75 Rect rect
= { 0 , 0 , height
, width
} ;
79 depth
= wxDisplayDepth() ;
82 err
= NewGWorld( &port
, depth
, &rect
, NULL
, NULL
, 0 ) ;
90 void wxMacDestroyGWorld( GWorldPtr gw
)
96 PicHandle
wxMacCreatePict(GWorldPtr wp
, GWorldPtr mask
)
101 PicHandle pict
; // this is the Picture we give back
103 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
104 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
105 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
107 unsigned char *maskimage
= NULL
;
109 GetPortBounds( wp
, &portRect
) ;
110 int width
= portRect
.right
- portRect
.left
;
111 int height
= portRect
.bottom
- portRect
.top
;
113 LockPixels( GetGWorldPixMap( wp
) ) ;
114 GetGWorld( &origPort
, &origDev
) ;
118 maskimage
= (unsigned char*) malloc( width
* height
) ;
119 SetGWorld( mask
, NULL
) ;
120 LockPixels( GetGWorldPixMap( mask
) ) ;
121 for ( int y
= 0 ; y
< height
; y
++ )
123 for( int x
= 0 ; x
< width
; x
++ )
127 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
128 maskimage
[y
*width
+ x
] = ( col
.red
== 0 ) ; // for monochrome masks
131 UnlockPixels( GetGWorldPixMap( mask
) ) ;
134 SetGWorld( wp
, NULL
) ;
136 pict
= OpenPicture(&portRect
); // open a picture, this disables drawing
142 RGBForeColor( &black
) ;
143 RGBBackColor( &white
) ;
144 PenMode(transparent
);
146 for ( int y
= 0 ; y
< height
; ++y
)
148 for( int x
= 0 ; x
< width
; ++x
)
150 if ( maskimage
[y
*width
+ x
] )
154 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
155 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
158 // With transparency set this sets a blank pixel not a white one
159 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &white
);
168 RGBBackColor( &gray
) ;
169 EraseRect(&portRect
);
170 RGBForeColor( &black
) ;
171 RGBBackColor( &white
) ;
173 CopyBits(GetPortBitMapForCopyBits(wp
), /* src PixMap - we copy image over
175 GetPortBitMapForCopyBits(wp
), // dst PixMap - no drawing occurs
176 &portRect
, // srcRect - it will be recorded and compressed -
177 &portRect
, // dstRect - into the picture that is open -
178 srcCopy
,NULL
); // copyMode and no clip region
180 ClosePicture(); // We are done recording the picture
181 UnlockPixels( GetGWorldPixMap( wp
) ) ;
182 SetGWorld( origPort
, origDev
) ;
184 return pict
; // return our groovy pict handle
187 wxBitmapRefData::wxBitmapRefData()
199 m_bitmapType
= kMacBitmapTypeUnknownType
;
202 wxBitmapRefData::~wxBitmapRefData()
204 switch (m_bitmapType
)
206 case kMacBitmapTypePict
:
210 KillPicture( m_hPict
) ;
215 case kMacBitmapTypeGrafWorld
:
219 wxMacDestroyGWorld( m_hBitmap
) ;
224 case kMacBitmapTypeIcon
:
227 DisposeCIcon( m_hIcon
) ;
243 wxList
wxBitmapBase::sm_handlers
;
246 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
256 if ( wxTheBitmapList
)
257 wxTheBitmapList
->AddBitmap(this);
260 wxBitmap::~wxBitmap()
263 wxTheBitmapList
->DeleteObject(this);
266 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
268 m_refData
= new wxBitmapRefData
;
270 M_BITMAPDATA
->m_width
= the_width
;
271 M_BITMAPDATA
->m_height
= the_height
;
272 M_BITMAPDATA
->m_depth
= no_bits
;
273 M_BITMAPDATA
->m_numColors
= 0;
276 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
277 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( the_width
, the_height
, no_bits
) ;
278 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
281 GDHandle origDevice
;
283 GetGWorld( &origPort
, &origDevice
) ;
284 SetGWorld( M_BITMAPDATA
->m_hBitmap
, NULL
) ;
285 LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
287 // bits is a char array
289 unsigned char* linestart
= (unsigned char*) bits
;
290 int linesize
= ( the_width
/ (sizeof(unsigned char) * 8)) ;
291 if ( the_width
% (sizeof(unsigned char) * 8) ) {
292 linesize
+= sizeof(unsigned char);
295 RGBColor colors
[2] = {
296 { 0xFFFF , 0xFFFF , 0xFFFF } ,
300 for ( int y
= 0 ; y
< the_height
; ++y
, linestart
+= linesize
)
302 for ( int x
= 0 ; x
< the_width
; ++x
)
306 int mask
= 1 << bit
;
307 if ( linestart
[index
] & mask
)
309 SetCPixel( x
, y
, &colors
[1] ) ;
313 SetCPixel( x
, y
, &colors
[0] ) ;
317 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
319 SetGWorld( origPort
, origDevice
) ;
323 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
326 if ( wxTheBitmapList
) {
327 wxTheBitmapList
->AddBitmap(this);
331 wxBitmap::wxBitmap(int w
, int h
, int d
)
333 (void)Create(w
, h
, d
);
335 if ( wxTheBitmapList
)
336 wxTheBitmapList
->AddBitmap(this);
339 wxBitmap::wxBitmap(void *data
, wxBitmapType type
, int width
, int height
, int depth
)
341 (void) Create(data
, type
, width
, height
, depth
);
343 if ( wxTheBitmapList
)
344 wxTheBitmapList
->AddBitmap(this);
347 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
)
349 LoadFile(filename
, type
);
351 if ( wxTheBitmapList
)
352 wxTheBitmapList
->AddBitmap(this);
355 bool wxBitmap::CreateFromXpm(const char **bits
)
357 wxCHECK_MSG( bits
!= NULL
, FALSE
, wxT("invalid bitmap data") )
358 wxXPMDecoder decoder
;
359 wxImage img
= decoder
.ReadData(bits
);
360 wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") )
361 *this = wxBitmap(img
);
362 if ( wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
366 wxBitmap::wxBitmap(const char **bits
)
368 (void) CreateFromXpm(bits
);
371 wxBitmap::wxBitmap(char **bits
)
373 (void) CreateFromXpm((const char **)bits
);
376 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
&rect
) const
379 (rect
.x
>= 0) && (rect
.y
>= 0) &&
380 (rect
.x
+rect
.width
<= GetWidth()) &&
381 (rect
.y
+rect
.height
<= GetHeight()),
382 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
385 wxBitmap
ret( rect
.width
, rect
.height
, GetDepth() );
386 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
391 GetGWorld( &origPort
, &origDevice
);
393 // Update the subbitmaps reference data
394 wxBitmapRefData
*ref
= (wxBitmapRefData
*)ret
.GetRefData();
396 ref
->m_numColors
= M_BITMAPDATA
->m_numColors
;
397 ref
->m_bitmapPalette
= M_BITMAPDATA
->m_bitmapPalette
;
398 ref
->m_bitmapType
= M_BITMAPDATA
->m_bitmapType
;
400 // Copy sub region of this bitmap
401 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
)
403 printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
405 else if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
410 WXHBITMAP submask
, mask
;
413 mask
= GetMask()->GetMaskBitmap();
414 submask
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1);
415 LockPixels(GetGWorldPixMap(mask
));
416 LockPixels(GetGWorldPixMap(submask
));
418 for(int yy
= 0; yy
< rect
.height
; yy
++)
420 for(int xx
= 0; xx
< rect
.width
; xx
++)
422 SetGWorld(mask
, NULL
);
423 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
424 SetGWorld(submask
, NULL
);
425 SetCPixel(xx
,yy
, &color
);
428 UnlockPixels(GetGWorldPixMap(mask
));
429 UnlockPixels(GetGWorldPixMap(submask
));
430 ref
->m_bitmapMask
= new wxMask
;
431 ref
->m_bitmapMask
->SetMaskBitmap(submask
);
437 WXHBITMAP subbitmap
, bitmap
;
440 bitmap
= GetHBITMAP();
441 subbitmap
= wxMacCreateGWorld(rect
.width
, rect
.height
, GetDepth());
442 LockPixels(GetGWorldPixMap(bitmap
));
443 LockPixels(GetGWorldPixMap(subbitmap
));
445 for(int yy
= 0; yy
< rect
.height
; yy
++)
447 for(int xx
= 0; xx
< rect
.width
; xx
++)
449 SetGWorld(bitmap
, NULL
);
450 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
451 SetGWorld(subbitmap
, NULL
);
452 SetCPixel(xx
, yy
, &color
);
455 UnlockPixels(GetGWorldPixMap(bitmap
));
456 UnlockPixels(GetGWorldPixMap(subbitmap
));
457 ret
.SetHBITMAP(subbitmap
);
460 SetGWorld( origPort
, origDevice
);
465 bool wxBitmap::Create(int w
, int h
, int d
)
469 m_refData
= new wxBitmapRefData
;
471 M_BITMAPDATA
->m_width
= w
;
472 M_BITMAPDATA
->m_height
= h
;
473 M_BITMAPDATA
->m_depth
= d
;
475 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
476 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( w
, h
, d
) ;
477 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
478 return M_BITMAPDATA
->m_ok
;
481 int wxBitmap::GetBitmapType() const
483 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") );
485 return M_BITMAPDATA
->m_bitmapType
;
488 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
490 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
491 M_BITMAPDATA
->m_hBitmap
= bmp
;
492 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
495 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
)
499 wxBitmapHandler
*handler
= FindHandler(type
);
503 m_refData
= new wxBitmapRefData
;
505 return handler
->LoadFile(this, filename
, type
, -1, -1);
509 wxImage
loadimage(filename
, type
);
510 if (loadimage
.Ok()) {
515 wxLogWarning("no bitmap handler for type %d defined.", type
);
519 bool wxBitmap::Create(void *data
, wxBitmapType 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
, 32 ) ;
554 GDHandle origDevice
;
556 PixMapHandle pixMap
= GetGWorldPixMap(GetHBITMAP()) ;
557 LockPixels( pixMap
);
559 GetGWorld( &origPort
, &origDevice
) ;
560 SetGWorld( GetHBITMAP() , NULL
) ;
565 register unsigned char* data
= image
.GetData();
566 char* destinationBase
= GetPixBaseAddr( pixMap
);
567 register unsigned char* destination
= (unsigned char*) destinationBase
;
568 for (int y
= 0; y
< height
; y
++)
570 for (int x
= 0; x
< width
; x
++)
573 *destination
++ = *data
++ ;
574 *destination
++ = *data
++ ;
575 *destination
++ = *data
++ ;
577 destinationBase
+= ((**pixMap
).rowBytes
& 0x7fff);
578 destination
= (unsigned char*) destinationBase
;
580 if ( image
.HasMask() )
582 data
= image
.GetData();
584 wxColour
maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue());
585 RGBColor white
= { 0xffff, 0xffff, 0xffff };
586 RGBColor black
= { 0 , 0 , 0 };
587 wxBitmap maskBitmap
;
589 maskBitmap
.Create( width
, height
, 1);
590 LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
591 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
);
593 for (int y
= 0; y
< height
; y
++)
595 for (int x
= 0; x
< width
; x
++)
597 if ( data
[0] == image
.GetMaskRed() && data
[1] == image
.GetMaskGreen() && data
[2] == image
.GetMaskBlue() )
599 SetCPixel(x
,y
, &white
);
602 SetCPixel(x
,y
, &black
);
607 SetGWorld(GetHBITMAP(), NULL
);
608 SetMask(new wxMask( maskBitmap
));
609 UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
612 UnlockPixels( GetGWorldPixMap(GetHBITMAP()) );
613 SetGWorld( origPort
, origDevice
);
616 wxImage
wxBitmap::ConvertToImage() const
620 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
622 // create an wxImage object
623 int width
= GetWidth();
624 int height
= GetHeight();
625 image
.Create( width
, height
);
627 unsigned char *data
= image
.GetData();
629 wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") );
635 // background color set to RGB(16,16,16) in consistent with wxGTK
636 unsigned char mask_r
=16, mask_g
=16, mask_b
=16;
638 wxMask
*mask
= GetMask();
640 GetGWorld( &origPort
, &origDevice
);
641 LockPixels(GetGWorldPixMap(GetHBITMAP()));
642 SetGWorld( GetHBITMAP(), NULL
);
644 // Copy data into image
646 for (int yy
= 0; yy
< height
; yy
++)
648 for (int xx
= 0; xx
< width
; xx
++)
650 GetCPixel(xx
,yy
, &color
);
651 r
= ((color
.red
) >> 8);
652 g
= ((color
.green
) >> 8);
653 b
= ((color
.blue
) >> 8);
659 if (mask
->PointMasked(xx
,yy
))
661 data
[index
] = mask_r
;
662 data
[index
+ 1] = mask_g
;
663 data
[index
+ 2] = mask_b
;
671 image
.SetMaskColour( mask_r
, mask_g
, mask_b
);
672 image
.SetMask( true );
676 UnlockPixels(GetGWorldPixMap(GetHBITMAP()));
677 SetGWorld(origPort
, origDevice
);
683 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
,
684 const wxPalette
*palette
) const
686 wxBitmapHandler
*handler
= FindHandler(type
);
690 return handler
->SaveFile(this, filename
, type
, palette
);
694 wxImage image
= ConvertToImage();
696 return image
.SaveFile(filename
, type
);
699 wxLogWarning("no bitmap handler for type %d defined.", type
);
703 bool wxBitmap::Ok() const
705 return (M_BITMAPDATA
&& M_BITMAPDATA
->m_ok
);
708 int wxBitmap::GetHeight() const
710 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
712 return M_BITMAPDATA
->m_height
;
715 int wxBitmap::GetWidth() const
717 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
719 return M_BITMAPDATA
->m_width
;
722 int wxBitmap::GetDepth() const
724 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
726 return M_BITMAPDATA
->m_depth
;
729 int wxBitmap::GetQuality() const
731 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
733 return M_BITMAPDATA
->m_quality
;
736 wxMask
*wxBitmap::GetMask() const
738 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
740 return M_BITMAPDATA
->m_bitmapMask
;
743 void wxBitmap::SetWidth(int w
)
746 m_refData
= new wxBitmapRefData
;
748 M_BITMAPDATA
->m_width
= w
;
751 void wxBitmap::SetHeight(int h
)
754 m_refData
= new wxBitmapRefData
;
756 M_BITMAPDATA
->m_height
= h
;
759 void wxBitmap::SetDepth(int d
)
762 m_refData
= new wxBitmapRefData
;
764 M_BITMAPDATA
->m_depth
= d
;
767 void wxBitmap::SetQuality(int q
)
770 m_refData
= new wxBitmapRefData
;
772 M_BITMAPDATA
->m_quality
= q
;
775 void wxBitmap::SetOk(bool isOk
)
778 m_refData
= new wxBitmapRefData
;
780 M_BITMAPDATA
->m_ok
= isOk
;
783 wxPalette
*wxBitmap::GetPalette() const
785 wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap GetPalette()") );
787 return &M_BITMAPDATA
->m_bitmapPalette
;
790 void wxBitmap::SetPalette(const wxPalette
& palette
)
793 m_refData
= new wxBitmapRefData
;
795 M_BITMAPDATA
->m_bitmapPalette
= palette
;
798 void wxBitmap::SetMask(wxMask
*mask
)
801 m_refData
= new wxBitmapRefData
;
803 // Remove existing mask if there is one.
804 if (M_BITMAPDATA
->m_bitmapMask
)
805 delete M_BITMAPDATA
->m_bitmapMask
;
807 M_BITMAPDATA
->m_bitmapMask
= mask
;
810 WXHBITMAP
wxBitmap::GetHBITMAP() const
812 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
814 return M_BITMAPDATA
->m_hBitmap
;
817 PicHandle
wxBitmap::GetPict() const
819 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
821 PicHandle picture
; // This is the returned picture
823 // If bitmap already in Pict format return pointer
824 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
) {
825 return M_BITMAPDATA
->m_hPict
;
827 else if(M_BITMAPDATA
->m_bitmapType
!= kMacBitmapTypeGrafWorld
) {
832 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
833 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
834 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
840 GetPortBounds( GetHBITMAP() , &portRect
) ;
841 int width
= portRect
.right
- portRect
.left
;
842 int height
= portRect
.bottom
- portRect
.top
;
844 LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
845 GetGWorld( &origPort
, &origDev
) ;
849 SetGWorld( GetHBITMAP() , NULL
) ;
851 picture
= OpenPicture(&portRect
); // open a picture, this disables drawing
859 RGBColor trans
= white
;
861 RGBBackColor( &gray
);
862 EraseRect( &portRect
);
863 RGBColor trans
= gray
;
865 RGBForeColor( &black
) ;
866 RGBBackColor( &white
) ;
867 PenMode(transparent
);
869 for ( int y
= 0 ; y
< height
; ++y
)
871 for( int x
= 0 ; x
< width
; ++x
)
873 if ( !mask
->PointMasked(x
,y
) )
877 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
878 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
881 // With transparency this sets a blank pixel
882 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &trans
);
889 RGBBackColor( &gray
) ;
890 EraseRect(&portRect
);
891 RGBForeColor( &black
) ;
892 RGBBackColor( &white
) ;
894 CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),
895 // src PixMap - we copy image over itself -
896 GetPortBitMapForCopyBits(GetHBITMAP()),
897 // dst PixMap - no drawing occurs
898 &portRect
, // srcRect - it will be recorded and compressed -
899 &portRect
, // dstRect - into the picture that is open -
900 srcCopy
,NULL
); // copyMode and no clip region
902 ClosePicture(); // We are done recording the picture
903 UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
904 SetGWorld( origPort
, origDev
) ;
906 return picture
; // return our groovy pict handle
909 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
911 sm_handlers
.Append(handler
);
914 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
916 sm_handlers
.Insert(handler
);
919 bool wxBitmap::RemoveHandler(const wxString
& name
)
921 wxBitmapHandler
*handler
= FindHandler(name
);
924 sm_handlers
.DeleteObject(handler
);
931 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
933 wxNode
*node
= sm_handlers
.First();
936 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
937 if ( handler
->GetName() == name
)
944 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, wxBitmapType type
)
946 wxNode
*node
= sm_handlers
.First();
949 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
950 if ( handler
->GetExtension() == extension
&&
951 (type
== -1 || handler
->GetType() == type
) )
958 wxBitmapHandler
*wxBitmap::FindHandler(wxBitmapType type
)
960 wxNode
*node
= sm_handlers
.First();
963 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
964 if (handler
->GetType() == type
)
980 // Construct a mask from a bitmap and a colour indicating
981 // the transparent area
982 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
985 Create(bitmap
, colour
);
988 // Construct a mask from a bitmap and a palette index indicating
989 // the transparent area
990 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
993 Create(bitmap
, paletteIndex
);
996 // Construct a mask from a mono bitmap (copies the bitmap).
997 wxMask::wxMask(const wxBitmap
& bitmap
)
1007 wxMacDestroyGWorld( m_maskBitmap
) ;
1008 m_maskBitmap
= NULL
;
1012 // Create a mask from a mono bitmap (copies the bitmap).
1013 bool wxMask::Create(const wxBitmap
& bitmap
)
1017 wxMacDestroyGWorld( m_maskBitmap
) ;
1018 m_maskBitmap
= NULL
;
1020 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1021 wxT("Cannot create mask from this bitmap type (TODO)"));
1022 // other types would require a temporary bitmap. not yet implemented
1024 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap"));
1026 wxCHECK_MSG(bitmap
.GetDepth() == 1, false,
1027 wxT("Cannot create mask from colour bitmap"));
1029 m_maskBitmap
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1);
1030 Rect rect
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() };
1032 LockPixels( GetGWorldPixMap(m_maskBitmap
) );
1033 LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1034 CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()),
1035 GetPortBitMapForCopyBits(m_maskBitmap
),
1036 &rect
, &rect
, srcCopy
, 0);
1037 UnlockPixels( GetGWorldPixMap(m_maskBitmap
) );
1038 UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1043 // Create a mask from a bitmap and a palette index indicating
1044 // the transparent area
1045 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
1048 wxCHECK_MSG( 0, false, wxT("Not implemented"));
1052 // Create a mask from a bitmap and a colour indicating
1053 // the transparent area
1054 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
1058 wxMacDestroyGWorld( m_maskBitmap
) ;
1059 m_maskBitmap
= NULL
;
1061 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1062 wxT("Cannot create mask from this bitmap type (TODO)"));
1063 // other types would require a temporary bitmap. not yet implemented
1065 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap"));
1067 m_maskBitmap
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );
1068 LockPixels( GetGWorldPixMap( m_maskBitmap
) );
1069 LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) );
1070 RGBColor maskColor
= colour
.GetPixel();
1072 // this is not very efficient, but I can't think
1073 // of a better way of doing it
1075 GDHandle origDevice
;
1077 RGBColor colors
[2] = {
1078 { 0xFFFF, 0xFFFF, 0xFFFF },
1081 GetGWorld( &origPort
, &origDevice
) ;
1082 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
1084 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
1086 SetGWorld( bitmap
.GetHBITMAP(), NULL
) ;
1087 GetCPixel( w
, h
, &col
) ;
1088 SetGWorld( m_maskBitmap
, NULL
) ;
1089 if (col
.red
== maskColor
.red
&& col
.green
== maskColor
.green
&& col
.blue
== maskColor
.blue
)
1091 SetCPixel( w
, h
, &colors
[0] ) ;
1095 SetCPixel( w
, h
, &colors
[1] ) ;
1099 UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap
) ) ;
1100 UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ;
1101 SetGWorld( origPort
, origDevice
) ;
1106 bool wxMask::PointMasked(int x
, int y
)
1109 GDHandle origDevice
;
1113 GetGWorld( &origPort
, &origDevice
);
1115 //Set port to mask and see if it masked (1) or not ( 0 )
1116 SetGWorld(m_maskBitmap
, NULL
);
1117 LockPixels(GetGWorldPixMap(m_maskBitmap
));
1118 GetCPixel(x
,y
, &color
);
1119 masked
= !(color
.red
== 0 && color
.green
== 0 && color
.blue
== 0);
1120 UnlockPixels(GetGWorldPixMap(m_maskBitmap
));
1122 SetGWorld( origPort
, origDevice
);
1131 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
1133 bool wxBitmapHandler::Create(wxBitmap
*bitmap
, void *data
, long type
, int width
, int height
, int depth
)
1138 bool wxBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1139 int desiredWidth
, int desiredHeight
)
1144 bool wxBitmapHandler::SaveFile(const wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1153 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
1155 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
)
1157 inline wxPICTResourceHandler()
1159 m_name
= "Macintosh Pict resource";
1161 m_type
= wxBITMAP_TYPE_PICT_RESOURCE
;
1164 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1165 int desiredWidth
, int desiredHeight
);
1167 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
)
1169 bool wxPICTResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1170 int desiredWidth
, int desiredHeight
)
1175 c2pstrcpy( (StringPtr
) theName
, name
) ;
1177 strcpy( (char *) theName
, name
) ;
1178 c2pstr( (char *)theName
) ;
1181 PicHandle thePict
= (PicHandle
) GetNamedResource( 'PICT' , theName
) ;
1186 GetPictInfo( thePict
, &theInfo
, 0 , 0 , systemMethod
, 0 ) ;
1187 DetachResource( (Handle
) thePict
) ;
1188 M_BITMAPHANDLERDATA
->m_bitmapType
= kMacBitmapTypePict
;
1189 M_BITMAPHANDLERDATA
->m_hPict
= thePict
;
1190 M_BITMAPHANDLERDATA
->m_width
= theInfo
.sourceRect
.right
- theInfo
.sourceRect
.left
;
1191 M_BITMAPHANDLERDATA
->m_height
= theInfo
.sourceRect
.bottom
- theInfo
.sourceRect
.top
;
1193 M_BITMAPHANDLERDATA
->m_depth
= theInfo
.depth
;
1194 M_BITMAPHANDLERDATA
->m_ok
= true ;
1195 M_BITMAPHANDLERDATA
->m_numColors
= theInfo
.uniqueColors
;
1196 // M_BITMAPHANDLERDATA->m_bitmapPalette;
1197 // M_BITMAPHANDLERDATA->m_quality;
1203 #if 0 // The following is an example for creating a bitmap handler
1205 // TODO: bitmap handlers, a bit like this:
1206 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
1208 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
1210 inline wxBMPResourceHandler()
1212 m_name
= "Windows bitmap resource";
1214 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
1217 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1218 int desiredWidth
, int desiredHeight
);
1220 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
1224 void wxBitmap::CleanUpHandlers()
1226 wxNode
*node
= sm_handlers
.First();
1229 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
1230 wxNode
*next
= node
->Next();
1237 void wxBitmap::InitStandardHandlers()
1239 AddHandler(new wxPICTResourceHandler
) ;
1240 AddHandler(new wxICONResourceHandler
) ;