added alpha channel support to wxGTK2's wxBitmap
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28850 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -249,6 +249,7 @@ wxGTK:
|
|||||||
- implemented wxTopLevel::IsMaximized() for GTK+2 and WMs that implement
|
- implemented wxTopLevel::IsMaximized() for GTK+2 and WMs that implement
|
||||||
freedesktop.org's wm-spec (Mart Raudsepp)
|
freedesktop.org's wm-spec (Mart Raudsepp)
|
||||||
- wxEVT_CONTEXT_MENU is now generated for right mouse press, not release
|
- wxEVT_CONTEXT_MENU is now generated for right mouse press, not release
|
||||||
|
- implemented alpha channel support in wxBitmap
|
||||||
|
|
||||||
wxMotif:
|
wxMotif:
|
||||||
|
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
#include "wx/palette.h"
|
#include "wx/palette.h"
|
||||||
#include "wx/gdiobj.h"
|
#include "wx/gdiobj.h"
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
typedef struct _GdkPixbuf GdkPixbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// classes
|
// classes
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -109,9 +113,17 @@ public:
|
|||||||
void SetDepth( int depth );
|
void SetDepth( int depth );
|
||||||
void SetPixmap( GdkPixmap *pixmap );
|
void SetPixmap( GdkPixmap *pixmap );
|
||||||
void SetBitmap( GdkBitmap *bitmap );
|
void SetBitmap( GdkBitmap *bitmap );
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
void SetPixbuf(GdkPixbuf *pixbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
GdkPixmap *GetPixmap() const;
|
GdkPixmap *GetPixmap() const;
|
||||||
GdkBitmap *GetBitmap() const;
|
GdkBitmap *GetBitmap() const;
|
||||||
|
bool HasPixmap() const;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
bool HasPixbuf() const;
|
||||||
|
GdkPixbuf *GetPixbuf() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Basically, this corresponds to Win32 StretchBlt()
|
// Basically, this corresponds to Win32 StretchBlt()
|
||||||
wxBitmap Rescale( int clipx, int clipy, int clipwidth, int clipheight, int width, int height );
|
wxBitmap Rescale( int clipx, int clipy, int clipwidth, int clipheight, int width, int height );
|
||||||
@@ -120,6 +132,25 @@ protected:
|
|||||||
bool CreateFromImage(const wxImage& image, int depth);
|
bool CreateFromImage(const wxImage& image, int depth);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// to be called from CreateFromImage only!
|
||||||
|
bool CreateFromImageAsBitmap(const wxImage& image);
|
||||||
|
bool CreateFromImageAsPixmap(const wxImage& image);
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
bool CreateFromImageAsPixbuf(const wxImage& image);
|
||||||
|
|
||||||
|
enum Representation
|
||||||
|
{
|
||||||
|
Pixmap,
|
||||||
|
Pixbuf
|
||||||
|
};
|
||||||
|
// removes other representations from memory, keeping only 'keep'
|
||||||
|
// (wxBitmap may keep same bitmap e.g. as both pixmap and pixbuf):
|
||||||
|
void PurgeOtherRepresentations(Representation keep);
|
||||||
|
|
||||||
|
friend class wxMemoryDC;
|
||||||
|
#endif
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxBitmap)
|
DECLARE_DYNAMIC_CLASS(wxBitmap)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
#include "wx/palette.h"
|
#include "wx/palette.h"
|
||||||
#include "wx/gdiobj.h"
|
#include "wx/gdiobj.h"
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
typedef struct _GdkPixbuf GdkPixbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// classes
|
// classes
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -109,9 +113,17 @@ public:
|
|||||||
void SetDepth( int depth );
|
void SetDepth( int depth );
|
||||||
void SetPixmap( GdkPixmap *pixmap );
|
void SetPixmap( GdkPixmap *pixmap );
|
||||||
void SetBitmap( GdkBitmap *bitmap );
|
void SetBitmap( GdkBitmap *bitmap );
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
void SetPixbuf(GdkPixbuf *pixbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
GdkPixmap *GetPixmap() const;
|
GdkPixmap *GetPixmap() const;
|
||||||
GdkBitmap *GetBitmap() const;
|
GdkBitmap *GetBitmap() const;
|
||||||
|
bool HasPixmap() const;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
bool HasPixbuf() const;
|
||||||
|
GdkPixbuf *GetPixbuf() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Basically, this corresponds to Win32 StretchBlt()
|
// Basically, this corresponds to Win32 StretchBlt()
|
||||||
wxBitmap Rescale( int clipx, int clipy, int clipwidth, int clipheight, int width, int height );
|
wxBitmap Rescale( int clipx, int clipy, int clipwidth, int clipheight, int width, int height );
|
||||||
@@ -120,6 +132,25 @@ protected:
|
|||||||
bool CreateFromImage(const wxImage& image, int depth);
|
bool CreateFromImage(const wxImage& image, int depth);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// to be called from CreateFromImage only!
|
||||||
|
bool CreateFromImageAsBitmap(const wxImage& image);
|
||||||
|
bool CreateFromImageAsPixmap(const wxImage& image);
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
bool CreateFromImageAsPixbuf(const wxImage& image);
|
||||||
|
|
||||||
|
enum Representation
|
||||||
|
{
|
||||||
|
Pixmap,
|
||||||
|
Pixbuf
|
||||||
|
};
|
||||||
|
// removes other representations from memory, keeping only 'keep'
|
||||||
|
// (wxBitmap may keep same bitmap e.g. as both pixmap and pixbuf):
|
||||||
|
void PurgeOtherRepresentations(Representation keep);
|
||||||
|
|
||||||
|
friend class wxMemoryDC;
|
||||||
|
#endif
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxBitmap)
|
DECLARE_DYNAMIC_CLASS(wxBitmap)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -239,6 +239,9 @@ public:
|
|||||||
|
|
||||||
GdkPixmap *m_pixmap;
|
GdkPixmap *m_pixmap;
|
||||||
GdkBitmap *m_bitmap;
|
GdkBitmap *m_bitmap;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
GdkPixbuf *m_pixbuf;
|
||||||
|
#endif
|
||||||
wxMask *m_mask;
|
wxMask *m_mask;
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
@@ -250,6 +253,9 @@ wxBitmapRefData::wxBitmapRefData()
|
|||||||
{
|
{
|
||||||
m_pixmap = (GdkPixmap *) NULL;
|
m_pixmap = (GdkPixmap *) NULL;
|
||||||
m_bitmap = (GdkBitmap *) NULL;
|
m_bitmap = (GdkBitmap *) NULL;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
m_pixbuf = (GdkPixbuf *) NULL;
|
||||||
|
#endif
|
||||||
m_mask = (wxMask *) NULL;
|
m_mask = (wxMask *) NULL;
|
||||||
m_width = 0;
|
m_width = 0;
|
||||||
m_height = 0;
|
m_height = 0;
|
||||||
@@ -263,6 +269,10 @@ wxBitmapRefData::~wxBitmapRefData()
|
|||||||
gdk_pixmap_unref( m_pixmap );
|
gdk_pixmap_unref( m_pixmap );
|
||||||
if (m_bitmap)
|
if (m_bitmap)
|
||||||
gdk_bitmap_unref( m_bitmap );
|
gdk_bitmap_unref( m_bitmap );
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (m_pixbuf)
|
||||||
|
gdk_pixbuf_unref( m_pixbuf );
|
||||||
|
#endif
|
||||||
delete m_mask;
|
delete m_mask;
|
||||||
delete m_palette;
|
delete m_palette;
|
||||||
}
|
}
|
||||||
@@ -353,6 +363,30 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height)
|
if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
|
int width = wxMax(newx, 1);
|
||||||
|
int height = wxMax(newy, 1);
|
||||||
|
width = wxMin(width, clipwidth);
|
||||||
|
height = wxMin(height, clipheight);
|
||||||
|
|
||||||
|
wxBitmap bmp;
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
bmp.SetWidth(width);
|
||||||
|
bmp.SetHeight(height);
|
||||||
|
bmp.SetDepth(GetDepth());
|
||||||
|
bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE/*has_alpha*/,
|
||||||
|
8, width, height));
|
||||||
|
gdk_pixbuf_scale(M_BMPDATA->m_pixbuf, bmp.GetPixbuf(),
|
||||||
|
0, 0, width, height,
|
||||||
|
clipx, clipy,
|
||||||
|
(double)newx/GetWidth(), (double)newy/GetHeight(),
|
||||||
|
GDK_INTERP_BILINEAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
GdkImage *img = (GdkImage*) NULL;
|
GdkImage *img = (GdkImage*) NULL;
|
||||||
if (GetPixmap())
|
if (GetPixmap())
|
||||||
img = gdk_image_get( GetPixmap(), 0, 0, GetWidth(), GetHeight() );
|
img = gdk_image_get( GetPixmap(), 0, 0, GetWidth(), GetHeight() );
|
||||||
@@ -363,13 +397,8 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
|
|
||||||
wxCHECK_MSG( img, wxNullBitmap, wxT("couldn't create image") );
|
wxCHECK_MSG( img, wxNullBitmap, wxT("couldn't create image") );
|
||||||
|
|
||||||
wxBitmap bmp;
|
|
||||||
int bpp = -1;
|
int bpp = -1;
|
||||||
|
|
||||||
int width = wxMax(newx, 1);
|
|
||||||
int height = wxMax(newy, 1);
|
|
||||||
width = wxMin(width, clipwidth);
|
|
||||||
height = wxMin(height, clipheight);
|
|
||||||
|
|
||||||
GdkGC *gc = NULL;
|
GdkGC *gc = NULL;
|
||||||
GdkPixmap *dstpix = NULL;
|
GdkPixmap *dstpix = NULL;
|
||||||
@@ -523,40 +552,50 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
|
|
||||||
free( tablex );
|
free( tablex );
|
||||||
free( tabley );
|
free( tabley );
|
||||||
|
}
|
||||||
|
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
|
||||||
{
|
{
|
||||||
UnRef();
|
UnRef();
|
||||||
|
|
||||||
wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid image") )
|
wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
|
||||||
wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") )
|
wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") )
|
||||||
|
|
||||||
// NB: wxGTK doesn't yet support alpha channel in bitmaps. The best we can
|
if (image.GetWidth() <= 0 || image.GetHeight() <= 0)
|
||||||
// do is to convert alpha channel to mask, if it is present:
|
return false;
|
||||||
|
|
||||||
|
m_refData = new wxBitmapRefData();
|
||||||
|
|
||||||
|
if (depth == 1)
|
||||||
|
{
|
||||||
|
return CreateFromImageAsBitmap(image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (image.HasAlpha())
|
||||||
|
return CreateFromImageAsPixbuf(image);
|
||||||
|
#endif
|
||||||
|
return CreateFromImageAsPixmap(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// conversion to mono bitmap:
|
||||||
|
bool wxBitmap::CreateFromImageAsBitmap(const wxImage& img)
|
||||||
|
{
|
||||||
|
// convert alpha channel to mask, if it is present:
|
||||||
wxImage image(img);
|
wxImage image(img);
|
||||||
image.ConvertAlphaToMask();
|
image.ConvertAlphaToMask();
|
||||||
|
|
||||||
int width = image.GetWidth();
|
int width = image.GetWidth();
|
||||||
int height = image.GetHeight();
|
int height = image.GetHeight();
|
||||||
|
|
||||||
if ( width <= 0 || height <= 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_refData = new wxBitmapRefData();
|
|
||||||
|
|
||||||
SetHeight( height );
|
SetHeight( height );
|
||||||
SetWidth( width );
|
SetWidth( width );
|
||||||
|
|
||||||
// ------
|
|
||||||
// conversion to mono bitmap:
|
|
||||||
// ------
|
|
||||||
if (depth == 1)
|
|
||||||
{
|
|
||||||
SetBitmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ) );
|
SetBitmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ) );
|
||||||
|
|
||||||
SetDepth( 1 );
|
SetDepth( 1 );
|
||||||
@@ -640,13 +679,23 @@ bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
|||||||
gdk_image_destroy( mask_image );
|
gdk_image_destroy( mask_image );
|
||||||
gdk_gc_unref( mask_gc );
|
gdk_gc_unref( mask_gc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------
|
|
||||||
// conversion to colour bitmap:
|
// conversion to colour bitmap:
|
||||||
// ------
|
bool wxBitmap::CreateFromImageAsPixmap(const wxImage& img)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// convert alpha channel to mask, if it is present:
|
||||||
|
wxImage image(img);
|
||||||
|
image.ConvertAlphaToMask();
|
||||||
|
|
||||||
|
int width = image.GetWidth();
|
||||||
|
int height = image.GetHeight();
|
||||||
|
|
||||||
|
SetHeight( height );
|
||||||
|
SetWidth( width );
|
||||||
|
|
||||||
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
|
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
|
||||||
|
|
||||||
GdkVisual *visual = wxTheApp->GetGdkVisual();
|
GdkVisual *visual = wxTheApp->GetGdkVisual();
|
||||||
@@ -869,26 +918,110 @@ bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
|||||||
gdk_image_destroy( mask_image );
|
gdk_image_destroy( mask_image );
|
||||||
gdk_gc_unref( mask_gc );
|
gdk_gc_unref( mask_gc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
#ifdef __WXGTK20__
|
||||||
|
bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image)
|
||||||
|
{
|
||||||
|
int width = image.GetWidth();
|
||||||
|
int height = image.GetHeight();
|
||||||
|
|
||||||
|
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
|
||||||
|
image.HasAlpha(),
|
||||||
|
8 /* bits per sample */,
|
||||||
|
width, height);
|
||||||
|
if (!pixbuf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxASSERT( gdk_pixbuf_get_n_channels(pixbuf) == 4 );
|
||||||
|
wxASSERT( gdk_pixbuf_get_width(pixbuf) == width );
|
||||||
|
wxASSERT( gdk_pixbuf_get_height(pixbuf) == height );
|
||||||
|
|
||||||
|
M_BMPDATA->m_pixbuf = pixbuf;
|
||||||
|
SetHeight(height);
|
||||||
|
SetWidth(width);
|
||||||
|
SetDepth(wxTheApp->GetGdkVisual()->depth);
|
||||||
|
|
||||||
|
// Copy the data:
|
||||||
|
unsigned char *in = image.GetData();
|
||||||
|
unsigned char *out = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
unsigned char *alpha = image.GetAlpha();
|
||||||
|
|
||||||
|
int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width;
|
||||||
|
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++, out += rowinc)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++, alpha++, out += 4, in += 3)
|
||||||
|
{
|
||||||
|
out[0] = in[0];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[2];
|
||||||
|
out[3] = *alpha;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
|
||||||
wxImage wxBitmap::ConvertToImage() const
|
wxImage wxBitmap::ConvertToImage() const
|
||||||
{
|
{
|
||||||
// the colour used as transparent one in wxImage and the one it is replaced
|
wxImage image;
|
||||||
// with when it really occurs in the bitmap
|
|
||||||
|
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
image.Create(GetWidth(), GetHeight());
|
||||||
|
unsigned char *data = image.GetData();
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( wxT("couldn't create image") );
|
||||||
|
return wxNullImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf = GetPixbuf();
|
||||||
|
wxASSERT( gdk_pixbuf_get_has_alpha(pixbuf) );
|
||||||
|
|
||||||
|
int w = GetWidth();
|
||||||
|
int h = GetHeight();
|
||||||
|
|
||||||
|
image.SetAlpha();
|
||||||
|
|
||||||
|
unsigned char *alpha = image.GetAlpha();
|
||||||
|
unsigned char *in = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
unsigned char *out = data;
|
||||||
|
int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * w;
|
||||||
|
|
||||||
|
for (int y = 0; y < h; y++, in += rowinc)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < w; x++, in += 4, out += 3, alpha++)
|
||||||
|
{
|
||||||
|
out[0] = in[0];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[2];
|
||||||
|
*alpha = in[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
|
// the colour used as transparent one in wxImage and the one it is
|
||||||
|
// replaced with when it really occurs in the bitmap
|
||||||
static const int MASK_RED = 1;
|
static const int MASK_RED = 1;
|
||||||
static const int MASK_GREEN = 2;
|
static const int MASK_GREEN = 2;
|
||||||
static const int MASK_BLUE = 3;
|
static const int MASK_BLUE = 3;
|
||||||
static const int MASK_BLUE_REPLACEMENT = 2;
|
static const int MASK_BLUE_REPLACEMENT = 2;
|
||||||
|
|
||||||
wxImage image;
|
|
||||||
|
|
||||||
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
|
||||||
|
|
||||||
GdkImage *gdk_image = (GdkImage*) NULL;
|
GdkImage *gdk_image = (GdkImage*) NULL;
|
||||||
if (GetPixmap())
|
|
||||||
|
if (HasPixmap())
|
||||||
{
|
{
|
||||||
gdk_image = gdk_image_get( GetPixmap(),
|
gdk_image = gdk_image_get( GetPixmap(),
|
||||||
0, 0,
|
0, 0,
|
||||||
@@ -907,16 +1040,6 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
|
|
||||||
wxCHECK_MSG( gdk_image, wxNullImage, wxT("couldn't create image") );
|
wxCHECK_MSG( gdk_image, wxNullImage, wxT("couldn't create image") );
|
||||||
|
|
||||||
image.Create( GetWidth(), GetHeight() );
|
|
||||||
char unsigned *data = image.GetData();
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
gdk_image_destroy( gdk_image );
|
|
||||||
wxFAIL_MSG( wxT("couldn't create image") );
|
|
||||||
return wxNullImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkImage *gdk_image_mask = (GdkImage*) NULL;
|
GdkImage *gdk_image_mask = (GdkImage*) NULL;
|
||||||
if (GetMask())
|
if (GetMask())
|
||||||
{
|
{
|
||||||
@@ -1023,6 +1146,7 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
|
|
||||||
gdk_image_destroy( gdk_image );
|
gdk_image_destroy( gdk_image );
|
||||||
if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
|
if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
|
||||||
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -1084,7 +1208,13 @@ bool wxBitmap::operator != ( const wxBitmap& bmp ) const
|
|||||||
|
|
||||||
bool wxBitmap::Ok() const
|
bool wxBitmap::Ok() const
|
||||||
{
|
{
|
||||||
return (m_refData != NULL) && (M_BMPDATA->m_bitmap || M_BMPDATA->m_pixmap);
|
return (m_refData != NULL) &&
|
||||||
|
(
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
M_BMPDATA->m_pixbuf ||
|
||||||
|
#endif
|
||||||
|
M_BMPDATA->m_bitmap || M_BMPDATA->m_pixmap
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxBitmap::GetHeight() const
|
int wxBitmap::GetHeight() const
|
||||||
@@ -1140,6 +1270,20 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
|
|||||||
wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
|
wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
|
||||||
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
|
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
|
||||||
|
TRUE/*has_alpha*/,
|
||||||
|
8, GetWidth(), GetHeight());
|
||||||
|
ret.SetPixbuf(pixbuf);
|
||||||
|
gdk_pixbuf_copy_area(M_BMPDATA->m_pixbuf,
|
||||||
|
rect.x, rect.y, rect.width, rect.height,
|
||||||
|
pixbuf, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
if (ret.GetPixmap())
|
if (ret.GetPixmap())
|
||||||
{
|
{
|
||||||
GdkGC *gc = gdk_gc_new( ret.GetPixmap() );
|
GdkGC *gc = gdk_gc_new( ret.GetPixmap() );
|
||||||
@@ -1157,6 +1301,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
|
|||||||
gdk_wx_draw_bitmap( ret.GetBitmap(), gc, GetBitmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
|
gdk_wx_draw_bitmap( ret.GetBitmap(), gc, GetBitmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
|
||||||
gdk_gc_destroy( gc );
|
gdk_gc_destroy( gc );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GetMask())
|
if (GetMask())
|
||||||
{
|
{
|
||||||
@@ -1288,12 +1433,69 @@ GdkPixmap *wxBitmap::GetPixmap() const
|
|||||||
{
|
{
|
||||||
wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, wxT("invalid bitmap") );
|
wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
// create the pixmap on the fly if we use Pixbuf representation:
|
||||||
|
if (HasPixbuf() && !HasPixmap())
|
||||||
|
{
|
||||||
|
gdk_pixbuf_render_pixmap_and_mask(M_BMPDATA->m_pixbuf,
|
||||||
|
&M_BMPDATA->m_pixmap,
|
||||||
|
NULL /*mask*/,
|
||||||
|
128 /*threshold*/);
|
||||||
|
}
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
|
||||||
return M_BMPDATA->m_pixmap;
|
return M_BMPDATA->m_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxBitmap::HasPixmap() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixmap != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
GdkBitmap *wxBitmap::GetBitmap() const
|
GdkBitmap *wxBitmap::GetBitmap() const
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, wxT("invalid bitmap") );
|
wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
return M_BMPDATA->m_bitmap;
|
return M_BMPDATA->m_bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
GdkPixbuf *wxBitmap::GetPixbuf() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxBitmap::HasPixbuf() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixbuf != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxBitmap::SetPixbuf( GdkPixbuf *pixbuf )
|
||||||
|
{
|
||||||
|
if (!m_refData)
|
||||||
|
m_refData = new wxBitmapRefData();
|
||||||
|
|
||||||
|
M_BMPDATA->m_pixbuf = pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep)
|
||||||
|
{
|
||||||
|
if (keep == Pixmap && HasPixbuf())
|
||||||
|
{
|
||||||
|
gdk_pixbuf_unref( M_BMPDATA->m_pixbuf );
|
||||||
|
M_BMPDATA->m_pixbuf = NULL;
|
||||||
|
}
|
||||||
|
if (keep == Pixbuf && HasPixmap())
|
||||||
|
{
|
||||||
|
gdk_pixmap_unref( M_BMPDATA->m_pixmap );
|
||||||
|
M_BMPDATA->m_pixmap = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
@@ -1147,7 +1147,21 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
|
#if GTK_CHECK_VERSION(2,2,0)
|
||||||
|
if (use_bitmap.HasPixbuf())
|
||||||
|
{
|
||||||
|
gdk_draw_pixbuf(m_window, m_penGC,
|
||||||
|
use_bitmap.GetPixbuf(),
|
||||||
|
0, 0, xx, yy, -1, -1,
|
||||||
|
GDK_RGB_DITHER_NORMAL, xx, yy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gdk_draw_pixmap(m_window, m_penGC,
|
||||||
|
use_bitmap.GetPixmap(),
|
||||||
|
0, 0, xx, yy, -1, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove mask again if any
|
// remove mask again if any
|
||||||
|
@@ -239,6 +239,9 @@ public:
|
|||||||
|
|
||||||
GdkPixmap *m_pixmap;
|
GdkPixmap *m_pixmap;
|
||||||
GdkBitmap *m_bitmap;
|
GdkBitmap *m_bitmap;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
GdkPixbuf *m_pixbuf;
|
||||||
|
#endif
|
||||||
wxMask *m_mask;
|
wxMask *m_mask;
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
@@ -250,6 +253,9 @@ wxBitmapRefData::wxBitmapRefData()
|
|||||||
{
|
{
|
||||||
m_pixmap = (GdkPixmap *) NULL;
|
m_pixmap = (GdkPixmap *) NULL;
|
||||||
m_bitmap = (GdkBitmap *) NULL;
|
m_bitmap = (GdkBitmap *) NULL;
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
m_pixbuf = (GdkPixbuf *) NULL;
|
||||||
|
#endif
|
||||||
m_mask = (wxMask *) NULL;
|
m_mask = (wxMask *) NULL;
|
||||||
m_width = 0;
|
m_width = 0;
|
||||||
m_height = 0;
|
m_height = 0;
|
||||||
@@ -263,6 +269,10 @@ wxBitmapRefData::~wxBitmapRefData()
|
|||||||
gdk_pixmap_unref( m_pixmap );
|
gdk_pixmap_unref( m_pixmap );
|
||||||
if (m_bitmap)
|
if (m_bitmap)
|
||||||
gdk_bitmap_unref( m_bitmap );
|
gdk_bitmap_unref( m_bitmap );
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (m_pixbuf)
|
||||||
|
gdk_pixbuf_unref( m_pixbuf );
|
||||||
|
#endif
|
||||||
delete m_mask;
|
delete m_mask;
|
||||||
delete m_palette;
|
delete m_palette;
|
||||||
}
|
}
|
||||||
@@ -353,6 +363,30 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height)
|
if (newy==M_BMPDATA->m_width && newy==M_BMPDATA->m_height)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
|
int width = wxMax(newx, 1);
|
||||||
|
int height = wxMax(newy, 1);
|
||||||
|
width = wxMin(width, clipwidth);
|
||||||
|
height = wxMin(height, clipheight);
|
||||||
|
|
||||||
|
wxBitmap bmp;
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
bmp.SetWidth(width);
|
||||||
|
bmp.SetHeight(height);
|
||||||
|
bmp.SetDepth(GetDepth());
|
||||||
|
bmp.SetPixbuf(gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE/*has_alpha*/,
|
||||||
|
8, width, height));
|
||||||
|
gdk_pixbuf_scale(M_BMPDATA->m_pixbuf, bmp.GetPixbuf(),
|
||||||
|
0, 0, width, height,
|
||||||
|
clipx, clipy,
|
||||||
|
(double)newx/GetWidth(), (double)newy/GetHeight(),
|
||||||
|
GDK_INTERP_BILINEAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
GdkImage *img = (GdkImage*) NULL;
|
GdkImage *img = (GdkImage*) NULL;
|
||||||
if (GetPixmap())
|
if (GetPixmap())
|
||||||
img = gdk_image_get( GetPixmap(), 0, 0, GetWidth(), GetHeight() );
|
img = gdk_image_get( GetPixmap(), 0, 0, GetWidth(), GetHeight() );
|
||||||
@@ -363,13 +397,8 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
|
|
||||||
wxCHECK_MSG( img, wxNullBitmap, wxT("couldn't create image") );
|
wxCHECK_MSG( img, wxNullBitmap, wxT("couldn't create image") );
|
||||||
|
|
||||||
wxBitmap bmp;
|
|
||||||
int bpp = -1;
|
int bpp = -1;
|
||||||
|
|
||||||
int width = wxMax(newx, 1);
|
|
||||||
int height = wxMax(newy, 1);
|
|
||||||
width = wxMin(width, clipwidth);
|
|
||||||
height = wxMin(height, clipheight);
|
|
||||||
|
|
||||||
GdkGC *gc = NULL;
|
GdkGC *gc = NULL;
|
||||||
GdkPixmap *dstpix = NULL;
|
GdkPixmap *dstpix = NULL;
|
||||||
@@ -523,40 +552,50 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
|
|||||||
|
|
||||||
free( tablex );
|
free( tablex );
|
||||||
free( tabley );
|
free( tabley );
|
||||||
|
}
|
||||||
|
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
|
||||||
{
|
{
|
||||||
UnRef();
|
UnRef();
|
||||||
|
|
||||||
wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid image") )
|
wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
|
||||||
wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") )
|
wxCHECK_MSG( depth == -1 || depth == 1, FALSE, wxT("invalid bitmap depth") )
|
||||||
|
|
||||||
// NB: wxGTK doesn't yet support alpha channel in bitmaps. The best we can
|
if (image.GetWidth() <= 0 || image.GetHeight() <= 0)
|
||||||
// do is to convert alpha channel to mask, if it is present:
|
return false;
|
||||||
|
|
||||||
|
m_refData = new wxBitmapRefData();
|
||||||
|
|
||||||
|
if (depth == 1)
|
||||||
|
{
|
||||||
|
return CreateFromImageAsBitmap(image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (image.HasAlpha())
|
||||||
|
return CreateFromImageAsPixbuf(image);
|
||||||
|
#endif
|
||||||
|
return CreateFromImageAsPixmap(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// conversion to mono bitmap:
|
||||||
|
bool wxBitmap::CreateFromImageAsBitmap(const wxImage& img)
|
||||||
|
{
|
||||||
|
// convert alpha channel to mask, if it is present:
|
||||||
wxImage image(img);
|
wxImage image(img);
|
||||||
image.ConvertAlphaToMask();
|
image.ConvertAlphaToMask();
|
||||||
|
|
||||||
int width = image.GetWidth();
|
int width = image.GetWidth();
|
||||||
int height = image.GetHeight();
|
int height = image.GetHeight();
|
||||||
|
|
||||||
if ( width <= 0 || height <= 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_refData = new wxBitmapRefData();
|
|
||||||
|
|
||||||
SetHeight( height );
|
SetHeight( height );
|
||||||
SetWidth( width );
|
SetWidth( width );
|
||||||
|
|
||||||
// ------
|
|
||||||
// conversion to mono bitmap:
|
|
||||||
// ------
|
|
||||||
if (depth == 1)
|
|
||||||
{
|
|
||||||
SetBitmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ) );
|
SetBitmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ) );
|
||||||
|
|
||||||
SetDepth( 1 );
|
SetDepth( 1 );
|
||||||
@@ -640,13 +679,23 @@ bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
|||||||
gdk_image_destroy( mask_image );
|
gdk_image_destroy( mask_image );
|
||||||
gdk_gc_unref( mask_gc );
|
gdk_gc_unref( mask_gc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------
|
|
||||||
// conversion to colour bitmap:
|
// conversion to colour bitmap:
|
||||||
// ------
|
bool wxBitmap::CreateFromImageAsPixmap(const wxImage& img)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// convert alpha channel to mask, if it is present:
|
||||||
|
wxImage image(img);
|
||||||
|
image.ConvertAlphaToMask();
|
||||||
|
|
||||||
|
int width = image.GetWidth();
|
||||||
|
int height = image.GetHeight();
|
||||||
|
|
||||||
|
SetHeight( height );
|
||||||
|
SetWidth( width );
|
||||||
|
|
||||||
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
|
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
|
||||||
|
|
||||||
GdkVisual *visual = wxTheApp->GetGdkVisual();
|
GdkVisual *visual = wxTheApp->GetGdkVisual();
|
||||||
@@ -869,26 +918,110 @@ bool wxBitmap::CreateFromImage( const wxImage& img, int depth )
|
|||||||
gdk_image_destroy( mask_image );
|
gdk_image_destroy( mask_image );
|
||||||
gdk_gc_unref( mask_gc );
|
gdk_gc_unref( mask_gc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
#ifdef __WXGTK20__
|
||||||
|
bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image)
|
||||||
|
{
|
||||||
|
int width = image.GetWidth();
|
||||||
|
int height = image.GetHeight();
|
||||||
|
|
||||||
|
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
|
||||||
|
image.HasAlpha(),
|
||||||
|
8 /* bits per sample */,
|
||||||
|
width, height);
|
||||||
|
if (!pixbuf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxASSERT( gdk_pixbuf_get_n_channels(pixbuf) == 4 );
|
||||||
|
wxASSERT( gdk_pixbuf_get_width(pixbuf) == width );
|
||||||
|
wxASSERT( gdk_pixbuf_get_height(pixbuf) == height );
|
||||||
|
|
||||||
|
M_BMPDATA->m_pixbuf = pixbuf;
|
||||||
|
SetHeight(height);
|
||||||
|
SetWidth(width);
|
||||||
|
SetDepth(wxTheApp->GetGdkVisual()->depth);
|
||||||
|
|
||||||
|
// Copy the data:
|
||||||
|
unsigned char *in = image.GetData();
|
||||||
|
unsigned char *out = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
unsigned char *alpha = image.GetAlpha();
|
||||||
|
|
||||||
|
int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * width;
|
||||||
|
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++, out += rowinc)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++, alpha++, out += 4, in += 3)
|
||||||
|
{
|
||||||
|
out[0] = in[0];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[2];
|
||||||
|
out[3] = *alpha;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
|
||||||
wxImage wxBitmap::ConvertToImage() const
|
wxImage wxBitmap::ConvertToImage() const
|
||||||
{
|
{
|
||||||
// the colour used as transparent one in wxImage and the one it is replaced
|
wxImage image;
|
||||||
// with when it really occurs in the bitmap
|
|
||||||
|
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
image.Create(GetWidth(), GetHeight());
|
||||||
|
unsigned char *data = image.GetData();
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( wxT("couldn't create image") );
|
||||||
|
return wxNullImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf = GetPixbuf();
|
||||||
|
wxASSERT( gdk_pixbuf_get_has_alpha(pixbuf) );
|
||||||
|
|
||||||
|
int w = GetWidth();
|
||||||
|
int h = GetHeight();
|
||||||
|
|
||||||
|
image.SetAlpha();
|
||||||
|
|
||||||
|
unsigned char *alpha = image.GetAlpha();
|
||||||
|
unsigned char *in = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
unsigned char *out = data;
|
||||||
|
int rowinc = gdk_pixbuf_get_rowstride(pixbuf) - 4 * w;
|
||||||
|
|
||||||
|
for (int y = 0; y < h; y++, in += rowinc)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < w; x++, in += 4, out += 3, alpha++)
|
||||||
|
{
|
||||||
|
out[0] = in[0];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[2];
|
||||||
|
*alpha = in[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
|
// the colour used as transparent one in wxImage and the one it is
|
||||||
|
// replaced with when it really occurs in the bitmap
|
||||||
static const int MASK_RED = 1;
|
static const int MASK_RED = 1;
|
||||||
static const int MASK_GREEN = 2;
|
static const int MASK_GREEN = 2;
|
||||||
static const int MASK_BLUE = 3;
|
static const int MASK_BLUE = 3;
|
||||||
static const int MASK_BLUE_REPLACEMENT = 2;
|
static const int MASK_BLUE_REPLACEMENT = 2;
|
||||||
|
|
||||||
wxImage image;
|
|
||||||
|
|
||||||
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
|
||||||
|
|
||||||
GdkImage *gdk_image = (GdkImage*) NULL;
|
GdkImage *gdk_image = (GdkImage*) NULL;
|
||||||
if (GetPixmap())
|
|
||||||
|
if (HasPixmap())
|
||||||
{
|
{
|
||||||
gdk_image = gdk_image_get( GetPixmap(),
|
gdk_image = gdk_image_get( GetPixmap(),
|
||||||
0, 0,
|
0, 0,
|
||||||
@@ -907,16 +1040,6 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
|
|
||||||
wxCHECK_MSG( gdk_image, wxNullImage, wxT("couldn't create image") );
|
wxCHECK_MSG( gdk_image, wxNullImage, wxT("couldn't create image") );
|
||||||
|
|
||||||
image.Create( GetWidth(), GetHeight() );
|
|
||||||
char unsigned *data = image.GetData();
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
gdk_image_destroy( gdk_image );
|
|
||||||
wxFAIL_MSG( wxT("couldn't create image") );
|
|
||||||
return wxNullImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkImage *gdk_image_mask = (GdkImage*) NULL;
|
GdkImage *gdk_image_mask = (GdkImage*) NULL;
|
||||||
if (GetMask())
|
if (GetMask())
|
||||||
{
|
{
|
||||||
@@ -1023,6 +1146,7 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
|
|
||||||
gdk_image_destroy( gdk_image );
|
gdk_image_destroy( gdk_image );
|
||||||
if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
|
if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
|
||||||
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -1084,7 +1208,13 @@ bool wxBitmap::operator != ( const wxBitmap& bmp ) const
|
|||||||
|
|
||||||
bool wxBitmap::Ok() const
|
bool wxBitmap::Ok() const
|
||||||
{
|
{
|
||||||
return (m_refData != NULL) && (M_BMPDATA->m_bitmap || M_BMPDATA->m_pixmap);
|
return (m_refData != NULL) &&
|
||||||
|
(
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
M_BMPDATA->m_pixbuf ||
|
||||||
|
#endif
|
||||||
|
M_BMPDATA->m_bitmap || M_BMPDATA->m_pixmap
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxBitmap::GetHeight() const
|
int wxBitmap::GetHeight() const
|
||||||
@@ -1140,6 +1270,20 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
|
|||||||
wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
|
wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
|
||||||
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
|
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
if (HasPixbuf())
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
|
||||||
|
TRUE/*has_alpha*/,
|
||||||
|
8, GetWidth(), GetHeight());
|
||||||
|
ret.SetPixbuf(pixbuf);
|
||||||
|
gdk_pixbuf_copy_area(M_BMPDATA->m_pixbuf,
|
||||||
|
rect.x, rect.y, rect.width, rect.height,
|
||||||
|
pixbuf, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
{
|
||||||
if (ret.GetPixmap())
|
if (ret.GetPixmap())
|
||||||
{
|
{
|
||||||
GdkGC *gc = gdk_gc_new( ret.GetPixmap() );
|
GdkGC *gc = gdk_gc_new( ret.GetPixmap() );
|
||||||
@@ -1157,6 +1301,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
|
|||||||
gdk_wx_draw_bitmap( ret.GetBitmap(), gc, GetBitmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
|
gdk_wx_draw_bitmap( ret.GetBitmap(), gc, GetBitmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
|
||||||
gdk_gc_destroy( gc );
|
gdk_gc_destroy( gc );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GetMask())
|
if (GetMask())
|
||||||
{
|
{
|
||||||
@@ -1288,12 +1433,69 @@ GdkPixmap *wxBitmap::GetPixmap() const
|
|||||||
{
|
{
|
||||||
wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, wxT("invalid bitmap") );
|
wxCHECK_MSG( Ok(), (GdkPixmap *) NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
// create the pixmap on the fly if we use Pixbuf representation:
|
||||||
|
if (HasPixbuf() && !HasPixmap())
|
||||||
|
{
|
||||||
|
gdk_pixbuf_render_pixmap_and_mask(M_BMPDATA->m_pixbuf,
|
||||||
|
&M_BMPDATA->m_pixmap,
|
||||||
|
NULL /*mask*/,
|
||||||
|
128 /*threshold*/);
|
||||||
|
}
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
|
||||||
return M_BMPDATA->m_pixmap;
|
return M_BMPDATA->m_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxBitmap::HasPixmap() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixmap != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
GdkBitmap *wxBitmap::GetBitmap() const
|
GdkBitmap *wxBitmap::GetBitmap() const
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, wxT("invalid bitmap") );
|
wxCHECK_MSG( Ok(), (GdkBitmap *) NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
return M_BMPDATA->m_bitmap;
|
return M_BMPDATA->m_bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
GdkPixbuf *wxBitmap::GetPixbuf() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxBitmap::HasPixbuf() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
return M_BMPDATA->m_pixbuf != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxBitmap::SetPixbuf( GdkPixbuf *pixbuf )
|
||||||
|
{
|
||||||
|
if (!m_refData)
|
||||||
|
m_refData = new wxBitmapRefData();
|
||||||
|
|
||||||
|
M_BMPDATA->m_pixbuf = pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep)
|
||||||
|
{
|
||||||
|
if (keep == Pixmap && HasPixbuf())
|
||||||
|
{
|
||||||
|
gdk_pixbuf_unref( M_BMPDATA->m_pixbuf );
|
||||||
|
M_BMPDATA->m_pixbuf = NULL;
|
||||||
|
}
|
||||||
|
if (keep == Pixbuf && HasPixmap())
|
||||||
|
{
|
||||||
|
gdk_pixmap_unref( M_BMPDATA->m_pixmap );
|
||||||
|
M_BMPDATA->m_pixmap = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
@@ -1147,7 +1147,21 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
|
#if GTK_CHECK_VERSION(2,2,0)
|
||||||
|
if (use_bitmap.HasPixbuf())
|
||||||
|
{
|
||||||
|
gdk_draw_pixbuf(m_window, m_penGC,
|
||||||
|
use_bitmap.GetPixbuf(),
|
||||||
|
0, 0, xx, yy, -1, -1,
|
||||||
|
GDK_RGB_DITHER_NORMAL, xx, yy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gdk_draw_pixmap(m_window, m_penGC,
|
||||||
|
use_bitmap.GetPixmap(),
|
||||||
|
0, 0, xx, yy, -1, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove mask again if any
|
// remove mask again if any
|
||||||
|
Reference in New Issue
Block a user