]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/bitmap.cpp
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"
17 #include "wx/palette.h"
23 #include "wx/rawbmp.h"
27 //-----------------------------------------------------------------------------
29 //-----------------------------------------------------------------------------
31 extern GtkWidget
*wxGetRootWindow();
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
37 IMPLEMENT_DYNAMIC_CLASS(wxMask
,wxObject
)
41 m_bitmap
= (GdkBitmap
*) NULL
;
44 wxMask::wxMask( const wxBitmap
& bitmap
, const wxColour
& colour
)
46 m_bitmap
= (GdkBitmap
*) NULL
;
47 Create( bitmap
, colour
);
51 wxMask::wxMask( const wxBitmap
& bitmap
, int paletteIndex
)
53 m_bitmap
= (GdkBitmap
*) NULL
;
54 Create( bitmap
, paletteIndex
);
56 #endif // wxUSE_PALETTE
58 wxMask::wxMask( const wxBitmap
& bitmap
)
60 m_bitmap
= (GdkBitmap
*) NULL
;
67 g_object_unref (m_bitmap
);
70 bool wxMask::Create( const wxBitmap
& bitmap
,
71 const wxColour
& colour
)
75 g_object_unref (m_bitmap
);
76 m_bitmap
= (GdkBitmap
*) NULL
;
79 const int w
= bitmap
.GetWidth();
80 const int h
= bitmap
.GetHeight();
81 m_bitmap
= gdk_pixmap_new(wxGetRootWindow()->window
, w
, h
, 1);
82 GdkGC
*gc
= gdk_gc_new( m_bitmap
);
86 gdk_gc_set_foreground( gc
, &color
);
87 gdk_draw_rectangle(m_bitmap
, gc
, true, 0, 0, w
, h
);
89 unsigned char red
= colour
.Red();
90 unsigned char green
= colour
.Green();
91 unsigned char blue
= colour
.Blue();
92 GdkImage
* image
= NULL
;
94 guint32 mask_pixel
= 1;
98 if (bitmap
.HasPixbuf())
100 GdkPixbuf
* pixbuf
= bitmap
.GetPixbuf();
101 data
= gdk_pixbuf_get_pixels(pixbuf
);
102 data_inc
= 3 + int(gdk_pixbuf_get_has_alpha(pixbuf
) != 0);
103 rowpadding
= gdk_pixbuf_get_rowstride(pixbuf
) - data_inc
* w
;
107 image
= gdk_drawable_get_image(bitmap
.GetPixmap(), 0, 0, w
, h
);
108 GdkColormap
* colormap
= gdk_image_get_colormap(image
);
109 if (colormap
!= NULL
)
112 c
.CalcPixel(colormap
);
113 mask_pixel
= c
.GetPixel();
118 gdk_gc_set_foreground( gc
, &color
);
120 for (int y
= 0; y
< h
; y
++)
124 for (x
= 0; x
< w
; x
++)
128 isMask
= gdk_image_get_pixel(image
, x
, y
) == mask_pixel
;
131 isMask
= data
[0] == red
&& data
[1] == green
&& data
[2] == blue
;
143 gdk_draw_line(m_bitmap
, gc
, start_x
, y
, x
- 1, y
);
149 gdk_draw_line(m_bitmap
, gc
, start_x
, y
, x
, y
);
153 g_object_unref(image
);
160 bool wxMask::Create( const wxBitmap
& bitmap
, int paletteIndex
)
163 wxPalette
*pal
= bitmap
.GetPalette();
165 wxCHECK_MSG( pal
, false, wxT("Cannot create mask from bitmap without palette") );
167 pal
->GetRGB(paletteIndex
, &r
, &g
, &b
);
169 return Create(bitmap
, wxColour(r
, g
, b
));
171 #endif // wxUSE_PALETTE
173 bool wxMask::Create( const wxBitmap
& bitmap
)
177 g_object_unref (m_bitmap
);
178 m_bitmap
= (GdkBitmap
*) NULL
;
181 if (!bitmap
.Ok()) return false;
183 wxCHECK_MSG( bitmap
.GetDepth() == 1, false, wxT("Cannot create mask from colour bitmap") );
185 m_bitmap
= gdk_pixmap_new( wxGetRootWindow()->window
, bitmap
.GetWidth(), bitmap
.GetHeight(), 1 );
187 if (!m_bitmap
) return false;
189 GdkGC
*gc
= gdk_gc_new( m_bitmap
);
190 gdk_gc_set_function(gc
, GDK_COPY_INVERT
);
191 gdk_draw_drawable(m_bitmap
, gc
, bitmap
.GetPixmap(), 0, 0, 0, 0, bitmap
.GetWidth(), bitmap
.GetHeight());
197 GdkBitmap
*wxMask::GetBitmap() const
202 //-----------------------------------------------------------------------------
204 //-----------------------------------------------------------------------------
206 class wxBitmapRefData
: public wxObjectRefData
218 wxPalette
*m_palette
;
221 wxBitmapRefData::wxBitmapRefData()
223 m_pixmap
= (GdkPixmap
*) NULL
;
224 m_pixbuf
= (GdkPixbuf
*) NULL
;
225 m_mask
= (wxMask
*) NULL
;
229 m_palette
= (wxPalette
*) NULL
;
232 wxBitmapRefData::~wxBitmapRefData()
235 g_object_unref (m_pixmap
);
237 g_object_unref (m_pixbuf
);
241 #endif // wxUSE_PALETTE
244 //-----------------------------------------------------------------------------
246 #define M_BMPDATA wx_static_cast(wxBitmapRefData*, m_refData)
248 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
,wxGDIObject
)
254 wxBitmap::wxBitmap( int width
, int height
, int depth
)
256 Create( width
, height
, depth
);
259 bool wxBitmap::Create( int width
, int height
, int depth
)
263 if ( width
<= 0 || height
<= 0 )
270 SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB
, true, 8, width
, height
));
271 M_BMPDATA
->m_bpp
= 32;
277 const GdkVisual
* visual
= wxTheApp
->GetGdkVisual();
279 depth
= visual
->depth
;
281 wxCHECK_MSG(depth
== visual
->depth
, false, wxT("invalid bitmap depth"));
284 SetPixmap(gdk_pixmap_new(wxGetRootWindow()->window
, width
, height
, depth
));
290 bool wxBitmap::CreateFromXpm( const char **bits
)
294 wxCHECK_MSG( bits
!= NULL
, false, wxT("invalid bitmap data") );
296 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
297 SetPixmap(gdk_pixmap_create_from_xpm_d(wxGetRootWindow()->window
, &mask
, NULL
, (gchar
**)bits
));
299 wxCHECK_MSG( M_BMPDATA
->m_pixmap
, false, wxT("couldn't create pixmap") );
303 M_BMPDATA
->m_mask
= new wxMask
;
304 M_BMPDATA
->m_mask
->m_bitmap
= mask
;
310 wxBitmap
wxBitmap::Rescale( int clipx
, int clipy
, int clipwidth
, int clipheight
, int newx
, int newy
)
314 wxCHECK_MSG(Ok(), bmp
, wxT("invalid bitmap"));
316 if (newy
==M_BMPDATA
->m_width
&& newy
==M_BMPDATA
->m_height
)
319 int width
= wxMax(newx
, 1);
320 int height
= wxMax(newy
, 1);
321 width
= wxMin(width
, clipwidth
);
322 height
= wxMin(height
, clipheight
);
326 bmp
.SetDepth(GetDepth());
327 bmp
.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB
,
328 gdk_pixbuf_get_has_alpha(GetPixbuf()),
330 gdk_pixbuf_scale(GetPixbuf(), bmp
.GetPixbuf(),
333 (double)newx
/GetWidth(), (double)newy
/GetHeight(),
334 GDK_INTERP_BILINEAR
);
338 GdkImage
* img
= gdk_drawable_get_image(GetPixmap(), 0, 0, GetWidth(), GetHeight());
340 wxCHECK_MSG(img
, bmp
, wxT("couldn't create image"));
343 GdkPixmap
*dstpix
= NULL
;
345 long dstbyteperline
= 0;
349 GdkVisual
*visual
= gdk_drawable_get_visual( GetPixmap() );
351 visual
= wxTheApp
->GetGdkVisual();
353 bmp
= wxBitmap(width
, height
, visual
->depth
);
354 dstpix
= bmp
.GetPixmap();
355 gc
= gdk_gc_new( dstpix
);
359 dstbyteperline
= (width
+ 7) / 8;
360 dst
= (char*) malloc(dstbyteperline
*height
);
363 // be careful to use the right scaling factor
364 float scx
= (float)M_BMPDATA
->m_width
/(float)newx
;
365 float scy
= (float)M_BMPDATA
->m_height
/(float)newy
;
366 // prepare accel-tables
367 int *tablex
= (int *)calloc(width
,sizeof(int));
368 int *tabley
= (int *)calloc(height
,sizeof(int));
370 // accel table filled with clipped values
371 for (int x
= 0; x
< width
; x
++)
372 tablex
[x
] = (int) (scx
* (x
+clipx
));
373 for (int y
= 0; y
< height
; y
++)
374 tabley
[y
] = (int) (scy
* (y
+clipy
));
376 // Main rescaling routine starts here
377 for (int h
= 0; h
< height
; h
++)
381 guint32 old_pixval
= 0;
383 for (int w
= 0; w
< width
; w
++)
391 pixval
= gdk_image_get_pixel( img
, x
, tabley
[h
] );
401 char shift
= bit
<< (w
% 8);
407 dst
[h
*dstbyteperline
+w
/8] = outbyte
;
415 gdk_gc_set_foreground( gc
, &col
);
416 gdk_draw_point( dstpix
, gc
, w
, h
);
420 // do not forget the last byte
421 if ( dst
&& (width
% 8 != 0) )
422 dst
[h
*dstbyteperline
+width
/8] = outbyte
;
425 g_object_unref (img
);
426 if (gc
) g_object_unref (gc
);
430 bmp
= wxBitmap( (const char *)dst
, width
, height
, 1 );
436 dstbyteperline
= (width
+ 7) / 8;
437 dst
= (char*) malloc(dstbyteperline
*height
);
438 img
= gdk_drawable_get_image(GetMask()->GetBitmap(), 0, 0, GetWidth(), GetHeight());
440 for (int h
= 0; h
< height
; h
++)
444 guint32 old_pixval
= 0;
446 for (int w
= 0; w
< width
; w
++)
454 pixval
= gdk_image_get_pixel( img
, x
, tabley
[h
] );
462 char shift
= bit
<< (w
% 8);
468 dst
[h
*dstbyteperline
+w
/8] = outbyte
;
473 // do not forget the last byte
475 dst
[h
*dstbyteperline
+width
/8] = outbyte
;
477 wxMask
* mask
= new wxMask
;
478 mask
->m_bitmap
= gdk_bitmap_create_from_data( wxGetRootWindow()->window
, (gchar
*) dst
, width
, height
);
482 g_object_unref (img
);
492 bool wxBitmap::CreateFromImage(const wxImage
& image
, int depth
)
496 wxCHECK_MSG( image
.Ok(), false, wxT("invalid image") );
497 wxCHECK_MSG( depth
== -1 || depth
== 1, false, wxT("invalid bitmap depth") );
499 if (image
.GetWidth() <= 0 || image
.GetHeight() <= 0)
503 return CreateFromImageAsBitmap(image
);
505 if (image
.HasAlpha())
506 return CreateFromImageAsPixbuf(image
);
508 return CreateFromImageAsPixmap(image
);
511 // conversion to mono bitmap:
512 bool wxBitmap::CreateFromImageAsBitmap(const wxImage
& img
)
514 // convert alpha channel to mask, if it is present:
516 image
.ConvertAlphaToMask();
518 int width
= image
.GetWidth();
519 int height
= image
.GetHeight();
521 SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 ) );
523 // Create picture image
525 GdkGC
* data_gc
= gdk_gc_new(M_BMPDATA
->m_pixmap
);
528 gdk_gc_set_foreground(data_gc
, &color
);
529 gdk_draw_rectangle(M_BMPDATA
->m_pixmap
, data_gc
, true, 0, 0, width
, height
);
530 GdkImage
* data_image
= gdk_drawable_get_image(M_BMPDATA
->m_pixmap
, 0, 0, width
, height
);
534 GdkImage
*mask_image
= (GdkImage
*) NULL
;
535 GdkGC
* mask_gc
= NULL
;
539 wxMask
* mask
= new wxMask
;
540 mask
->m_bitmap
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 );
541 mask_gc
= gdk_gc_new(mask
->m_bitmap
);
542 gdk_gc_set_foreground(mask_gc
, &color
);
543 gdk_draw_rectangle(mask
->m_bitmap
, mask_gc
, true, 0, 0, width
, height
);
544 mask_image
= gdk_drawable_get_image(mask
->m_bitmap
, 0, 0, width
, height
);
549 int r_mask
= image
.GetMaskRed();
550 int g_mask
= image
.GetMaskGreen();
551 int b_mask
= image
.GetMaskBlue();
553 unsigned char* data
= image
.GetData();
556 for (int y
= 0; y
< height
; y
++)
558 for (int x
= 0; x
< width
; x
++)
567 if (mask_image
!= NULL
)
569 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
570 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
573 if ((r
== 255) && (b
== 255) && (g
== 255))
574 gdk_image_put_pixel( data_image
, x
, y
, 0 );
581 gdk_draw_image( GetPixmap(), data_gc
, data_image
, 0, 0, 0, 0, width
, height
);
583 g_object_unref (data_image
);
584 g_object_unref (data_gc
);
588 if (mask_image
!= NULL
)
590 gdk_draw_image( GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height
);
592 g_object_unref (mask_image
);
593 g_object_unref (mask_gc
);
599 // conversion to colour bitmap:
600 bool wxBitmap::CreateFromImageAsPixmap(const wxImage
& image
)
602 // alpha is handled by CreateFromImageAsPixbuf
603 wxASSERT(!image
.HasAlpha());
605 int width
= image
.GetWidth();
606 int height
= image
.GetHeight();
608 SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, -1 ) );
610 GdkGC
*gc
= gdk_gc_new( GetPixmap() );
612 gdk_draw_rgb_image( GetPixmap(),
624 if (!image
.HasMask())
627 wxMask
* mask
= new wxMask
;
628 mask
->m_bitmap
= gdk_pixmap_new( wxGetRootWindow()->window
, width
, height
, 1 );
629 GdkGC
* mask_gc
= gdk_gc_new(mask
->m_bitmap
);
632 gdk_gc_set_foreground(mask_gc
, &color
);
633 gdk_draw_rectangle(mask
->m_bitmap
, mask_gc
, true, 0, 0, width
, height
);
634 GdkImage
* mask_image
= gdk_drawable_get_image(mask
->m_bitmap
, 0, 0, width
, height
);
638 int r_mask
= image
.GetMaskRed();
639 int g_mask
= image
.GetMaskGreen();
640 int b_mask
= image
.GetMaskBlue();
642 unsigned char* data
= image
.GetData();
645 for (int y
= 0; y
< height
; y
++)
647 for (int x
= 0; x
< width
; x
++)
656 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
657 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
663 gdk_draw_image( GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height
);
665 g_object_unref (mask_image
);
666 g_object_unref (mask_gc
);
671 bool wxBitmap::CreateFromImageAsPixbuf(const wxImage
& image
)
673 int width
= image
.GetWidth();
674 int height
= image
.GetHeight();
676 GdkPixbuf
*pixbuf
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
,
678 8 /* bits per sample */,
683 wxASSERT( image
.HasAlpha() ); // for now
684 wxASSERT( gdk_pixbuf_get_n_channels(pixbuf
) == 4 );
685 wxASSERT( gdk_pixbuf_get_width(pixbuf
) == width
);
686 wxASSERT( gdk_pixbuf_get_height(pixbuf
) == height
);
688 SetDepth(wxTheApp
->GetGdkVisual()->depth
);
692 unsigned char *in
= image
.GetData();
693 unsigned char *out
= gdk_pixbuf_get_pixels(pixbuf
);
694 unsigned char *alpha
= image
.GetAlpha();
696 int rowinc
= gdk_pixbuf_get_rowstride(pixbuf
) - 4 * width
;
698 for (int y
= 0; y
< height
; y
++, out
+= rowinc
)
700 for (int x
= 0; x
< width
; x
++, alpha
++, out
+= 4, in
+= 3)
712 wxImage
wxBitmap::ConvertToImage() const
716 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
718 const int w
= GetWidth();
719 const int h
= GetHeight();
721 unsigned char *data
= image
.GetData();
723 wxCHECK_MSG(data
!= NULL
, wxNullImage
, wxT("couldn't create image") );
727 GdkPixbuf
*pixbuf
= GetPixbuf();
728 wxASSERT( gdk_pixbuf_get_has_alpha(pixbuf
) );
732 unsigned char *alpha
= image
.GetAlpha();
733 unsigned char *in
= gdk_pixbuf_get_pixels(pixbuf
);
734 unsigned char *out
= data
;
735 int rowinc
= gdk_pixbuf_get_rowstride(pixbuf
) - 4 * w
;
737 for (int y
= 0; y
< h
; y
++, in
+= rowinc
)
739 for (int x
= 0; x
< w
; x
++, in
+= 4, out
+= 3, alpha
++)
750 GdkPixmap
* pixmap
= GetPixmap();
751 GdkPixmap
* pixmap_invert
= NULL
;
754 // mono bitmaps are inverted
755 pixmap_invert
= gdk_pixmap_new(pixmap
, w
, h
, 1);
756 GdkGC
* gc
= gdk_gc_new(pixmap_invert
);
757 gdk_gc_set_function(gc
, GDK_COPY_INVERT
);
758 gdk_draw_drawable(pixmap_invert
, gc
, pixmap
, 0, 0, 0, 0, w
, h
);
760 pixmap
= pixmap_invert
;
762 // create a pixbuf which shares data with the wxImage
763 GdkPixbuf
* pixbuf
= gdk_pixbuf_new_from_data(
764 data
, GDK_COLORSPACE_RGB
, false, 8, w
, h
, 3 * w
, NULL
, NULL
);
766 gdk_pixbuf_get_from_drawable(pixbuf
, pixmap
, NULL
, 0, 0, 0, 0, w
, h
);
768 g_object_unref(pixbuf
);
769 if (pixmap_invert
!= NULL
)
770 g_object_unref(pixmap_invert
);
774 // the colour used as transparent one in wxImage and the one it is
775 // replaced with when it really occurs in the bitmap
776 const int MASK_RED
= 1;
777 const int MASK_GREEN
= 2;
778 const int MASK_BLUE
= 3;
779 const int MASK_BLUE_REPLACEMENT
= 2;
781 image
.SetMaskColour(MASK_RED
, MASK_GREEN
, MASK_BLUE
);
782 GdkImage
* image_mask
= gdk_drawable_get_image(GetMask()->GetBitmap(), 0, 0, w
, h
);
784 for (int y
= 0; y
< h
; y
++)
786 for (int x
= 0; x
< w
; x
++, data
+= 3)
788 if (gdk_image_get_pixel(image_mask
, x
, y
) == 0)
791 data
[1] = MASK_GREEN
;
794 else if (data
[0] == MASK_RED
&& data
[1] == MASK_GREEN
&& data
[2] == MASK_BLUE
)
796 data
[2] = MASK_BLUE_REPLACEMENT
;
800 g_object_unref(image_mask
);
807 wxBitmap::wxBitmap( const wxString
&filename
, wxBitmapType type
)
809 LoadFile( filename
, type
);
812 wxBitmap::wxBitmap( const char bits
[], int width
, int height
, int WXUNUSED(depth
))
814 if ( width
> 0 && height
> 0 )
816 SetPixmap(gdk_bitmap_create_from_data(wxGetRootWindow()->window
, bits
, width
, height
));
818 wxASSERT_MSG( M_BMPDATA
->m_pixmap
, wxT("couldn't create bitmap") );
822 wxBitmap::~wxBitmap()
826 bool wxBitmap::operator == ( const wxBitmap
& bmp
) const
828 return m_refData
== bmp
.m_refData
;
831 bool wxBitmap::operator != ( const wxBitmap
& bmp
) const
833 return m_refData
!= bmp
.m_refData
;
836 bool wxBitmap::Ok() const
838 return (m_refData
!= NULL
) &&
840 M_BMPDATA
->m_pixbuf
||
845 int wxBitmap::GetHeight() const
847 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
849 return M_BMPDATA
->m_height
;
852 int wxBitmap::GetWidth() const
854 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
856 return M_BMPDATA
->m_width
;
859 int wxBitmap::GetDepth() const
861 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
863 return M_BMPDATA
->m_bpp
;
866 wxMask
*wxBitmap::GetMask() const
868 wxCHECK_MSG( Ok(), (wxMask
*) NULL
, wxT("invalid bitmap") );
870 return M_BMPDATA
->m_mask
;
873 void wxBitmap::SetMask( wxMask
*mask
)
875 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
877 if (M_BMPDATA
->m_mask
) delete M_BMPDATA
->m_mask
;
879 M_BMPDATA
->m_mask
= mask
;
882 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
888 wxBitmap
wxBitmap::GetSubBitmap( const wxRect
& rect
) const
893 (rect
.x
>= 0) && (rect
.y
>= 0) &&
894 (rect
.x
+rect
.width
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height
<= M_BMPDATA
->m_height
),
895 ret
, wxT("invalid bitmap or bitmap region") );
899 GdkPixbuf
*pixbuf
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
,
900 gdk_pixbuf_get_has_alpha(GetPixbuf()),
901 8, rect
.width
, rect
.height
);
902 ret
.SetPixbuf(pixbuf
);
903 ret
.SetDepth(M_BMPDATA
->m_bpp
);
904 gdk_pixbuf_copy_area(GetPixbuf(),
905 rect
.x
, rect
.y
, rect
.width
, rect
.height
,
910 ret
= wxBitmap(rect
.width
, rect
.height
, M_BMPDATA
->m_bpp
);
911 GdkGC
*gc
= gdk_gc_new( ret
.GetPixmap() );
912 gdk_draw_drawable( ret
.GetPixmap(), gc
, GetPixmap(), rect
.x
, rect
.y
, 0, 0, rect
.width
, rect
.height
);
918 wxMask
*mask
= new wxMask
;
919 mask
->m_bitmap
= gdk_pixmap_new( wxGetRootWindow()->window
, rect
.width
, rect
.height
, 1 );
921 GdkGC
*gc
= gdk_gc_new( mask
->m_bitmap
);
922 gdk_draw_drawable(mask
->m_bitmap
, gc
, M_BMPDATA
->m_mask
->m_bitmap
, rect
.x
, rect
.y
, 0, 0, rect
.width
, rect
.height
);
931 bool wxBitmap::SaveFile( const wxString
&name
, wxBitmapType type
, const wxPalette
*WXUNUSED(palette
) ) const
933 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
935 // Try to save the bitmap via wxImage handlers:
936 wxImage image
= ConvertToImage();
937 return image
.Ok() && image
.SaveFile(name
, type
);
940 bool wxBitmap::LoadFile( const wxString
&name
, wxBitmapType type
)
944 if (type
== wxBITMAP_TYPE_XPM
)
946 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
947 SetPixmap(gdk_pixmap_create_from_xpm(wxGetRootWindow()->window
, &mask
, NULL
, name
.fn_str()));
951 M_BMPDATA
->m_mask
= new wxMask
;
952 M_BMPDATA
->m_mask
->m_bitmap
= mask
;
955 else // try if wxImage can load it
958 if (image
.LoadFile(name
, type
) && image
.Ok())
959 *this = wxBitmap(image
);
966 wxPalette
*wxBitmap::GetPalette() const
969 return (wxPalette
*) NULL
;
971 return M_BMPDATA
->m_palette
;
974 void wxBitmap::SetPalette(const wxPalette
& WXUNUSED(palette
))
978 #endif // wxUSE_PALETTE
980 void wxBitmap::SetHeight( int height
)
983 m_refData
= new wxBitmapRefData
;
985 M_BMPDATA
->m_height
= height
;
988 void wxBitmap::SetWidth( int width
)
991 m_refData
= new wxBitmapRefData
;
993 M_BMPDATA
->m_width
= width
;
996 void wxBitmap::SetDepth( int depth
)
999 m_refData
= new wxBitmapRefData
;
1001 M_BMPDATA
->m_bpp
= depth
;
1004 void wxBitmap::SetPixmap( GdkPixmap
*pixmap
)
1007 m_refData
= new wxBitmapRefData
;
1009 wxASSERT(M_BMPDATA
->m_pixmap
== NULL
);
1010 M_BMPDATA
->m_pixmap
= pixmap
;
1011 gdk_drawable_get_size(pixmap
, &M_BMPDATA
->m_width
, &M_BMPDATA
->m_height
);
1012 M_BMPDATA
->m_bpp
= gdk_drawable_get_depth(pixmap
);
1013 PurgeOtherRepresentations(Pixmap
);
1016 GdkPixmap
*wxBitmap::GetPixmap() const
1018 wxCHECK_MSG( Ok(), (GdkPixmap
*) NULL
, wxT("invalid bitmap") );
1020 // create the pixmap on the fly if we use Pixbuf representation:
1021 if (M_BMPDATA
->m_pixmap
== NULL
)
1023 delete M_BMPDATA
->m_mask
;
1024 M_BMPDATA
->m_mask
= new wxMask
;
1025 gdk_pixbuf_render_pixmap_and_mask(M_BMPDATA
->m_pixbuf
,
1026 &M_BMPDATA
->m_pixmap
,
1027 &M_BMPDATA
->m_mask
->m_bitmap
,
1031 return M_BMPDATA
->m_pixmap
;
1034 bool wxBitmap::HasPixmap() const
1036 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
1038 return M_BMPDATA
->m_pixmap
!= NULL
;
1041 GdkPixbuf
*wxBitmap::GetPixbuf() const
1043 wxCHECK_MSG( Ok(), NULL
, wxT("invalid bitmap") );
1045 if (M_BMPDATA
->m_pixbuf
== NULL
)
1047 int width
= GetWidth();
1048 int height
= GetHeight();
1050 GdkPixbuf
*pixbuf
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
,
1053 M_BMPDATA
->m_pixbuf
=
1054 gdk_pixbuf_get_from_drawable(pixbuf
, M_BMPDATA
->m_pixmap
, NULL
,
1055 0, 0, 0, 0, width
, height
);
1057 // apply the mask to created pixbuf:
1058 if (M_BMPDATA
->m_pixbuf
&& M_BMPDATA
->m_mask
)
1061 gdk_pixbuf_get_from_drawable(NULL
,
1062 M_BMPDATA
->m_mask
->GetBitmap(),
1064 0, 0, 0, 0, width
, height
);
1067 guchar
*bmp
= gdk_pixbuf_get_pixels(pixbuf
);
1068 guchar
*mask
= gdk_pixbuf_get_pixels(pmask
);
1069 int bmprowinc
= gdk_pixbuf_get_rowstride(pixbuf
) - 4 * width
;
1070 int maskrowinc
= gdk_pixbuf_get_rowstride(pmask
) - 3 * width
;
1072 for (int y
= 0; y
< height
;
1073 y
++, bmp
+= bmprowinc
, mask
+= maskrowinc
)
1075 for (int x
= 0; x
< width
; x
++, bmp
+= 4, mask
+= 3)
1077 if (mask
[0] == 0 /*black pixel*/)
1082 g_object_unref (pmask
);
1087 return M_BMPDATA
->m_pixbuf
;
1090 bool wxBitmap::HasPixbuf() const
1092 wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
1094 return M_BMPDATA
->m_pixbuf
!= NULL
;
1097 void wxBitmap::SetPixbuf( GdkPixbuf
*pixbuf
)
1100 m_refData
= new wxBitmapRefData
;
1102 wxASSERT(M_BMPDATA
->m_pixbuf
== NULL
);
1103 M_BMPDATA
->m_pixbuf
= pixbuf
;
1104 M_BMPDATA
->m_width
= gdk_pixbuf_get_width(pixbuf
);
1105 M_BMPDATA
->m_height
= gdk_pixbuf_get_height(pixbuf
);
1106 PurgeOtherRepresentations(Pixbuf
);
1109 void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep
)
1111 if (keep
== Pixmap
&& HasPixbuf())
1113 g_object_unref (M_BMPDATA
->m_pixbuf
);
1114 M_BMPDATA
->m_pixbuf
= NULL
;
1116 if (keep
== Pixbuf
&& HasPixmap())
1118 g_object_unref (M_BMPDATA
->m_pixmap
);
1119 M_BMPDATA
->m_pixmap
= NULL
;
1123 void *wxBitmap::GetRawData(wxPixelDataBase
& data
, int bpp
)
1128 GdkPixbuf
*pixbuf
= GetPixbuf();
1133 if (gdk_pixbuf_get_has_alpha( pixbuf
))
1134 wxPrintf( wxT("Has alpha\n") );
1136 wxPrintf( wxT("No alpha.\n") );
1139 data
.m_height
= gdk_pixbuf_get_height( pixbuf
);
1140 data
.m_width
= gdk_pixbuf_get_width( pixbuf
);
1141 data
.m_stride
= gdk_pixbuf_get_rowstride( pixbuf
);
1143 return gdk_pixbuf_get_pixels( pixbuf
);
1146 void wxBitmap::UngetRawData(wxPixelDataBase
& WXUNUSED(data
))
1151 bool wxBitmap::HasAlpha() const
1156 void wxBitmap::UseAlpha()
1161 //-----------------------------------------------------------------------------
1163 //-----------------------------------------------------------------------------
1165 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
,wxBitmapHandlerBase
)
1167 wxBitmapHandler::~wxBitmapHandler()
1171 bool wxBitmapHandler::Create(wxBitmap
* WXUNUSED(bitmap
),
1172 void * WXUNUSED(data
),
1173 long WXUNUSED(type
),
1174 int WXUNUSED(width
),
1175 int WXUNUSED(height
),
1176 int WXUNUSED(depth
))
1178 wxFAIL_MSG( _T("not implemented") );
1183 bool wxBitmapHandler::LoadFile(wxBitmap
* WXUNUSED(bitmap
),
1184 const wxString
& WXUNUSED(name
),
1185 long WXUNUSED(flags
),
1186 int WXUNUSED(desiredWidth
),
1187 int WXUNUSED(desiredHeight
))
1189 wxFAIL_MSG( _T("not implemented") );
1194 bool wxBitmapHandler::SaveFile(const wxBitmap
* WXUNUSED(bitmap
),
1195 const wxString
& WXUNUSED(name
),
1197 const wxPalette
* WXUNUSED(palette
))
1199 wxFAIL_MSG( _T("not implemented") );
1204 /* static */ void wxBitmap::InitStandardHandlers()
1206 // TODO: Insert handler based on GdkPixbufs handler later