add wxMask::GetBitmap(), closes #9381

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73409 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett 2013-01-20 06:28:11 +00:00
parent 3e118784c7
commit 5ca21fe7bf
13 changed files with 95 additions and 47 deletions

View File

@ -606,6 +606,7 @@ All (GUI):
- Add wxListCtrl::EnableAlternateRowColours() (troelsk). - Add wxListCtrl::EnableAlternateRowColours() (troelsk).
- Fix wrong tab order in wxAuiNotebook after dragging (Mark Barber). - Fix wrong tab order in wxAuiNotebook after dragging (Mark Barber).
- Fix bug in generic wxDataViewCtrl column dragging (jobuz). - Fix bug in generic wxDataViewCtrl column dragging (jobuz).
- Add wxMask::GetBitmap() for wxMSW, wxGTK and wxOSX
wxGTK: wxGTK:

View File

@ -32,14 +32,15 @@ public:
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
wxMask( const wxBitmap& bitmap ); wxMask( const wxBitmap& bitmap );
virtual ~wxMask(); virtual ~wxMask();
wxBitmap GetBitmap() const;
// implementation // implementation
#ifdef __WXGTK3__ #ifdef __WXGTK3__
wxMask(cairo_surface_t*); wxMask(cairo_surface_t*);
cairo_surface_t* GetBitmap() const; operator cairo_surface_t*() const;
#else #else
wxMask(GdkPixmap*); wxMask(GdkPixmap*);
GdkPixmap* GetBitmap() const; operator GdkPixmap*() const;
#endif #endif
protected: protected:
@ -80,7 +81,7 @@ public:
#if wxUSE_IMAGE #if wxUSE_IMAGE
wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH); wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH);
#endif // wxUSE_IMAGE #endif // wxUSE_IMAGE
wxBitmap(GdkPixbuf* pixbuf); wxBitmap(GdkPixbuf* pixbuf, int depth = 0);
virtual ~wxBitmap(); virtual ~wxBitmap();
bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH); bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH);
@ -132,6 +133,7 @@ public:
GdkPixmap *GetPixmap() const; GdkPixmap *GetPixmap() const;
bool HasPixmap() const; bool HasPixmap() const;
bool HasPixbuf() const; bool HasPixbuf() const;
wxBitmap(GdkPixmap* pixmap);
#endif #endif
GdkPixbuf *GetPixbuf() const; GdkPixbuf *GetPixbuf() const;

View File

@ -160,7 +160,6 @@ public:
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
wxMask *GetMask() const; wxMask *GetMask() const;
wxBitmap GetMaskBitmap() const;
void SetMask(wxMask *mask); void SetMask(wxMask *mask);
// these functions are internal and shouldn't be used, they risk to // these functions are internal and shouldn't be used, they risk to
@ -238,6 +237,8 @@ public:
bool Create(const wxBitmap& bitmap, int paletteIndex); bool Create(const wxBitmap& bitmap, int paletteIndex);
bool Create(const wxBitmap& bitmap); bool Create(const wxBitmap& bitmap);
wxBitmap GetBitmap() const;
// Implementation // Implementation
WXHBITMAP GetMaskBitmap() const { return m_maskBitmap; } WXHBITMAP GetMaskBitmap() const { return m_maskBitmap; }
void SetMaskBitmap(WXHBITMAP bmp) { m_maskBitmap = bmp; } void SetMaskBitmap(WXHBITMAP bmp) { m_maskBitmap = bmp; }

View File

@ -57,6 +57,8 @@ public:
bool Create(const wxBitmap& bitmap); bool Create(const wxBitmap& bitmap);
bool Create(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ; bool Create(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ;
wxBitmap GetBitmap() const;
// Implementation below // Implementation below
void Init() ; void Init() ;

View File

@ -769,5 +769,13 @@ public:
Constructs a mask from a bitmap and a colour that indicates the background. Constructs a mask from a bitmap and a colour that indicates the background.
*/ */
bool Create(const wxBitmap& bitmap, const wxColour& colour); bool Create(const wxBitmap& bitmap, const wxColour& colour);
/**
Returns the mask as a monochrome bitmap.
Currently this method is implemented in wxMSW, wxGTK and wxOSX.
@since 2.9.5
*/
wxBitmap GetBitmap() const;
}; };

View File

@ -1404,7 +1404,7 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
// fully transparent or fully opaque // fully transparent or fully opaque
if (bmpSource.GetMask()) if (bmpSource.GetMask())
{ {
wxBitmap bmpMask = bmpSource.GetMaskBitmap(); wxBitmap bmpMask = bmpSource.GetMask()->GetBitmap();
bufferFormat = CAIRO_FORMAT_ARGB32; bufferFormat = CAIRO_FORMAT_ARGB32;
data = (wxUint32*)m_buffer; data = (wxUint32*)m_buffer;
wxNativePixelData wxNativePixelData

View File

@ -274,9 +274,9 @@ bool wxMask::InitFromMonoBitmap(const wxBitmap& bitmap)
} }
#ifdef __WXGTK3__ #ifdef __WXGTK3__
cairo_surface_t* wxMask::GetBitmap() const wxMask::operator cairo_surface_t*() const
#else #else
GdkPixmap* wxMask::GetBitmap() const wxMask::operator GdkPixmap*() const
#endif #endif
{ {
return m_bitmap; return m_bitmap;
@ -442,13 +442,15 @@ wxBitmap::wxBitmap(const char* const* bits)
#endif #endif
} }
wxBitmap::wxBitmap(GdkPixbuf* pixbuf) wxBitmap::wxBitmap(GdkPixbuf* pixbuf, int depth)
{ {
if (pixbuf) if (pixbuf)
{ {
if (depth != 1)
depth = gdk_pixbuf_get_n_channels(pixbuf) * 8;
wxBitmapRefData* bmpData = new wxBitmapRefData( wxBitmapRefData* bmpData = new wxBitmapRefData(
gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
gdk_pixbuf_get_n_channels(pixbuf) * 8); depth);
m_refData = bmpData; m_refData = bmpData;
#ifdef __WXGTK3__ #ifdef __WXGTK3__
bmpData->m_pixbufNoMask = pixbuf; bmpData->m_pixbufNoMask = pixbuf;
@ -458,6 +460,21 @@ wxBitmap::wxBitmap(GdkPixbuf* pixbuf)
} }
} }
#ifndef __WXGTK3__
wxBitmap::wxBitmap(GdkPixmap* pixmap)
{
if (pixmap)
{
int w, h;
gdk_drawable_get_size(pixmap, &w, &h);
wxBitmapRefData* bmpData =
new wxBitmapRefData(w, h, gdk_drawable_get_depth(pixmap));
m_refData = bmpData;
bmpData->m_pixmap = pixmap;
}
}
#endif
wxBitmap::~wxBitmap() wxBitmap::~wxBitmap()
{ {
} }
@ -730,7 +747,7 @@ wxImage wxBitmap::ConvertToImage() const
} }
cairo_surface_t* maskSurf = NULL; cairo_surface_t* maskSurf = NULL;
if (bmpData->m_mask) if (bmpData->m_mask)
maskSurf = bmpData->m_mask->GetBitmap(); maskSurf = *bmpData->m_mask;
if (maskSurf) if (maskSurf)
{ {
const guchar r = 1; const guchar r = 1;
@ -826,7 +843,7 @@ wxImage wxBitmap::ConvertToImage() const
const int MASK_BLUE_REPLACEMENT = 2; const int MASK_BLUE_REPLACEMENT = 2;
image.SetMaskColour(MASK_RED, MASK_GREEN, MASK_BLUE); image.SetMaskColour(MASK_RED, MASK_GREEN, MASK_BLUE);
GdkImage* image_mask = gdk_drawable_get_image(GetMask()->GetBitmap(), 0, 0, w, h); GdkImage* image_mask = gdk_drawable_get_image(*GetMask(), 0, 0, w, h);
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
@ -892,16 +909,13 @@ void wxBitmap::SetMask( wxMask *mask )
M_BMPDATA->m_mask = mask; M_BMPDATA->m_mask = mask;
} }
wxBitmap wxBitmap::GetMaskBitmap() const wxBitmap wxMask::GetBitmap() const
{ {
wxBitmap bitmap; wxBitmap bitmap;
wxBitmapRefData* bmpData = M_BMPDATA; if (m_bitmap)
#ifdef __WXGTK3__
cairo_surface_t* mask = NULL;
if (bmpData && bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap();
if (mask)
{ {
#ifdef __WXGTK3__
cairo_surface_t* mask = m_bitmap;
const int w = cairo_image_surface_get_width(mask); const int w = cairo_image_surface_get_width(mask);
const int h = cairo_image_surface_get_height(mask); const int h = cairo_image_surface_get_height(mask);
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, w, h); GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, w, h);
@ -919,21 +933,19 @@ wxBitmap wxBitmap::GetMaskBitmap() const
d[2] = src[i]; d[2] = src[i];
} }
} }
bitmap = wxBitmap(pixbuf); bitmap = wxBitmap(pixbuf, 1);
}
#else #else
GdkPixmap* mask = NULL; GdkPixmap* mask = m_bitmap;
if (bmpData && bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap();
if (mask)
{
int w, h; int w, h;
gdk_drawable_get_size(mask, &w, &h); gdk_drawable_get_size(mask, &w, &h);
GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable( GdkPixmap* pixmap = gdk_pixmap_new(mask, w, h, -1);
NULL, mask, NULL, 0, 0, 0, 0, w, h); GdkGC* gc = gdk_gc_new(pixmap);
bitmap = wxBitmap(pixbuf); gdk_gc_set_function(gc, GDK_COPY_INVERT);
} gdk_draw_drawable(pixmap, gc, mask, 0, 0, 0, 0, w, h);
g_object_unref(gc);
bitmap = wxBitmap(pixmap);
#endif #endif
}
return bitmap; return bitmap;
} }
@ -994,7 +1006,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
cairo_surface_t* maskSurf = NULL; cairo_surface_t* maskSurf = NULL;
if (bmpData->m_mask) if (bmpData->m_mask)
maskSurf = bmpData->m_mask->GetBitmap(); maskSurf = *bmpData->m_mask;
if (maskSurf) if (maskSurf)
{ {
newRef->m_mask = new wxMask(GetSubSurface(maskSurf, rect)); newRef->m_mask = new wxMask(GetSubSurface(maskSurf, rect));
@ -1017,7 +1029,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
} }
GdkPixmap* mask = NULL; GdkPixmap* mask = NULL;
if (bmpData->m_mask) if (bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap(); mask = *bmpData->m_mask;
if (mask) if (mask)
{ {
GdkPixmap* sub_mask = gdk_pixmap_new(mask, w, h, 1); GdkPixmap* sub_mask = gdk_pixmap_new(mask, w, h, 1);
@ -1289,7 +1301,7 @@ void wxBitmap::Draw(cairo_t* cr, int x, int y, bool useMask, const wxColour* fg,
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
cairo_surface_t* mask = NULL; cairo_surface_t* mask = NULL;
if (useMask && bmpData->m_mask) if (useMask && bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap(); mask = *bmpData->m_mask;
if (mask) if (mask)
cairo_mask_surface(cr, mask, x, y); cairo_mask_surface(cr, mask, x, y);
else else
@ -1310,7 +1322,7 @@ GdkPixbuf *wxBitmap::GetPixbuf() const
GetPixbufNoMask(); GetPixbufNoMask();
cairo_surface_t* mask = NULL; cairo_surface_t* mask = NULL;
if (bmpData->m_mask) if (bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap(); mask = *bmpData->m_mask;
if (mask == NULL) if (mask == NULL)
return bmpData->m_pixbufNoMask; return bmpData->m_pixbufNoMask;
@ -1342,7 +1354,7 @@ GdkPixbuf *wxBitmap::GetPixbuf() const
const int h = bmpData->m_height; const int h = bmpData->m_height;
GdkPixmap* mask = NULL; GdkPixmap* mask = NULL;
if (bmpData->m_mask) if (bmpData->m_mask)
mask = bmpData->m_mask->GetBitmap(); mask = *bmpData->m_mask;
const bool useAlpha = bmpData->m_alphaRequested || mask; const bool useAlpha = bmpData->m_alphaRequested || mask;
bmpData->m_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, useAlpha, 8, w, h); bmpData->m_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, useAlpha, 8, w, h);
if (bmpData->m_pixmap) if (bmpData->m_pixmap)

View File

@ -154,7 +154,7 @@ bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dst
{ {
wxMask* mask = bitmap.GetMask(); wxMask* mask = bitmap.GetMask();
if (mask) if (mask)
maskSurf = mask->GetBitmap(); maskSurf = *mask;
} }
} }
if (maskSurf) if (maskSurf)

View File

@ -1130,7 +1130,7 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap,
{ {
wxMask* m = bitmap.GetMask(); wxMask* m = bitmap.GetMask();
if (m) if (m)
mask = m->GetBitmap(); mask = *m;
} }
if (mask) if (mask)
{ {
@ -1228,7 +1228,7 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest,
{ {
wxMask* m = bitmap.GetMask(); wxMask* m = bitmap.GetMask();
if (m) if (m)
mask = m->GetBitmap(); mask = *m;
} }
} }
else else
@ -1796,7 +1796,7 @@ void wxWindowDCImpl::SetBrush( const wxBrush &brush )
if ((m_brush.GetStyle() == wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask())) if ((m_brush.GetStyle() == wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask()))
{ {
gdk_gc_set_fill( m_textGC, GDK_OPAQUE_STIPPLED); gdk_gc_set_fill( m_textGC, GDK_OPAQUE_STIPPLED);
gdk_gc_set_stipple( m_textGC, m_brush.GetStipple()->GetMask()->GetBitmap() ); gdk_gc_set_stipple( m_textGC, *m_brush.GetStipple()->GetMask() );
} }
if (m_brush.IsHatch()) if (m_brush.IsHatch())

View File

@ -764,7 +764,7 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
#ifndef __WXGTK3__ #ifndef __WXGTK3__
GdkBitmap *mask; GdkBitmap *mask;
if ( icon->GetMask() ) if ( icon->GetMask() )
mask = icon->GetMask()->GetBitmap(); mask = *icon->GetMask();
else else
mask = NULL; mask = NULL;
@ -796,7 +796,9 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
cairo_pattern_t* pattern = cairo_get_source(cr); cairo_pattern_t* pattern = cairo_get_source(cr);
gdk_window_set_background_pattern(gtk_widget_get_window(m_iconWindow), pattern); gdk_window_set_background_pattern(gtk_widget_get_window(m_iconWindow), pattern);
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_t* mask = icon->GetMask()->GetBitmap(); cairo_surface_t* mask = NULL;
if (icon->GetMask())
mask = *icon->GetMask();
if (mask) if (mask)
{ {
cairo_region_t* region = gdk_cairo_region_create_from_surface(mask); cairo_region_t* region = gdk_cairo_region_create_from_surface(mask);

View File

@ -188,15 +188,15 @@ private:
virtual bool DoSetShape(GdkWindow *window) virtual bool DoSetShape(GdkWindow *window)
{ {
if (m_mask.GetBitmap() == NULL) if (!m_mask)
return false; return false;
#ifdef __WXGTK3__ #ifdef __WXGTK3__
cairo_region_t* region = gdk_cairo_region_create_from_surface(m_mask.GetBitmap()); cairo_region_t* region = gdk_cairo_region_create_from_surface(m_mask);
gdk_window_shape_combine_region(window, region, 0, 0); gdk_window_shape_combine_region(window, region, 0, 0);
cairo_region_destroy(region); cairo_region_destroy(region);
#else #else
gdk_window_shape_combine_mask(window, m_mask.GetBitmap(), 0, 0); gdk_window_shape_combine_mask(window, m_mask, 0, 0);
#endif #endif
return true; return true;

View File

@ -1173,12 +1173,10 @@ wxMask *wxBitmap::GetMask() const
return GetBitmapData() ? GetBitmapData()->GetMask() : NULL; return GetBitmapData() ? GetBitmapData()->GetMask() : NULL;
} }
wxBitmap wxBitmap::GetMaskBitmap() const wxBitmap wxMask::GetBitmap() const
{ {
wxBitmap bmp; wxBitmap bmp;
wxMask *mask = GetMask(); bmp.SetHBITMAP(m_maskBitmap);
if ( mask )
bmp.SetHBITMAP(mask->GetMaskBitmap());
return bmp; return bmp;
} }

View File

@ -1649,6 +1649,28 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
return true; return true;
} }
wxBitmap wxMask::GetBitmap() const
{
wxBitmap bitmap(m_width, m_height, 1);
unsigned char* dst = static_cast<unsigned char*>(bitmap.BeginRawAccess());
const int dst_stride = bitmap.GetBitmapData()->GetBytesPerRow();
const unsigned char* src = static_cast<unsigned char*>(GetRawAccess());
for (int j = 0; j < m_height; j++, src += m_bytesPerRow, dst += dst_stride)
{
unsigned char* d = dst;
for (int i = 0; i < m_width; i++)
{
const unsigned char byte = src[i];
*d++ = 0xff;
*d++ = byte;
*d++ = byte;
*d++ = byte;
}
}
bitmap.EndRawAccess();
return bitmap;
}
WXHBITMAP wxMask::GetHBITMAP() const WXHBITMAP wxMask::GetHBITMAP() const
{ {
return m_maskBitmap ; return m_maskBitmap ;