]> git.saurik.com Git - wxWidgets.git/commitdiff
add wxMask::GetBitmap(), closes #9381
authorPaul Cornett <paulcor@bullseye.com>
Sun, 20 Jan 2013 06:28:11 +0000 (06:28 +0000)
committerPaul Cornett <paulcor@bullseye.com>
Sun, 20 Jan 2013 06:28:11 +0000 (06:28 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73409 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
docs/changes.txt
include/wx/gtk/bitmap.h
include/wx/msw/bitmap.h
include/wx/osx/bitmap.h
interface/wx/bitmap.h
src/generic/graphicc.cpp
src/gtk/bitmap.cpp
src/gtk/dc.cpp
src/gtk/dcclient.cpp
src/gtk/dnd.cpp
src/gtk/nonownedwnd.cpp
src/msw/bitmap.cpp
src/osx/core/bitmap.cpp

index 08b630feda5fc8aee21989c7b869a23d6fde1011..d202fc9ace0fc760fd3319f5698fe8ee3a02fe12 100644 (file)
@@ -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:
 
index d176833ca8737f190bbdde797d1b188bbe52cf1e..afd8247eb444bd6249a135a4f35e0fae94530d20 100644 (file)
@@ -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;
 
index ef2a73fb2798c888e7b10cfe911eaa530e7b992e..6af2d21627f8eab77e11b223459bd2b8b29da65d 100644 (file)
@@ -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; }
index c799d9db5d3b1f4af004c5ff57b13932134fda69..904a4b0314b8f549daf537df6bd0a798c00e4017 100644 (file)
@@ -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() ;
index 9f6c3ffe41c44c3eb15650b17e2716f9f573b670..5b6e27864422ff7e67a94e6285d40f7d2664fabb 100644 (file)
@@ -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;
 };
 
index dfc35238f398bd7e127f8dc8f7e06b78c6d5ee75..5e7da3dcba2654ae70349dea4a19e51820e43c1d 100644 (file)
@@ -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
index a551b04a284d5572e4883bb6026a99e4c39d97d3..5bbc25c7ad04d1ed2291930b8ec56135019f7a7a 100644 (file)
@@ -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)
index 791961499cb692d5dea1710dce660cf40b1bb84e..52abd3b2bea78827c2aa6709ed3ddb3d9c9d1ff0 100644 (file)
@@ -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)
index 03d45851154386954428e7ccfd8b4a0f1915bfc0..dab19cc1986b125e317fa32b8fc0a210928d92f9 100644 (file)
@@ -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())
index acb68d6af29be701de0c8b03a93daebf993c5964..4679fd0bbd055932c9a1755695e5b796ab633b4b 100644 (file)
@@ -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);
index 0e6226877def5430371fbe156ac4b7c8f7fb2ffb..e558b5298404167deae92ea9476bc5d6f155b808 100644 (file)
@@ -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;
index b910da5380b68a6d6a382de9b2f086baa163afc8..05d24b6d82a14afe822c7baa8f9e1d3e16ea309e 100644 (file)
@@ -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;
 }
 
index 0003cb5a475c3c0d12db218598604a97ecf3db5e..1161256016c7fb4698c8f448c51a1c53984d12aa 100644 (file)
@@ -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<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
 {
     return m_maskBitmap ;