From 5ca21fe7bfda18e2da4e17eb529c4dfa0c824db2 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sun, 20 Jan 2013 06:28:11 +0000 Subject: [PATCH] add wxMask::GetBitmap(), closes #9381 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73409 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/gtk/bitmap.h | 8 +++-- include/wx/msw/bitmap.h | 3 +- include/wx/osx/bitmap.h | 2 ++ interface/wx/bitmap.h | 8 +++++ src/generic/graphicc.cpp | 2 +- src/gtk/bitmap.cpp | 70 +++++++++++++++++++++++----------------- src/gtk/dc.cpp | 2 +- src/gtk/dcclient.cpp | 6 ++-- src/gtk/dnd.cpp | 6 ++-- src/gtk/nonownedwnd.cpp | 6 ++-- src/msw/bitmap.cpp | 6 ++-- src/osx/core/bitmap.cpp | 22 +++++++++++++ 13 files changed, 95 insertions(+), 47 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 08b630feda..d202fc9ace 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -606,6 +606,7 @@ All (GUI): - Add wxListCtrl::EnableAlternateRowColours() (troelsk). - Fix wrong tab order in wxAuiNotebook after dragging (Mark Barber). - Fix bug in generic wxDataViewCtrl column dragging (jobuz). +- Add wxMask::GetBitmap() for wxMSW, wxGTK and wxOSX wxGTK: diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index d176833ca8..afd8247eb4 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -32,14 +32,15 @@ public: #endif // wxUSE_PALETTE wxMask( const wxBitmap& bitmap ); virtual ~wxMask(); + wxBitmap GetBitmap() const; // implementation #ifdef __WXGTK3__ wxMask(cairo_surface_t*); - cairo_surface_t* GetBitmap() const; + operator cairo_surface_t*() const; #else wxMask(GdkPixmap*); - GdkPixmap* GetBitmap() const; + operator GdkPixmap*() const; #endif protected: @@ -80,7 +81,7 @@ public: #if wxUSE_IMAGE wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH); #endif // wxUSE_IMAGE - wxBitmap(GdkPixbuf* pixbuf); + wxBitmap(GdkPixbuf* pixbuf, int depth = 0); virtual ~wxBitmap(); bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH); @@ -132,6 +133,7 @@ public: GdkPixmap *GetPixmap() const; bool HasPixmap() const; bool HasPixbuf() const; + wxBitmap(GdkPixmap* pixmap); #endif GdkPixbuf *GetPixbuf() const; diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index ef2a73fb27..6af2d21627 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -160,7 +160,6 @@ public: #endif // wxUSE_PALETTE wxMask *GetMask() const; - wxBitmap GetMaskBitmap() const; void SetMask(wxMask *mask); // 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); + wxBitmap GetBitmap() const; + // Implementation WXHBITMAP GetMaskBitmap() const { return m_maskBitmap; } void SetMaskBitmap(WXHBITMAP bmp) { m_maskBitmap = bmp; } diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index c799d9db5d..904a4b0314 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -57,6 +57,8 @@ public: bool Create(const wxBitmap& bitmap); bool Create(const wxMemoryBuffer& buf, int width , int height , int bytesPerRow ) ; + wxBitmap GetBitmap() const; + // Implementation below void Init() ; diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index 9f6c3ffe41..5b6e278644 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -769,5 +769,13 @@ public: Constructs a mask from a bitmap and a colour that indicates the background. */ 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; }; diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index dfc35238f3..5e7da3dcba 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -1404,7 +1404,7 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm // fully transparent or fully opaque if (bmpSource.GetMask()) { - wxBitmap bmpMask = bmpSource.GetMaskBitmap(); + wxBitmap bmpMask = bmpSource.GetMask()->GetBitmap(); bufferFormat = CAIRO_FORMAT_ARGB32; data = (wxUint32*)m_buffer; wxNativePixelData diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp index a551b04a28..5bbc25c7ad 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -274,9 +274,9 @@ bool wxMask::InitFromMonoBitmap(const wxBitmap& bitmap) } #ifdef __WXGTK3__ -cairo_surface_t* wxMask::GetBitmap() const +wxMask::operator cairo_surface_t*() const #else -GdkPixmap* wxMask::GetBitmap() const +wxMask::operator GdkPixmap*() const #endif { return m_bitmap; @@ -442,13 +442,15 @@ wxBitmap::wxBitmap(const char* const* bits) #endif } -wxBitmap::wxBitmap(GdkPixbuf* pixbuf) +wxBitmap::wxBitmap(GdkPixbuf* pixbuf, int depth) { if (pixbuf) { + if (depth != 1) + depth = gdk_pixbuf_get_n_channels(pixbuf) * 8; wxBitmapRefData* bmpData = new wxBitmapRefData( gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), - gdk_pixbuf_get_n_channels(pixbuf) * 8); + depth); m_refData = bmpData; #ifdef __WXGTK3__ 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() { } @@ -730,7 +747,7 @@ wxImage wxBitmap::ConvertToImage() const } cairo_surface_t* maskSurf = NULL; if (bmpData->m_mask) - maskSurf = bmpData->m_mask->GetBitmap(); + maskSurf = *bmpData->m_mask; if (maskSurf) { const guchar r = 1; @@ -826,7 +843,7 @@ wxImage wxBitmap::ConvertToImage() const const int MASK_BLUE_REPLACEMENT = 2; 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++) { @@ -892,16 +909,13 @@ void wxBitmap::SetMask( wxMask *mask ) M_BMPDATA->m_mask = mask; } -wxBitmap wxBitmap::GetMaskBitmap() const +wxBitmap wxMask::GetBitmap() const { wxBitmap bitmap; - wxBitmapRefData* bmpData = M_BMPDATA; -#ifdef __WXGTK3__ - cairo_surface_t* mask = NULL; - if (bmpData && bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); - if (mask) + if (m_bitmap) { +#ifdef __WXGTK3__ + cairo_surface_t* mask = m_bitmap; const int w = cairo_image_surface_get_width(mask); const int h = cairo_image_surface_get_height(mask); GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, w, h); @@ -919,21 +933,19 @@ wxBitmap wxBitmap::GetMaskBitmap() const d[2] = src[i]; } } - bitmap = wxBitmap(pixbuf); - } + bitmap = wxBitmap(pixbuf, 1); #else - GdkPixmap* mask = NULL; - if (bmpData && bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); - if (mask) - { + GdkPixmap* mask = m_bitmap; int w, h; gdk_drawable_get_size(mask, &w, &h); - GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable( - NULL, mask, NULL, 0, 0, 0, 0, w, h); - bitmap = wxBitmap(pixbuf); - } + GdkPixmap* pixmap = gdk_pixmap_new(mask, w, h, -1); + GdkGC* gc = gdk_gc_new(pixmap); + 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 + } return bitmap; } @@ -994,7 +1006,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const cairo_surface_t* maskSurf = NULL; if (bmpData->m_mask) - maskSurf = bmpData->m_mask->GetBitmap(); + maskSurf = *bmpData->m_mask; if (maskSurf) { newRef->m_mask = new wxMask(GetSubSurface(maskSurf, rect)); @@ -1017,7 +1029,7 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const } GdkPixmap* mask = NULL; if (bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); + mask = *bmpData->m_mask; if (mask) { 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_surface_t* mask = NULL; if (useMask && bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); + mask = *bmpData->m_mask; if (mask) cairo_mask_surface(cr, mask, x, y); else @@ -1310,7 +1322,7 @@ GdkPixbuf *wxBitmap::GetPixbuf() const GetPixbufNoMask(); cairo_surface_t* mask = NULL; if (bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); + mask = *bmpData->m_mask; if (mask == NULL) return bmpData->m_pixbufNoMask; @@ -1342,7 +1354,7 @@ GdkPixbuf *wxBitmap::GetPixbuf() const const int h = bmpData->m_height; GdkPixmap* mask = NULL; if (bmpData->m_mask) - mask = bmpData->m_mask->GetBitmap(); + mask = *bmpData->m_mask; const bool useAlpha = bmpData->m_alphaRequested || mask; bmpData->m_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, useAlpha, 8, w, h); if (bmpData->m_pixmap) diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index 791961499c..52abd3b2be 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -154,7 +154,7 @@ bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dst { wxMask* mask = bitmap.GetMask(); if (mask) - maskSurf = mask->GetBitmap(); + maskSurf = *mask; } } if (maskSurf) diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 03d4585115..dab19cc198 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -1130,7 +1130,7 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap, { wxMask* m = bitmap.GetMask(); if (m) - mask = m->GetBitmap(); + mask = *m; } if (mask) { @@ -1228,7 +1228,7 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, { wxMask* m = bitmap.GetMask(); if (m) - mask = m->GetBitmap(); + mask = *m; } } else @@ -1796,7 +1796,7 @@ void wxWindowDCImpl::SetBrush( const wxBrush &brush ) if ((m_brush.GetStyle() == wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask())) { 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()) diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp index acb68d6af2..4679fd0bbd 100644 --- a/src/gtk/dnd.cpp +++ b/src/gtk/dnd.cpp @@ -764,7 +764,7 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context ) #ifndef __WXGTK3__ GdkBitmap *mask; if ( icon->GetMask() ) - mask = icon->GetMask()->GetBitmap(); + mask = *icon->GetMask(); else mask = NULL; @@ -796,7 +796,9 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context ) cairo_pattern_t* pattern = cairo_get_source(cr); gdk_window_set_background_pattern(gtk_widget_get_window(m_iconWindow), pattern); cairo_destroy(cr); - cairo_surface_t* mask = icon->GetMask()->GetBitmap(); + cairo_surface_t* mask = NULL; + if (icon->GetMask()) + mask = *icon->GetMask(); if (mask) { cairo_region_t* region = gdk_cairo_region_create_from_surface(mask); diff --git a/src/gtk/nonownedwnd.cpp b/src/gtk/nonownedwnd.cpp index 0e6226877d..e558b52984 100644 --- a/src/gtk/nonownedwnd.cpp +++ b/src/gtk/nonownedwnd.cpp @@ -188,15 +188,15 @@ private: virtual bool DoSetShape(GdkWindow *window) { - if (m_mask.GetBitmap() == NULL) + if (!m_mask) return false; #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); cairo_region_destroy(region); #else - gdk_window_shape_combine_mask(window, m_mask.GetBitmap(), 0, 0); + gdk_window_shape_combine_mask(window, m_mask, 0, 0); #endif return true; diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index b910da5380..05d24b6d82 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -1173,12 +1173,10 @@ wxMask *wxBitmap::GetMask() const return GetBitmapData() ? GetBitmapData()->GetMask() : NULL; } -wxBitmap wxBitmap::GetMaskBitmap() const +wxBitmap wxMask::GetBitmap() const { wxBitmap bmp; - wxMask *mask = GetMask(); - if ( mask ) - bmp.SetHBITMAP(mask->GetMaskBitmap()); + bmp.SetHBITMAP(m_maskBitmap); return bmp; } diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index 0003cb5a47..1161256016 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -1649,6 +1649,28 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) return true; } +wxBitmap wxMask::GetBitmap() const +{ + wxBitmap bitmap(m_width, m_height, 1); + unsigned char* dst = static_cast(bitmap.BeginRawAccess()); + const int dst_stride = bitmap.GetBitmapData()->GetBytesPerRow(); + const unsigned char* src = static_cast(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 { return m_maskBitmap ; -- 2.47.2