]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/bitmap.cpp
c296558642e3163dda0ba3766da33ecb6acb5714
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/bitmap.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 #include "wx/bitmap.h" 
  18     #include "wx/colour.h" 
  21 #include "wx/rawbmp.h" 
  23 #include "wx/gtk/private/object.h" 
  27 extern GtkWidget 
*wxGetRootWindow(); 
  29 static void PixmapToPixbuf(GdkPixmap
* pixmap
, GdkPixbuf
* pixbuf
, int w
, int h
) 
  31     gdk_pixbuf_get_from_drawable(pixbuf
, pixmap
, NULL
, 0, 0, 0, 0, w
, h
); 
  32     if (gdk_drawable_get_depth(pixmap
) == 1) 
  34         // invert to match XBM convention 
  35         guchar
* p 
= gdk_pixbuf_get_pixels(pixbuf
); 
  36         const int inc 
= 3 + int(gdk_pixbuf_get_has_alpha(pixbuf
) != 0); 
  37         const int rowpad 
= gdk_pixbuf_get_rowstride(pixbuf
) - w 
* inc
; 
  38         for (int y 
= h
; y
; y
--, p 
+= rowpad
) 
  39             for (int x 
= w
; x
; x
--, p 
+= inc
) 
  41                 // pixels are either (0,0,0) or (0xff,0xff,0xff) 
  49 static void MaskToAlpha(GdkPixmap
* mask
, GdkPixbuf
* pixbuf
, int w
, int h
) 
  51     GdkPixbuf
* mask_pixbuf 
= gdk_pixbuf_get_from_drawable( 
  52         NULL
, mask
, NULL
, 0, 0, 0, 0, w
, h
); 
  53     guchar
* p 
= gdk_pixbuf_get_pixels(pixbuf
) + 3; 
  54     const guchar
* mask_data 
= gdk_pixbuf_get_pixels(mask_pixbuf
); 
  55     const int rowpad 
= gdk_pixbuf_get_rowstride(pixbuf
) - w 
* 4; 
  56     const int mask_rowpad 
= gdk_pixbuf_get_rowstride(mask_pixbuf
) - w 
* 3; 
  57     for (int y 
= h
; y
; y
--, p 
+= rowpad
, mask_data 
+= mask_rowpad
) 
  59         for (int x 
= w
; x
; x
--, p 
+= 4, mask_data 
+= 3) 
  62             // no need to test all 3 components, 
  63             //   pixels are either (0,0,0) or (0xff,0xff,0xff) 
  64             if (mask_data
[0] == 0) 
  68     g_object_unref(mask_pixbuf
); 
  71 //----------------------------------------------------------------------------- 
  73 //----------------------------------------------------------------------------- 
  75 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxMaskBase
) 
  82 wxMask::wxMask(const wxMask
& mask
) 
  90     // create a copy of an existing mask 
  92     gdk_drawable_get_size(mask
.m_bitmap
, &w
, &h
); 
  93     m_bitmap 
= gdk_pixmap_new(mask
.m_bitmap
, w
, h
, 1); 
  95     wxGtkObject
<GdkGC
> gc(gdk_gc_new(m_bitmap
)); 
  96     gdk_draw_drawable(m_bitmap
, gc
, mask
.m_bitmap
, 0, 0, 0, 0, -1, -1); 
  99 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour 
) 
 102     InitFromColour(bitmap
, colour
); 
 106 wxMask::wxMask( const wxBitmap
& bitmap
, int paletteIndex 
) 
 109     Create( bitmap
, paletteIndex 
); 
 111 #endif // wxUSE_PALETTE 
 113 wxMask::wxMask( const wxBitmap
& bitmap 
) 
 116     InitFromMonoBitmap(bitmap
); 
 122         g_object_unref (m_bitmap
); 
 125 void wxMask::FreeData() 
 129         g_object_unref (m_bitmap
); 
 134 bool wxMask::InitFromColour(const wxBitmap
& bitmap
, const wxColour
& colour
) 
 136     const int w 
= bitmap
.GetWidth(); 
 137     const int h 
= bitmap
.GetHeight(); 
 139     // create mask as XBM format bitmap 
 141     // one bit per pixel, each row starts on a byte boundary 
 142     const size_t out_size 
= size_t((w 
+ 7) / 8) * unsigned(h
); 
 143     wxByte
* out 
= new wxByte
[out_size
]; 
 144     // set bits are unmasked 
 145     memset(out
, 0xff, out_size
); 
 146     unsigned bit_index 
= 0; 
 147     if (bitmap
.HasPixbuf()) 
 149         const wxByte r_mask 
= colour
.Red(); 
 150         const wxByte g_mask 
= colour
.Green(); 
 151         const wxByte b_mask 
= colour
.Blue(); 
 152         GdkPixbuf
* pixbuf 
= bitmap
.GetPixbuf(); 
 153         const wxByte
* in 
= gdk_pixbuf_get_pixels(pixbuf
); 
 154         const int inc 
= 3 + int(gdk_pixbuf_get_has_alpha(pixbuf
) != 0); 
 155         const int rowpadding 
= gdk_pixbuf_get_rowstride(pixbuf
) - inc 
* w
; 
 156         for (int y 
= 0; y 
< h
; y
++, in 
+= rowpadding
) 
 158             for (int x 
= 0; x 
< w
; x
++, in 
+= inc
, bit_index
++) 
 159                 if (in
[0] == r_mask 
&& in
[1] == g_mask 
&& in
[2] == b_mask
) 
 160                     out
[bit_index 
>> 3] ^= 1 << (bit_index 
& 7); 
 161             // move index to next byte boundary 
 162             bit_index 
= (bit_index 
+ 7) & ~7u; 
 167         GdkImage
* image 
= gdk_drawable_get_image(bitmap
.GetPixmap(), 0, 0, w
, h
); 
 168         GdkColormap
* colormap 
= gdk_image_get_colormap(image
); 
 170         if (colormap 
== NULL
) 
 171             // mono bitmap, white is pixel value 0 
 172             mask_pixel 
= guint32(colour
.Red() != 255 || colour
.Green() != 255 || colour
.Blue() != 255); 
 176             c
.CalcPixel(colormap
); 
 177             mask_pixel 
= c
.GetPixel(); 
 179         for (int y 
= 0; y 
< h
; y
++) 
 181             for (int x 
= 0; x 
< w
; x
++, bit_index
++) 
 182                 if (gdk_image_get_pixel(image
, x
, y
) == mask_pixel
) 
 183                     out
[bit_index 
>> 3] ^= 1 << (bit_index 
& 7); 
 184             bit_index 
= (bit_index 
+ 7) & ~7u; 
 186         g_object_unref(image
); 
 188     m_bitmap 
= gdk_bitmap_create_from_data(wxGetRootWindow()->window
, (char*)out
, w
, h
); 
 193 bool wxMask::InitFromMonoBitmap(const wxBitmap
& bitmap
) 
 195     if (!bitmap
.IsOk()) return false; 
 197     wxCHECK_MSG( bitmap
.GetDepth() == 1, false, wxT("Cannot create mask from colour bitmap") ); 
 199     m_bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, bitmap
.GetWidth(), bitmap
.GetHeight(), 1 ); 
 201     if (!m_bitmap
) return false; 
 203     wxGtkObject
<GdkGC
> gc(gdk_gc_new( m_bitmap 
)); 
 204     gdk_gc_set_function(gc
, GDK_COPY_INVERT
); 
 205     gdk_draw_drawable(m_bitmap
, gc
, bitmap
.GetPixmap(), 0, 0, 0, 0, bitmap
.GetWidth(), bitmap
.GetHeight()); 
 210 GdkBitmap 
*wxMask::GetBitmap() const 
 215 //----------------------------------------------------------------------------- 
 217 //----------------------------------------------------------------------------- 
 219 class wxBitmapRefData
: public wxGDIRefData
 
 222     wxBitmapRefData(int width
, int height
, int depth
); 
 223     virtual ~wxBitmapRefData(); 
 225     virtual bool IsOk() const; 
 233     bool m_alphaRequested
; 
 236 wxBitmapRefData::wxBitmapRefData(int width
, int height
, int depth
) 
 245         m_bpp 
= gdk_drawable_get_depth(wxGetRootWindow()->window
); 
 246     m_alphaRequested 
= depth 
== 32; 
 249 wxBitmapRefData::~wxBitmapRefData() 
 252         g_object_unref (m_pixmap
); 
 254         g_object_unref (m_pixbuf
); 
 258 bool wxBitmapRefData::IsOk() const 
 263 //----------------------------------------------------------------------------- 
 265 //----------------------------------------------------------------------------- 
 267 #define M_BMPDATA static_cast<wxBitmapRefData*>(m_refData) 
 269 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxGDIObject
) 
 271 wxBitmap::wxBitmap(const wxString 
&filename
, wxBitmapType type
) 
 273     LoadFile(filename
, type
); 
 276 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
) 
 278     wxASSERT(depth 
== 1); 
 279     if (width 
> 0 && height 
> 0 && depth 
== 1) 
 281         SetPixmap(gdk_bitmap_create_from_data(wxGetRootWindow()->window
, bits
, width
, height
)); 
 285 wxBitmap::wxBitmap(const char* const* bits
) 
 287     wxCHECK2_MSG(bits 
!= NULL
, return, wxT("invalid bitmap data")); 
 289     GdkBitmap
* mask 
= NULL
; 
 290     SetPixmap(gdk_pixmap_create_from_xpm_d(wxGetRootWindow()->window
, &mask
, NULL
, const_cast<char**>(bits
))); 
 294     if (M_BMPDATA
->m_pixmap 
!= NULL 
&& mask 
!= NULL
) 
 296         M_BMPDATA
->m_mask 
= new wxMask
; 
 297         M_BMPDATA
->m_mask
->m_bitmap 
= mask
; 
 301 wxBitmap::~wxBitmap() 
 305 bool wxBitmap::Create( int width
, int height
, int depth 
) 
 308     wxCHECK_MSG(width 
>= 0 && height 
>= 0, false, "invalid bitmap size"); 
 309     m_refData 
= new wxBitmapRefData(width
, height
, depth
); 
 315 bool wxBitmap::CreateFromImage(const wxImage
& image
, int depth
) 
 319     wxCHECK_MSG( image
.IsOk(), false, wxT("invalid image") ); 
 320     wxCHECK_MSG( depth 
== -1 || depth 
== 1, false, wxT("invalid bitmap depth") ); 
 322     if (image
.GetWidth() <= 0 || image
.GetHeight() <= 0) 
 325     // create pixbuf if image has alpha and requested depth is compatible 
 326     if (image
.HasAlpha() && (depth 
== -1 || depth 
== 32)) 
 327         return CreateFromImageAsPixbuf(image
); 
 329     // otherwise create pixmap, if alpha is present it will be converted to mask 
 330     return CreateFromImageAsPixmap(image
, depth
); 
 333 bool wxBitmap::CreateFromImageAsPixmap(const wxImage
& image
, int depth
) 
 335     const int w 
= image
.GetWidth(); 
 336     const int h 
= image
.GetHeight(); 
 339         // create XBM format bitmap 
 341         // one bit per pixel, each row starts on a byte boundary 
 342         const size_t out_size 
= size_t((w 
+ 7) / 8) * unsigned(h
); 
 343         wxByte
* out 
= new wxByte
[out_size
]; 
 344         // set bits are black 
 345         memset(out
, 0xff, out_size
); 
 346         const wxByte
* in 
= image
.GetData(); 
 347         unsigned bit_index 
= 0; 
 348         for (int y 
= 0; y 
< h
; y
++) 
 350             for (int x 
= 0; x 
< w
; x
++, in 
+= 3, bit_index
++) 
 351                 if (in
[0] == 255 && in
[1] == 255 && in
[2] == 255) 
 352                     out
[bit_index 
>> 3] ^= 1 << (bit_index 
& 7); 
 353             // move index to next byte boundary 
 354             bit_index 
= (bit_index 
+ 7) & ~7u; 
 356         SetPixmap(gdk_bitmap_create_from_data(wxGetRootWindow()->window
, (char*)out
, w
, h
)); 
 359         if (!M_BMPDATA
)     // SetPixmap may have failed 
 364         SetPixmap(gdk_pixmap_new(wxGetRootWindow()->window
, w
, h
, depth
)); 
 368         wxGtkObject
<GdkGC
> gc(gdk_gc_new(M_BMPDATA
->m_pixmap
)); 
 370             M_BMPDATA
->m_pixmap
, gc
, 
 372             GDK_RGB_DITHER_NONE
, image
.GetData(), w 
* 3); 
 375     const wxByte
* alpha 
= image
.GetAlpha(); 
 376     if (alpha 
!= NULL 
|| image
.HasMask()) 
 378         // create mask as XBM format bitmap 
 380         const size_t out_size 
= size_t((w 
+ 7) / 8) * unsigned(h
); 
 381         wxByte
* out 
= new wxByte
[out_size
]; 
 382         memset(out
, 0xff, out_size
); 
 383         unsigned bit_index 
= 0; 
 386             for (int y 
= 0; y 
< h
; y
++) 
 388                 for (int x 
= 0; x 
< w
; x
++, bit_index
++) 
 389                     if (*alpha
++ < wxIMAGE_ALPHA_THRESHOLD
) 
 390                         out
[bit_index 
>> 3] ^= 1 << (bit_index 
& 7); 
 391                 bit_index 
= (bit_index 
+ 7) & ~7u; 
 396             const wxByte r_mask 
= image
.GetMaskRed(); 
 397             const wxByte g_mask 
= image
.GetMaskGreen(); 
 398             const wxByte b_mask 
= image
.GetMaskBlue(); 
 399             const wxByte
* in 
= image
.GetData(); 
 400             for (int y 
= 0; y 
< h
; y
++) 
 402                 for (int x 
= 0; x 
< w
; x
++, in 
+= 3, bit_index
++) 
 403                     if (in
[0] == r_mask 
&& in
[1] == g_mask 
&& in
[2] == b_mask
) 
 404                         out
[bit_index 
>> 3] ^= 1 << (bit_index 
& 7); 
 405                 bit_index 
= (bit_index 
+ 7) & ~7u; 
 408         wxMask
* mask 
= new wxMask
; 
 409         mask
->m_bitmap 
= gdk_bitmap_create_from_data(M_BMPDATA
->m_pixmap
, (char*)out
, w
, h
); 
 416 bool wxBitmap::CreateFromImageAsPixbuf(const wxImage
& image
) 
 418     wxASSERT(image
.HasAlpha()); 
 420     int width 
= image
.GetWidth(); 
 421     int height 
= image
.GetHeight(); 
 423     Create(width
, height
, 32); 
 424     GdkPixbuf
* pixbuf 
= GetPixbuf(); 
 429     const unsigned char* in 
= image
.GetData(); 
 430     unsigned char *out 
= gdk_pixbuf_get_pixels(pixbuf
); 
 431     unsigned char *alpha 
= image
.GetAlpha(); 
 433     int rowpad 
= gdk_pixbuf_get_rowstride(pixbuf
) - 4 * width
; 
 435     for (int y 
= 0; y 
< height
; y
++, out 
+= rowpad
) 
 437         for (int x 
= 0; x 
< width
; x
++, alpha
++, out 
+= 4, in 
+= 3) 
 449 wxImage 
wxBitmap::ConvertToImage() const 
 451     wxCHECK_MSG( IsOk(), wxNullImage
, wxT("invalid bitmap") ); 
 453     const int w 
= GetWidth(); 
 454     const int h 
= GetHeight(); 
 455     wxImage 
image(w
, h
, false); 
 456     unsigned char *data 
= image
.GetData(); 
 458     wxCHECK_MSG(data 
!= NULL
, wxNullImage
, wxT("couldn't create image") ); 
 460     // prefer pixbuf if available, it will preserve alpha and should be quicker 
 463         GdkPixbuf 
*pixbuf 
= GetPixbuf(); 
 464         unsigned char* alpha 
= NULL
; 
 465         if (gdk_pixbuf_get_has_alpha(pixbuf
)) 
 468             alpha 
= image
.GetAlpha(); 
 470         const unsigned char* in 
= gdk_pixbuf_get_pixels(pixbuf
); 
 471         unsigned char *out 
= data
; 
 472         const int inc 
= 3 + int(alpha 
!= NULL
); 
 473         const int rowpad 
= gdk_pixbuf_get_rowstride(pixbuf
) - inc 
* w
; 
 475         for (int y 
= 0; y 
< h
; y
++, in 
+= rowpad
) 
 477             for (int x 
= 0; x 
< w
; x
++, in 
+= inc
, out 
+= 3) 
 489         GdkPixmap
* pixmap 
= GetPixmap(); 
 490         GdkPixmap
* pixmap_invert 
= NULL
; 
 493             // mono bitmaps are inverted, i.e. 0 is white 
 494             pixmap_invert 
= gdk_pixmap_new(pixmap
, w
, h
, 1); 
 495             wxGtkObject
<GdkGC
> gc(gdk_gc_new(pixmap_invert
)); 
 496             gdk_gc_set_function(gc
, GDK_COPY_INVERT
); 
 497             gdk_draw_drawable(pixmap_invert
, gc
, pixmap
, 0, 0, 0, 0, w
, h
); 
 498             pixmap 
= pixmap_invert
; 
 500         // create a pixbuf which shares data with the wxImage 
 501         GdkPixbuf
* pixbuf 
= gdk_pixbuf_new_from_data( 
 502             data
, GDK_COLORSPACE_RGB
, false, 8, w
, h
, 3 * w
, NULL
, NULL
); 
 504         gdk_pixbuf_get_from_drawable(pixbuf
, pixmap
, NULL
, 0, 0, 0, 0, w
, h
); 
 506         g_object_unref(pixbuf
); 
 507         if (pixmap_invert 
!= NULL
) 
 508             g_object_unref(pixmap_invert
); 
 510     // convert mask, unless there is already alpha 
 511     if (GetMask() && !image
.HasAlpha()) 
 513         // we hard code the mask colour for now but we could also make an 
 514         // effort (and waste time) to choose a colour not present in the 
 515         // image already to avoid having to fudge the pixels below -- 
 516         // whether it's worth to do it is unclear however 
 517         const int MASK_RED 
= 1; 
 518         const int MASK_GREEN 
= 2; 
 519         const int MASK_BLUE 
= 3; 
 520         const int MASK_BLUE_REPLACEMENT 
= 2; 
 522         image
.SetMaskColour(MASK_RED
, MASK_GREEN
, MASK_BLUE
); 
 523         GdkImage
* image_mask 
= gdk_drawable_get_image(GetMask()->GetBitmap(), 0, 0, w
, h
); 
 525         for (int y 
= 0; y 
< h
; y
++) 
 527             for (int x 
= 0; x 
< w
; x
++, data 
+= 3) 
 529                 if (gdk_image_get_pixel(image_mask
, x
, y
) == 0) 
 532                     data
[1] = MASK_GREEN
; 
 535                 else if (data
[0] == MASK_RED 
&& data
[1] == MASK_GREEN 
&& data
[2] == MASK_BLUE
) 
 537                     // we have to fudge the colour a bit to prevent 
 538                     // this pixel from appearing transparent 
 539                     data
[2] = MASK_BLUE_REPLACEMENT
; 
 543         g_object_unref(image_mask
); 
 549 #endif // wxUSE_IMAGE 
 551 int wxBitmap::GetHeight() const 
 553     wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
 555     return M_BMPDATA
->m_height
; 
 558 int wxBitmap::GetWidth() const 
 560     wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
 562     return M_BMPDATA
->m_width
; 
 565 int wxBitmap::GetDepth() const 
 567     wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); 
 569     return M_BMPDATA
->m_bpp
; 
 572 wxMask 
*wxBitmap::GetMask() const 
 574     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ); 
 576     return M_BMPDATA
->m_mask
; 
 579 void wxBitmap::SetMask( wxMask 
*mask 
) 
 581     wxCHECK_RET( IsOk(), wxT("invalid bitmap") ); 
 584     delete M_BMPDATA
->m_mask
; 
 585     M_BMPDATA
->m_mask 
= mask
; 
 588 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
) 
 594 wxBitmap 
wxBitmap::GetSubBitmap( const wxRect
& rect
) const 
 598     wxCHECK_MSG(IsOk(), ret
, wxT("invalid bitmap")); 
 600     const int w 
= rect
.width
; 
 601     const int h 
= rect
.height
; 
 602     const wxBitmapRefData
* bmpData 
= M_BMPDATA
; 
 604     wxCHECK_MSG(rect
.x 
>= 0 && rect
.y 
>= 0 && 
 605                 rect
.x 
+ w 
<= bmpData
->m_width 
&& 
 606                 rect
.y 
+ h 
<= bmpData
->m_height
, 
 607                 ret
, wxT("invalid bitmap region")); 
 609     wxBitmapRefData
* newRef 
= new wxBitmapRefData(*bmpData
); 
 610     ret
.m_refData 
= newRef
; 
 612     newRef
->m_height 
= h
; 
 614     if (bmpData
->m_pixbuf
) 
 617             gdk_pixbuf_new_subpixbuf(bmpData
->m_pixbuf
, rect
.x
, rect
.y
, w
, h
); 
 618         newRef
->m_pixbuf 
= gdk_pixbuf_copy(pixbuf
); 
 619         g_object_unref(pixbuf
); 
 621     if (bmpData
->m_pixmap
) 
 623         newRef
->m_pixmap 
= gdk_pixmap_new(bmpData
->m_pixmap
, w
, h
, -1); 
 624         GdkGC
* gc 
= gdk_gc_new(newRef
->m_pixmap
); 
 626             newRef
->m_pixmap
, gc
, bmpData
->m_pixmap
, rect
.x
, rect
.y
, 0, 0, w
, h
); 
 629     newRef
->m_mask 
= NULL
; 
 630     if (bmpData
->m_mask 
&& bmpData
->m_mask
->m_bitmap
) 
 632         GdkPixmap
* sub_mask 
= gdk_pixmap_new(bmpData
->m_mask
->m_bitmap
, w
, h
, 1); 
 633         newRef
->m_mask 
= new wxMask
; 
 634         newRef
->m_mask
->m_bitmap 
= sub_mask
; 
 635         GdkGC
* gc 
= gdk_gc_new(sub_mask
); 
 637             sub_mask
, gc
, bmpData
->m_mask
->m_bitmap
, rect
.x
, rect
.y
, 0, 0, w
, h
); 
 644 bool wxBitmap::SaveFile( const wxString 
&name
, wxBitmapType type
, const wxPalette 
*WXUNUSED(palette
) ) const 
 646     wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") ); 
 649     wxImage image 
= ConvertToImage(); 
 650     if (image
.IsOk() && image
.SaveFile(name
, type
)) 
 653     const char* type_name 
= NULL
; 
 656         case wxBITMAP_TYPE_BMP
:  type_name 
= "bmp";  break; 
 657         case wxBITMAP_TYPE_ICO
:  type_name 
= "ico";  break; 
 658         case wxBITMAP_TYPE_JPEG
: type_name 
= "jpeg"; break; 
 659         case wxBITMAP_TYPE_PNG
:  type_name 
= "png";  break; 
 663         gdk_pixbuf_save(GetPixbuf(), name
.fn_str(), type_name
, NULL
, NULL
); 
 666 bool wxBitmap::LoadFile( const wxString 
&name
, wxBitmapType type 
) 
 670     if (image
.LoadFile(name
, type
) && image
.IsOk()) 
 671         *this = wxBitmap(image
); 
 676         GdkPixbuf
* pixbuf 
= gdk_pixbuf_new_from_file(name
.fn_str(), NULL
); 
 685 wxPalette 
*wxBitmap::GetPalette() const 
 690 void wxBitmap::SetPalette(const wxPalette
& WXUNUSED(palette
)) 
 694 #endif // wxUSE_PALETTE 
 696 void wxBitmap::SetHeight( int height 
) 
 699     M_BMPDATA
->m_height 
= height
; 
 702 void wxBitmap::SetWidth( int width 
) 
 705     M_BMPDATA
->m_width 
= width
; 
 708 void wxBitmap::SetDepth( int depth 
) 
 711     M_BMPDATA
->m_bpp 
= depth
; 
 714 void wxBitmap::SetPixmap( GdkPixmap 
*pixmap 
) 
 722     gdk_drawable_get_size(pixmap
, &w
, &h
); 
 723     wxBitmapRefData
* bmpData 
= new wxBitmapRefData(w
, h
, 0); 
 725     bmpData
->m_pixmap 
= pixmap
; 
 726     bmpData
->m_bpp 
= gdk_drawable_get_depth(pixmap
); 
 729 GdkPixmap 
*wxBitmap::GetPixmap() const 
 731     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ); 
 733     wxBitmapRefData
* bmpData 
= M_BMPDATA
; 
 734     if (bmpData
->m_pixmap
) 
 735         return bmpData
->m_pixmap
; 
 737     if (bmpData
->m_pixbuf
) 
 739         GdkPixmap
** mask_pixmap 
= NULL
; 
 740         if (gdk_pixbuf_get_has_alpha(bmpData
->m_pixbuf
)) 
 742             // make new mask from alpha 
 743             delete bmpData
->m_mask
; 
 744             bmpData
->m_mask 
= new wxMask
; 
 745             mask_pixmap 
= &bmpData
->m_mask
->m_bitmap
; 
 747         gdk_pixbuf_render_pixmap_and_mask( 
 748             bmpData
->m_pixbuf
, &bmpData
->m_pixmap
, mask_pixmap
, 128); 
 752         bmpData
->m_pixmap 
= gdk_pixmap_new(wxGetRootWindow()->window
, 
 753             bmpData
->m_width
, bmpData
->m_height
, bmpData
->m_bpp 
== 1 ? 1 : -1); 
 755     return bmpData
->m_pixmap
; 
 758 bool wxBitmap::HasPixmap() const 
 760     wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") ); 
 762     return M_BMPDATA
->m_pixmap 
!= NULL
; 
 765 GdkPixbuf 
*wxBitmap::GetPixbuf() const 
 767     wxCHECK_MSG( IsOk(), NULL
, wxT("invalid bitmap") ); 
 769     wxBitmapRefData
* bmpData 
= M_BMPDATA
; 
 770     if (bmpData
->m_pixbuf
) 
 771         return bmpData
->m_pixbuf
; 
 773     const int w 
= bmpData
->m_width
; 
 774     const int h 
= bmpData
->m_height
; 
 775     GdkPixmap
* mask 
= NULL
; 
 777         mask 
= bmpData
->m_mask
->m_bitmap
; 
 778     const bool useAlpha 
= bmpData
->m_alphaRequested 
|| mask
; 
 779     bmpData
->m_pixbuf 
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
, useAlpha
, 8, w
, h
); 
 780     if (bmpData
->m_pixmap
) 
 781         PixmapToPixbuf(bmpData
->m_pixmap
, bmpData
->m_pixbuf
, w
, h
); 
 783         MaskToAlpha(mask
, bmpData
->m_pixbuf
, w
, h
); 
 784     return bmpData
->m_pixbuf
; 
 787 bool wxBitmap::HasPixbuf() const 
 789     wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") ); 
 791     return M_BMPDATA
->m_pixbuf 
!= NULL
; 
 794 void wxBitmap::SetPixbuf(GdkPixbuf
* pixbuf
) 
 802     if (gdk_pixbuf_get_has_alpha(pixbuf
)) 
 804     m_refData 
= new wxBitmapRefData( 
 805         gdk_pixbuf_get_width(pixbuf
), gdk_pixbuf_get_height(pixbuf
), depth
); 
 807     M_BMPDATA
->m_pixbuf 
= pixbuf
; 
 810 void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep
) 
 812     if (keep 
== Pixmap 
&& HasPixbuf()) 
 814         g_object_unref (M_BMPDATA
->m_pixbuf
); 
 815         M_BMPDATA
->m_pixbuf 
= NULL
; 
 817     if (keep 
== Pixbuf 
&& HasPixmap()) 
 819         g_object_unref (M_BMPDATA
->m_pixmap
); 
 820         M_BMPDATA
->m_pixmap 
= NULL
; 
 824 #ifdef wxHAS_RAW_BITMAP 
 825 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int bpp
) 
 828     GdkPixbuf 
*pixbuf 
= GetPixbuf(); 
 829     const bool hasAlpha 
= HasAlpha(); 
 831     // allow access if bpp is valid and matches existence of alpha 
 832     if ( pixbuf 
&& ((bpp 
== 24 && !hasAlpha
) || (bpp 
== 32 && hasAlpha
)) ) 
 834         data
.m_height 
= gdk_pixbuf_get_height( pixbuf 
); 
 835         data
.m_width 
= gdk_pixbuf_get_width( pixbuf 
); 
 836         data
.m_stride 
= gdk_pixbuf_get_rowstride( pixbuf 
); 
 837         bits 
= gdk_pixbuf_get_pixels(pixbuf
); 
 842 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(data
)) 
 845 #endif // wxHAS_RAW_BITMAP 
 847 bool wxBitmap::HasAlpha() const 
 849     const wxBitmapRefData
* bmpData 
= M_BMPDATA
; 
 850     return bmpData 
&& (bmpData
->m_alphaRequested 
|| 
 851         (bmpData
->m_pixbuf 
&& gdk_pixbuf_get_has_alpha(bmpData
->m_pixbuf
))); 
 854 wxGDIRefData
* wxBitmap::CreateGDIRefData() const 
 856     return new wxBitmapRefData(0, 0, 0); 
 859 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
 861     const wxBitmapRefData
* oldRef 
= static_cast<const wxBitmapRefData
*>(data
); 
 862     wxBitmapRefData
* newRef 
= new wxBitmapRefData(*oldRef
); 
 863     if (oldRef
->m_pixmap 
!= NULL
) 
 865         newRef
->m_pixmap 
= gdk_pixmap_new( 
 866             oldRef
->m_pixmap
, oldRef
->m_width
, oldRef
->m_height
, 
 867             // use pixmap depth, m_bpp may not match 
 868             gdk_drawable_get_depth(oldRef
->m_pixmap
)); 
 869         wxGtkObject
<GdkGC
> gc(gdk_gc_new(newRef
->m_pixmap
)); 
 871             newRef
->m_pixmap
, gc
, oldRef
->m_pixmap
, 0, 0, 0, 0, -1, -1); 
 873     if (oldRef
->m_pixbuf 
!= NULL
) 
 875         newRef
->m_pixbuf 
= gdk_pixbuf_copy(oldRef
->m_pixbuf
); 
 877     if (oldRef
->m_mask 
!= NULL
) 
 879         newRef
->m_mask 
= new wxMask(*oldRef
->m_mask
); 
 885 /* static */ void wxBitmap::InitStandardHandlers() 
 887     // TODO: Insert handler based on GdkPixbufs handler later