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 // TODO move this do a public function of Bitmap Ref
203 static void DisposeBitmapRefData(wxBitmapRefData
*data
)
205 switch (data
->m_bitmapType
)
207 case kMacBitmapTypePict
:
211 KillPicture( data
->m_hPict
) ;
212 data
->m_hPict
= NULL
;
216 case kMacBitmapTypeGrafWorld
:
218 if ( data
->m_hBitmap
)
220 wxMacDestroyGWorld( data
->m_hBitmap
) ;
221 data
->m_hBitmap
= NULL
;
225 case kMacBitmapTypeIcon
:
228 DisposeCIcon( data
->m_hIcon
) ;
229 data
->m_hIcon
= NULL
;
237 if (data
->m_bitmapMask
)
239 delete data
->m_bitmapMask
;
240 data
->m_bitmapMask
= NULL
;
244 wxBitmapRefData::~wxBitmapRefData()
246 DisposeBitmapRefData( this ) ;
249 wxList
wxBitmapBase::sm_handlers
;
252 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
262 if ( wxTheBitmapList
)
263 wxTheBitmapList
->AddBitmap(this);
266 wxBitmap::~wxBitmap()
269 wxTheBitmapList
->DeleteObject(this);
272 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
274 m_refData
= new wxBitmapRefData
;
276 M_BITMAPDATA
->m_width
= the_width
;
277 M_BITMAPDATA
->m_height
= the_height
;
278 M_BITMAPDATA
->m_depth
= no_bits
;
279 M_BITMAPDATA
->m_numColors
= 0;
282 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
283 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( the_width
, the_height
, no_bits
) ;
284 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
287 GDHandle origDevice
;
289 GetGWorld( &origPort
, &origDevice
) ;
290 SetGWorld( M_BITMAPDATA
->m_hBitmap
, NULL
) ;
291 LockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
293 // bits is a char array
295 unsigned char* linestart
= (unsigned char*) bits
;
296 int linesize
= ( the_width
/ (sizeof(unsigned char) * 8)) ;
297 if ( the_width
% (sizeof(unsigned char) * 8) ) {
298 linesize
+= sizeof(unsigned char);
301 RGBColor colors
[2] = {
302 { 0xFFFF , 0xFFFF , 0xFFFF } ,
306 for ( int y
= 0 ; y
< the_height
; ++y
, linestart
+= linesize
)
308 for ( int x
= 0 ; x
< the_width
; ++x
)
312 int mask
= 1 << bit
;
313 if ( linestart
[index
] & mask
)
315 SetCPixel( x
, y
, &colors
[1] ) ;
319 SetCPixel( x
, y
, &colors
[0] ) ;
323 UnlockPixels( GetGWorldPixMap( M_BITMAPDATA
->m_hBitmap
) ) ;
325 SetGWorld( origPort
, origDevice
) ;
329 wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
332 if ( wxTheBitmapList
) {
333 wxTheBitmapList
->AddBitmap(this);
337 wxBitmap::wxBitmap(int w
, int h
, int d
)
339 (void)Create(w
, h
, d
);
341 if ( wxTheBitmapList
)
342 wxTheBitmapList
->AddBitmap(this);
345 wxBitmap::wxBitmap(void *data
, wxBitmapType type
, int width
, int height
, int depth
)
347 (void) Create(data
, type
, width
, height
, depth
);
349 if ( wxTheBitmapList
)
350 wxTheBitmapList
->AddBitmap(this);
353 wxBitmap::wxBitmap(const wxString
& filename
, wxBitmapType type
)
355 LoadFile(filename
, type
);
357 if ( wxTheBitmapList
)
358 wxTheBitmapList
->AddBitmap(this);
361 bool wxBitmap::CreateFromXpm(const char **bits
)
363 wxCHECK_MSG( bits
!= NULL
, FALSE
, wxT("invalid bitmap data") )
364 wxXPMDecoder decoder
;
365 wxImage img
= decoder
.ReadData(bits
);
366 wxCHECK_MSG( img
.Ok(), FALSE
, wxT("invalid bitmap data") )
367 *this = wxBitmap(img
);
368 if ( wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
372 wxBitmap::wxBitmap(const char **bits
)
374 (void) CreateFromXpm(bits
);
377 wxBitmap::wxBitmap(char **bits
)
379 (void) CreateFromXpm((const char **)bits
);
382 wxBitmap
wxBitmap::GetSubBitmap(const wxRect
&rect
) const
385 (rect
.x
>= 0) && (rect
.y
>= 0) &&
386 (rect
.x
+rect
.width
<= GetWidth()) &&
387 (rect
.y
+rect
.height
<= GetHeight()),
388 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
391 wxBitmap
ret( rect
.width
, rect
.height
, GetDepth() );
392 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
397 GetGWorld( &origPort
, &origDevice
);
399 // Update the subbitmaps reference data
400 wxBitmapRefData
*ref
= (wxBitmapRefData
*)ret
.GetRefData();
402 ref
->m_numColors
= M_BITMAPDATA
->m_numColors
;
403 ref
->m_bitmapPalette
= M_BITMAPDATA
->m_bitmapPalette
;
404 ref
->m_bitmapType
= M_BITMAPDATA
->m_bitmapType
;
406 // Copy sub region of this bitmap
407 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
)
409 printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
411 else if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
416 WXHBITMAP submask
, mask
;
419 mask
= GetMask()->GetMaskBitmap();
420 submask
= wxMacCreateGWorld(rect
.width
, rect
.height
, 1);
421 LockPixels(GetGWorldPixMap(mask
));
422 LockPixels(GetGWorldPixMap(submask
));
424 for(int yy
= 0; yy
< rect
.height
; yy
++)
426 for(int xx
= 0; xx
< rect
.width
; xx
++)
428 SetGWorld(mask
, NULL
);
429 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
430 SetGWorld(submask
, NULL
);
431 SetCPixel(xx
,yy
, &color
);
434 UnlockPixels(GetGWorldPixMap(mask
));
435 UnlockPixels(GetGWorldPixMap(submask
));
436 ref
->m_bitmapMask
= new wxMask
;
437 ref
->m_bitmapMask
->SetMaskBitmap(submask
);
443 WXHBITMAP subbitmap
, bitmap
;
446 bitmap
= GetHBITMAP();
447 subbitmap
= ref
->m_hBitmap
;
448 LockPixels(GetGWorldPixMap(bitmap
));
449 LockPixels(GetGWorldPixMap(subbitmap
));
451 for(int yy
= 0; yy
< rect
.height
; yy
++)
453 for(int xx
= 0; xx
< rect
.width
; xx
++)
455 SetGWorld(bitmap
, NULL
);
456 GetCPixel(rect
.x
+ xx
, rect
.y
+ yy
, &color
);
457 SetGWorld(subbitmap
, NULL
);
458 SetCPixel(xx
, yy
, &color
);
461 UnlockPixels(GetGWorldPixMap(bitmap
));
462 UnlockPixels(GetGWorldPixMap(subbitmap
));
465 SetGWorld( origPort
, origDevice
);
470 bool wxBitmap::Create(int w
, int h
, int d
)
474 m_refData
= new wxBitmapRefData
;
476 M_BITMAPDATA
->m_width
= w
;
477 M_BITMAPDATA
->m_height
= h
;
478 M_BITMAPDATA
->m_depth
= d
;
480 M_BITMAPDATA
->m_bitmapType
= kMacBitmapTypeGrafWorld
;
481 M_BITMAPDATA
->m_hBitmap
= wxMacCreateGWorld( w
, h
, d
) ;
482 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_hBitmap
!= NULL
) ;
483 return M_BITMAPDATA
->m_ok
;
486 int wxBitmap::GetBitmapType() const
488 wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType
, wxT("invalid bitmap") );
490 return M_BITMAPDATA
->m_bitmapType
;
493 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
495 DisposeBitmapRefData( M_BITMAPDATA
) ;
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
, wxBitmapType type
)
506 wxBitmapHandler
*handler
= FindHandler(type
);
510 m_refData
= new wxBitmapRefData
;
512 return handler
->LoadFile(this, filename
, type
, -1, -1);
516 wxImage
loadimage(filename
, type
);
517 if (loadimage
.Ok()) {
522 wxLogWarning("no bitmap handler for type %d defined.", type
);
526 bool wxBitmap::Create(void *data
, wxBitmapType type
, int width
, int height
, int depth
)
530 m_refData
= new wxBitmapRefData
;
532 wxBitmapHandler
*handler
= FindHandler(type
);
534 if ( handler
== NULL
) {
535 wxLogWarning("no bitmap handler for type %d defined.", type
);
540 return handler
->Create(this, data
, type
, width
, height
, depth
);
543 wxBitmap::wxBitmap(const wxImage
& image
, int depth
)
545 wxCHECK_RET( image
.Ok(), wxT("invalid image") )
546 wxCHECK_RET( depth
== -1, wxT("invalid bitmap depth") )
548 m_refData
= new wxBitmapRefData();
550 if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
552 // width and height of the device-dependent bitmap
553 int width
= image
.GetWidth();
554 int height
= image
.GetHeight();
558 Create( width
, height
, 32 ) ;
561 GDHandle origDevice
;
563 PixMapHandle pixMap
= GetGWorldPixMap(GetHBITMAP()) ;
564 LockPixels( pixMap
);
566 GetGWorld( &origPort
, &origDevice
) ;
567 SetGWorld( GetHBITMAP() , NULL
) ;
572 register unsigned char* data
= image
.GetData();
573 char* destinationBase
= GetPixBaseAddr( pixMap
);
574 register unsigned char* destination
= (unsigned char*) destinationBase
;
575 for (int y
= 0; y
< height
; y
++)
577 for (int x
= 0; x
< width
; x
++)
580 *destination
++ = *data
++ ;
581 *destination
++ = *data
++ ;
582 *destination
++ = *data
++ ;
584 destinationBase
+= ((**pixMap
).rowBytes
& 0x7fff);
585 destination
= (unsigned char*) destinationBase
;
587 if ( image
.HasMask() )
589 data
= image
.GetData();
591 wxColour
maskcolor(image
.GetMaskRed(), image
.GetMaskGreen(), image
.GetMaskBlue());
592 RGBColor white
= { 0xffff, 0xffff, 0xffff };
593 RGBColor black
= { 0 , 0 , 0 };
594 wxBitmap maskBitmap
;
596 maskBitmap
.Create( width
, height
, 1);
597 LockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
598 SetGWorld(maskBitmap
.GetHBITMAP(), NULL
);
600 for (int y
= 0; y
< height
; y
++)
602 for (int x
= 0; x
< width
; x
++)
604 if ( data
[0] == image
.GetMaskRed() && data
[1] == image
.GetMaskGreen() && data
[2] == image
.GetMaskBlue() )
606 SetCPixel(x
,y
, &white
);
609 SetCPixel(x
,y
, &black
);
614 SetGWorld(GetHBITMAP(), NULL
);
615 SetMask(new wxMask( maskBitmap
));
616 UnlockPixels( GetGWorldPixMap(maskBitmap
.GetHBITMAP()) );
619 UnlockPixels( GetGWorldPixMap(GetHBITMAP()) );
620 SetGWorld( origPort
, origDevice
);
623 wxImage
wxBitmap::ConvertToImage() const
627 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
629 // create an wxImage object
630 int width
= GetWidth();
631 int height
= GetHeight();
632 image
.Create( width
, height
);
634 unsigned char *data
= image
.GetData();
636 wxCHECK_MSG( data
, wxNullImage
, wxT("Could not allocate data for image") );
642 // background color set to RGB(16,16,16) in consistent with wxGTK
643 unsigned char mask_r
=16, mask_g
=16, mask_b
=16;
645 wxMask
*mask
= GetMask();
647 GetGWorld( &origPort
, &origDevice
);
648 LockPixels(GetGWorldPixMap(GetHBITMAP()));
649 SetGWorld( GetHBITMAP(), NULL
);
651 // Copy data into image
653 for (int yy
= 0; yy
< height
; yy
++)
655 for (int xx
= 0; xx
< width
; xx
++)
657 GetCPixel(xx
,yy
, &color
);
658 r
= ((color
.red
) >> 8);
659 g
= ((color
.green
) >> 8);
660 b
= ((color
.blue
) >> 8);
666 if (mask
->PointMasked(xx
,yy
))
668 data
[index
] = mask_r
;
669 data
[index
+ 1] = mask_g
;
670 data
[index
+ 2] = mask_b
;
678 image
.SetMaskColour( mask_r
, mask_g
, mask_b
);
679 image
.SetMask( true );
683 UnlockPixels(GetGWorldPixMap(GetHBITMAP()));
684 SetGWorld(origPort
, origDevice
);
690 bool wxBitmap::SaveFile(const wxString
& filename
, wxBitmapType type
,
691 const wxPalette
*palette
) const
693 wxBitmapHandler
*handler
= FindHandler(type
);
697 return handler
->SaveFile(this, filename
, type
, palette
);
701 wxImage image
= ConvertToImage();
703 return image
.SaveFile(filename
, type
);
706 wxLogWarning("no bitmap handler for type %d defined.", type
);
710 bool wxBitmap::Ok() const
712 return (M_BITMAPDATA
&& M_BITMAPDATA
->m_ok
);
715 int wxBitmap::GetHeight() const
717 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
719 return M_BITMAPDATA
->m_height
;
722 int wxBitmap::GetWidth() const
724 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
726 return M_BITMAPDATA
->m_width
;
729 int wxBitmap::GetDepth() const
731 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
733 return M_BITMAPDATA
->m_depth
;
736 int wxBitmap::GetQuality() const
738 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
740 return M_BITMAPDATA
->m_quality
;
743 wxMask
*wxBitmap::GetMask() const
745 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
747 return M_BITMAPDATA
->m_bitmapMask
;
750 void wxBitmap::SetWidth(int w
)
753 m_refData
= new wxBitmapRefData
;
755 M_BITMAPDATA
->m_width
= w
;
758 void wxBitmap::SetHeight(int h
)
761 m_refData
= new wxBitmapRefData
;
763 M_BITMAPDATA
->m_height
= h
;
766 void wxBitmap::SetDepth(int d
)
769 m_refData
= new wxBitmapRefData
;
771 M_BITMAPDATA
->m_depth
= d
;
774 void wxBitmap::SetQuality(int q
)
777 m_refData
= new wxBitmapRefData
;
779 M_BITMAPDATA
->m_quality
= q
;
782 void wxBitmap::SetOk(bool isOk
)
785 m_refData
= new wxBitmapRefData
;
787 M_BITMAPDATA
->m_ok
= isOk
;
790 wxPalette
*wxBitmap::GetPalette() const
792 wxCHECK_MSG( Ok(), NULL
, wxT("Invalid bitmap GetPalette()") );
794 return &M_BITMAPDATA
->m_bitmapPalette
;
797 void wxBitmap::SetPalette(const wxPalette
& palette
)
800 m_refData
= new wxBitmapRefData
;
802 M_BITMAPDATA
->m_bitmapPalette
= palette
;
805 void wxBitmap::SetMask(wxMask
*mask
)
808 m_refData
= new wxBitmapRefData
;
810 // Remove existing mask if there is one.
811 if (M_BITMAPDATA
->m_bitmapMask
)
812 delete M_BITMAPDATA
->m_bitmapMask
;
814 M_BITMAPDATA
->m_bitmapMask
= mask
;
817 WXHBITMAP
wxBitmap::GetHBITMAP() const
819 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
821 return M_BITMAPDATA
->m_hBitmap
;
824 PicHandle
wxBitmap::GetPict() const
826 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
828 PicHandle picture
; // This is the returned picture
830 // If bitmap already in Pict format return pointer
831 if(M_BITMAPDATA
->m_bitmapType
== kMacBitmapTypePict
) {
832 return M_BITMAPDATA
->m_hPict
;
834 else if(M_BITMAPDATA
->m_bitmapType
!= kMacBitmapTypeGrafWorld
) {
839 RGBColor gray
= { 0xCCCC ,0xCCCC , 0xCCCC } ;
840 RGBColor white
= { 0xffff ,0xffff , 0xffff } ;
841 RGBColor black
= { 0x0000 ,0x0000 , 0x0000 } ;
847 GetPortBounds( GetHBITMAP() , &portRect
) ;
848 int width
= portRect
.right
- portRect
.left
;
849 int height
= portRect
.bottom
- portRect
.top
;
851 LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
852 GetGWorld( &origPort
, &origDev
) ;
856 SetGWorld( GetHBITMAP() , NULL
) ;
858 picture
= OpenPicture(&portRect
); // open a picture, this disables drawing
866 RGBColor trans
= white
;
868 RGBBackColor( &gray
);
869 EraseRect( &portRect
);
870 RGBColor trans
= gray
;
872 RGBForeColor( &black
) ;
873 RGBBackColor( &white
) ;
874 PenMode(transparent
);
876 for ( int y
= 0 ; y
< height
; ++y
)
878 for( int x
= 0 ; x
< width
; ++x
)
880 if ( !mask
->PointMasked(x
,y
) )
884 GetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
885 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &col
) ;
888 // With transparency this sets a blank pixel
889 SetCPixel( x
+ portRect
.left
, y
+ portRect
.top
, &trans
);
896 RGBBackColor( &gray
) ;
897 EraseRect(&portRect
);
898 RGBForeColor( &black
) ;
899 RGBBackColor( &white
) ;
901 CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()),
902 // src PixMap - we copy image over itself -
903 GetPortBitMapForCopyBits(GetHBITMAP()),
904 // dst PixMap - no drawing occurs
905 &portRect
, // srcRect - it will be recorded and compressed -
906 &portRect
, // dstRect - into the picture that is open -
907 srcCopy
,NULL
); // copyMode and no clip region
909 ClosePicture(); // We are done recording the picture
910 UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ;
911 SetGWorld( origPort
, origDev
) ;
913 return picture
; // return our groovy pict handle
916 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
918 sm_handlers
.Append(handler
);
921 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
923 sm_handlers
.Insert(handler
);
926 bool wxBitmap::RemoveHandler(const wxString
& name
)
928 wxBitmapHandler
*handler
= FindHandler(name
);
931 sm_handlers
.DeleteObject(handler
);
938 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
940 wxNode
*node
= sm_handlers
.First();
943 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
944 if ( handler
->GetName() == name
)
951 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, wxBitmapType type
)
953 wxNode
*node
= sm_handlers
.First();
956 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
957 if ( handler
->GetExtension() == extension
&&
958 (type
== -1 || handler
->GetType() == type
) )
965 wxBitmapHandler
*wxBitmap::FindHandler(wxBitmapType type
)
967 wxNode
*node
= sm_handlers
.First();
970 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
971 if (handler
->GetType() == type
)
987 // Construct a mask from a bitmap and a colour indicating
988 // the transparent area
989 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
992 Create(bitmap
, colour
);
995 // Construct a mask from a bitmap and a palette index indicating
996 // the transparent area
997 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
1000 Create(bitmap
, paletteIndex
);
1003 // Construct a mask from a mono bitmap (copies the bitmap).
1004 wxMask::wxMask(const wxBitmap
& bitmap
)
1014 wxMacDestroyGWorld( m_maskBitmap
) ;
1015 m_maskBitmap
= NULL
;
1019 // Create a mask from a mono bitmap (copies the bitmap).
1020 bool wxMask::Create(const wxBitmap
& bitmap
)
1024 wxMacDestroyGWorld( m_maskBitmap
) ;
1025 m_maskBitmap
= NULL
;
1027 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1028 wxT("Cannot create mask from this bitmap type (TODO)"));
1029 // other types would require a temporary bitmap. not yet implemented
1031 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Invalid bitmap"));
1033 wxCHECK_MSG(bitmap
.GetDepth() == 1, false,
1034 wxT("Cannot create mask from colour bitmap"));
1036 m_maskBitmap
= wxMacCreateGWorld(bitmap
.GetWidth(), bitmap
.GetHeight(), 1);
1037 Rect rect
= { 0,0, bitmap
.GetHeight(), bitmap
.GetWidth() };
1039 LockPixels( GetGWorldPixMap(m_maskBitmap
) );
1040 LockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1041 CopyBits(GetPortBitMapForCopyBits(bitmap
.GetHBITMAP()),
1042 GetPortBitMapForCopyBits(m_maskBitmap
),
1043 &rect
, &rect
, srcCopy
, 0);
1044 UnlockPixels( GetGWorldPixMap(m_maskBitmap
) );
1045 UnlockPixels( GetGWorldPixMap(bitmap
.GetHBITMAP()) );
1050 // Create a mask from a bitmap and a palette index indicating
1051 // the transparent area
1052 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
1055 wxCHECK_MSG( 0, false, wxT("Not implemented"));
1059 // Create a mask from a bitmap and a colour indicating
1060 // the transparent area
1061 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
1065 wxMacDestroyGWorld( m_maskBitmap
) ;
1066 m_maskBitmap
= NULL
;
1068 wxCHECK_MSG( bitmap
.GetBitmapType() == kMacBitmapTypeGrafWorld
, false,
1069 wxT("Cannot create mask from this bitmap type (TODO)"));
1070 // other types would require a temporary bitmap. not yet implemented
1072 wxCHECK_MSG( bitmap
.Ok(), false, wxT("Illigal bitmap"));
1074 m_maskBitmap
= wxMacCreateGWorld( bitmap
.GetWidth() , bitmap
.GetHeight() , 1 );
1075 LockPixels( GetGWorldPixMap( m_maskBitmap
) );
1076 LockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) );
1077 RGBColor maskColor
= colour
.GetPixel();
1079 // this is not very efficient, but I can't think
1080 // of a better way of doing it
1082 GDHandle origDevice
;
1084 RGBColor colors
[2] = {
1085 { 0xFFFF, 0xFFFF, 0xFFFF },
1088 GetGWorld( &origPort
, &origDevice
) ;
1089 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
1091 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
1093 SetGWorld( bitmap
.GetHBITMAP(), NULL
) ;
1094 GetCPixel( w
, h
, &col
) ;
1095 SetGWorld( m_maskBitmap
, NULL
) ;
1096 if (col
.red
== maskColor
.red
&& col
.green
== maskColor
.green
&& col
.blue
== maskColor
.blue
)
1098 SetCPixel( w
, h
, &colors
[0] ) ;
1102 SetCPixel( w
, h
, &colors
[1] ) ;
1106 UnlockPixels( GetGWorldPixMap( (CGrafPtr
) m_maskBitmap
) ) ;
1107 UnlockPixels( GetGWorldPixMap( bitmap
.GetHBITMAP() ) ) ;
1108 SetGWorld( origPort
, origDevice
) ;
1113 bool wxMask::PointMasked(int x
, int y
)
1116 GDHandle origDevice
;
1120 GetGWorld( &origPort
, &origDevice
);
1122 //Set port to mask and see if it masked (1) or not ( 0 )
1123 SetGWorld(m_maskBitmap
, NULL
);
1124 LockPixels(GetGWorldPixMap(m_maskBitmap
));
1125 GetCPixel(x
,y
, &color
);
1126 masked
= !(color
.red
== 0 && color
.green
== 0 && color
.blue
== 0);
1127 UnlockPixels(GetGWorldPixMap(m_maskBitmap
));
1129 SetGWorld( origPort
, origDevice
);
1138 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
1140 bool wxBitmapHandler::Create(wxBitmap
*bitmap
, void *data
, long type
, int width
, int height
, int depth
)
1145 bool wxBitmapHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1146 int desiredWidth
, int desiredHeight
)
1151 bool wxBitmapHandler::SaveFile(const wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
)
1160 class WXDLLEXPORT wxPICTResourceHandler
: public wxBitmapHandler
1162 DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler
)
1164 inline wxPICTResourceHandler()
1166 m_name
= "Macintosh Pict resource";
1168 m_type
= wxBITMAP_TYPE_PICT_RESOURCE
;
1171 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1172 int desiredWidth
, int desiredHeight
);
1174 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler
, wxBitmapHandler
)
1176 bool wxPICTResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1177 int desiredWidth
, int desiredHeight
)
1182 c2pstrcpy( (StringPtr
) theName
, name
) ;
1184 strcpy( (char *) theName
, name
) ;
1185 c2pstr( (char *)theName
) ;
1188 PicHandle thePict
= (PicHandle
) GetNamedResource( 'PICT' , theName
) ;
1193 GetPictInfo( thePict
, &theInfo
, 0 , 0 , systemMethod
, 0 ) ;
1194 DetachResource( (Handle
) thePict
) ;
1195 M_BITMAPHANDLERDATA
->m_bitmapType
= kMacBitmapTypePict
;
1196 M_BITMAPHANDLERDATA
->m_hPict
= thePict
;
1197 M_BITMAPHANDLERDATA
->m_width
= theInfo
.sourceRect
.right
- theInfo
.sourceRect
.left
;
1198 M_BITMAPHANDLERDATA
->m_height
= theInfo
.sourceRect
.bottom
- theInfo
.sourceRect
.top
;
1200 M_BITMAPHANDLERDATA
->m_depth
= theInfo
.depth
;
1201 M_BITMAPHANDLERDATA
->m_ok
= true ;
1202 M_BITMAPHANDLERDATA
->m_numColors
= theInfo
.uniqueColors
;
1203 // M_BITMAPHANDLERDATA->m_bitmapPalette;
1204 // M_BITMAPHANDLERDATA->m_quality;
1210 #if 0 // The following is an example for creating a bitmap handler
1212 // TODO: bitmap handlers, a bit like this:
1213 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
1215 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
1217 inline wxBMPResourceHandler()
1219 m_name
= "Windows bitmap resource";
1221 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
1224 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
1225 int desiredWidth
, int desiredHeight
);
1227 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
1231 void wxBitmap::CleanUpHandlers()
1233 wxNode
*node
= sm_handlers
.First();
1236 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
1237 wxNode
*next
= node
->Next();
1244 void wxBitmap::InitStandardHandlers()
1246 AddHandler(new wxPICTResourceHandler
) ;
1247 AddHandler(new wxICONResourceHandler
) ;