1 /////////////////////////////////////////////////////////////////////////////
 
   3 // Purpose:     SWIG interface for wxBitmap and wxMask
 
   7 // Created:     7-July-1997
 
   9 // Copyright:   (c) 2003 by Total Control Software
 
  10 // Licence:     wxWindows license
 
  11 /////////////////////////////////////////////////////////////////////////////
 
  16 #include <wx/rawbmp.h>
 
  20 // Turn off the aquisition of the Global Interpreter Lock for the classes and
 
  21 // functions in this file
 
  24 //---------------------------------------------------------------------------
 
  29     static char** ConvertListOfStrings(PyObject* listOfStrings) {
 
  33         if (!PyList_Check(listOfStrings)) {
 
  34             PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
 
  37         count = PyList_Size(listOfStrings);
 
  38         cArray = new char*[count];
 
  40         for(int x=0; x<count; x++) {
 
  41             // TODO: Need some validation and error checking here
 
  42             cArray[x] = PyString_AsString(PyList_GET_ITEM(listOfStrings, x));
 
  49 //---------------------------------------------------------------------------
 
  51 // TODO:  When the API stabalizes and is available on other platforms, add
 
  52 // wrappers for the new wxBitmap, wxRawBitmap, wxDIB stuff...
 
  55 "The wx.Bitmap class encapsulates the concept of a platform-dependent
 
  56 bitmap.  It can be either monochrome or colour, and either loaded from
 
  57 a file or created dynamically.  A bitmap can be selected into a memory
 
  58 device context (instance of `wx.MemoryDC`). This enables the bitmap to
 
  59 be copied to a window or memory device context using `wx.DC.Blit`, or
 
  60 to be used as a drawing surface.", "
 
  62 The BMP and XMP image file formats are supported on all platforms by
 
  63 wx.Bitmap.  Other formats are automatically loaded by `wx.Image` and
 
  64 converted to a wx.Bitmap, so any image file format supported by
 
  65 `wx.Image` can be used.
 
  67 :todo: Add wrappers and support for raw bitmap data access.  Can this
 
  68        be be put into Python without losing the speed benefits of the
 
  69        teplates and iterators in rawbmp.h?
 
  71 :todo: Find a way to do very efficient PIL Image <--> wx.Bitmap
 
  74 :see: `wx.EmptyBitmap`, `wx.BitmapFromIcon`, `wx.BitmapFromImage`,
 
  75       `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, `wx.BitmapFromBuffer`,
 
  76       `wx.BitmapFromBufferRGBA`, `wx.Image`
 
  80 MustHaveApp(wxBitmap);
 
  82 class wxBitmap : public wxGDIObject
 
  86         wxBitmap(const wxString& name, wxBitmapType type=wxBITMAP_TYPE_ANY),
 
  87         "Loads a bitmap from a file.",
 
  89     :param name:  Name of the file to load the bitmap from.
 
  90     :param type: The type of image to expect.  Can be one of the following
 
  91         constants (assuming that the neccessary `wx.Image` handlers are
 
 103         * wx.BITMAP_TYPE_JPEG
 
 106         * wx.BITMAP_TYPE_PICT
 
 107         * wx.BITMAP_TYPE_ICON
 
 111 :see: Alternate constructors `wx.EmptyBitmap`, `wx.BitmapFromIcon`,
 
 112       `wx.BitmapFromImage`, `wx.BitmapFromXPMData`, `wx.BitmapFromBits`,
 
 113       `wx.BitmapFromBuffer`, `wx.BitmapFromBufferRGBA`,
 
 119         wxBitmap(int width, int height, int depth=-1),
 
 120         "Creates a new bitmap of the given size.  A depth of -1 indicates the
 
 121 depth of the current screen or visual. Some platforms only support 1
 
 122 for monochrome and -1 for the current display depth.", "",
 
 126         wxBitmap(const wxIcon& icon),
 
 127         "Create a new bitmap from a `wx.Icon` object.", "",
 
 131         wxBitmap(const wxImage& image, int depth=-1),
 
 132         "Creates bitmap object from a `wx.Image`. This has to be done to
 
 133 actually display a `wx.Image` as you cannot draw an image directly on
 
 134 a window. The resulting bitmap will use the provided colour depth (or
 
 135 that of the current screen colour depth if depth is -1) which entails
 
 136 that a colour reduction may have to take place.", "",
 
 143             "Construct a Bitmap from a list of strings formatted as XPM data.", "",
 
 144             wxBitmap(PyObject* listOfStrings))
 
 146                 char**    cArray = NULL;
 
 149                 cArray = ConvertListOfStrings(listOfStrings);
 
 152                 bmp = new wxBitmap(cArray);
 
 160             "Creates a bitmap from an array of bits.  You should only use this
 
 161 function for monochrome bitmaps (depth 1) in portable programs: in
 
 162 this case the bits parameter should contain an XBM image.  For other
 
 163 bit depths, the behaviour is platform dependent.", "",
 
 164             wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
 
 168                 PyString_AsStringAndSize(bits, &buf, &length);
 
 169                 return new wxBitmap(buf, width, height, depth);
 
 174     // wxGDIImage methods
 
 178         void SetHandle(long handle) { self->SetHandle((WXHANDLE)handle); }
 
 183     %pythoncode { Ok = IsOk }
 
 187         "Gets the width of the bitmap in pixels.", "");
 
 192         "Gets the height of the bitmap in pixels.", "");
 
 197         "Gets the colour depth of the bitmap. A value of 1 indicates a
 
 198 monochrome bitmap.", "");
 
 203         DocStr(GetSize, "Get the size of the bitmap.", "");
 
 205             wxSize size(self->GetWidth(), self->GetHeight());
 
 212         virtual wxImage , ConvertToImage() const,
 
 213         "Creates a platform-independent image from a platform-dependent
 
 214 bitmap. This preserves mask information so that bitmaps and images can
 
 215 be converted back and forth without loss in that respect.", "");
 
 219         virtual wxMask* , GetMask() const,
 
 220         "Gets the associated mask (if any) which may have been loaded from a
 
 221 file or explpicitly set for the bitmap.
 
 223 :see: `SetMask`, `wx.Mask`
 
 226     // MSW only?    wxBitmap GetMaskBitmap() const;
 
 230         virtual void , SetMask(wxMask* mask),
 
 231         "Sets the mask for this bitmap.
 
 233 :see: `GetMask`, `wx.Mask`
 
 235     %cleardisown(wxMask*);
 
 238         DocStr(SetMaskColour,
 
 239                "Create a Mask based on a specified colour in the Bitmap.", "");
 
 240         void SetMaskColour(const wxColour& colour) {
 
 241             wxMask *mask = new wxMask(*self, colour);
 
 248         virtual wxBitmap , GetSubBitmap(const wxRect& rect) const,
 
 249         "Returns a sub-bitmap of the current one as long as the rect belongs
 
 250 entirely to the bitmap. This function preserves bit depth and mask
 
 255         virtual bool , SaveFile(const wxString &name, wxBitmapType type,
 
 256                                 wxPalette *palette = NULL),
 
 257         "Saves a bitmap in the named file.  See `__init__` for a description of
 
 258 the ``type`` parameter.", "");
 
 262         virtual bool , LoadFile(const wxString &name, wxBitmapType type),
 
 263         "Loads a bitmap from a file.  See `__init__` for a description of the
 
 264 ``type`` parameter.", "");
 
 268     virtual wxPalette *GetPalette() const;
 
 270     virtual void SetPalette(const wxPalette& palette);
 
 274     virtual bool CopyFromIcon(const wxIcon& icon);
 
 277         virtual void , SetHeight(int height),
 
 278         "Set the height property (does not affect the existing bitmap data).", "");
 
 282         virtual void , SetWidth(int width),
 
 283         "Set the width property (does not affect the existing bitmap data).", "");
 
 287         virtual void , SetDepth(int depth),
 
 288         "Set the depth property (does not affect the existing bitmap data).", "");
 
 292         DocStr(SetSize, "Set the bitmap size (does not affect the existing bitmap data).", "");
 
 293         void SetSize(const wxSize& size) {
 
 294             self->SetWidth(size.x);
 
 295             self->SetHeight(size.y);
 
 300     bool CopyFromCursor(const wxCursor& cursor);
 
 302 // WXWIN_COMPATIBILITY_2_4
 
 305     void SetQuality(int q);
 
 306     %pythoncode { GetQuality = wx._deprecated(GetQuality) }
 
 307     %pythoncode { SetQuality = wx._deprecated(SetQuality) }
 
 311     %pythoncode { def __nonzero__(self): return self.IsOk() }
 
 314         bool __eq__(const wxBitmap* other) { return other ? (*self == *other) : false; }
 
 315         bool __ne__(const wxBitmap* other) { return other ? (*self != *other) : true;  }
 
 318     %property(Depth, GetDepth, SetDepth, doc="See `GetDepth` and `SetDepth`");
 
 319     %property(Height, GetHeight, SetHeight, doc="See `GetHeight` and `SetHeight`");
 
 320     %property(Mask, GetMask, SetMask, doc="See `GetMask` and `SetMask`");
 
 321     %property(Palette, GetPalette, doc="See `GetPalette`");
 
 322     %property(Size, GetSize, SetSize, doc="See `GetSize` and `SetSize`");
 
 323     %property(SubBitmap, GetSubBitmap, doc="See `GetSubBitmap`");
 
 324     %property(Width, GetWidth, SetWidth, doc="See `GetWidth` and `SetWidth`");
 
 329 //---------------------------------------------------------------------------
 
 330 // Factory functions for creating wxBitmaps from Python buffer objects.  They
 
 331 // use the Abstract Pixel API to be able to set RGB and A bytes directly into
 
 332 // the wxBitmap's pixel buffer.
 
 335 // See http://tinyurl.com/e5adr for what premultiplying alpha means.  It
 
 336 // appears to me that the other platforms are already doing it, so I'll just
 
 337 // automatically do it for wxMSW here.
 
 339 #define wxPy_premultiply(p, a)   ((p) * (a) / 0xff)
 
 340 #define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p))    
 
 342 #define wxPy_premultiply(p, a)   (p)
 
 343 #define wxPy_unpremultiply(p, a) (p)    
 
 348 %newobject _BitmapFromBufferAlpha;
 
 349 %newobject _BitmapFromBuffer;
 
 351     wxBitmap* _BitmapFromBufferAlpha(int width, int height,
 
 352                                     buffer data, int DATASIZE,
 
 353                                     buffer alpha, int ALPHASIZE)
 
 355         if (DATASIZE != width*height*3) {
 
 356             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 360         if (ALPHASIZE != width*height) {
 
 361             wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 365         wxBitmap* bmp = new wxBitmap(width, height, 32);
 
 366         wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 368             // raise an exception...
 
 369             wxPyErr_SetString(PyExc_RuntimeError,
 
 370                               "Failed to gain raw access to bitmap data.");
 
 375         wxAlphaPixelData::Iterator p(pixData);
 
 376         for (int y=0; y<height; y++) {
 
 377             wxAlphaPixelData::Iterator rowStart = p;
 
 378             for (int x=0; x<width; x++) {
 
 380                 p.Red()   = wxPy_premultiply(*(data++), a);
 
 381                 p.Green() = wxPy_premultiply(*(data++), a);
 
 382                 p.Blue()  = wxPy_premultiply(*(data++), a);
 
 387             p.OffsetY(pixData, 1);
 
 392     wxBitmap* _BitmapFromBuffer(int width, int height, buffer data, int DATASIZE)
 
 394         if (DATASIZE != width*height*3) {
 
 395             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 399         wxBitmap* bmp = new wxBitmap(width, height, 24);
 
 400         wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 402             // raise an exception...
 
 403             wxPyErr_SetString(PyExc_RuntimeError,
 
 404                               "Failed to gain raw access to bitmap data.");
 
 408         wxNativePixelData::Iterator p(pixData);
 
 409         for (int y=0; y<height; y++) {
 
 410             wxNativePixelData::Iterator rowStart = p;
 
 411             for (int x=0; x<width; x++) {
 
 413                 p.Green() = *(data++);
 
 414                 p.Blue()  = *(data++);
 
 418             p.OffsetY(pixData, 1);
 
 426 def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
 
 428     Creates a `wx.Bitmap` from the data in dataBuffer.  The dataBuffer
 
 429     parameter must be a Python object that implements the buffer
 
 430     interface, such as a string, array, etc.  The dataBuffer object is
 
 431     expected to contain a series of RGB bytes and be width*height*3
 
 432     bytes long.  A buffer object can optionally be supplied for the
 
 433     image's alpha channel data, and it is expected to be width*height
 
 434     bytes long.  On Windows the RGB values are 'premultiplied' by the
 
 435     alpha values.  (The other platforms do the multiplication
 
 438     Unlike `wx.ImageFromBuffer` the bitmap created with this function
 
 439     does not share the memory buffer with the buffer object.  This is
 
 440     because the native pixel buffer format varies on different
 
 441     platforms, and so instead an efficient as possible copy of the
 
 442     data is made from the buffer objects to the bitmap's native pixel
 
 443     buffer.  For direct access to a bitmap's pixel buffer see
 
 444     `wx.NativePixelData` and `wx.AlphaPixelData`.
 
 446     :see: `wx.Bitmap`, `wx.BitmapFromBufferRGBA`, `wx.NativePixelData`,
 
 447           `wx.AlphaPixelData`, `wx.ImageFromBuffer`
 
 449     if alphaBuffer is not None:
 
 450         return _gdi_._BitmapFromBufferAlpha(width, height, dataBuffer, alphaBuffer)
 
 452         return _gdi_._BitmapFromBuffer(width, height, dataBuffer)
 
 457 %newobject _BitmapFromBufferRGBA;
 
 459     wxBitmap* _BitmapFromBufferRGBA(int width, int height, buffer data, int DATASIZE)
 
 461         if (DATASIZE != width*height*4) {
 
 462             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 466         wxBitmap* bmp = new wxBitmap(width, height, 32);
 
 467         wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 469             // raise an exception...
 
 470             wxPyErr_SetString(PyExc_RuntimeError,
 
 471                               "Failed to gain raw access to bitmap data.");
 
 476         wxAlphaPixelData::Iterator p(pixData);
 
 477         for (int y=0; y<height; y++) {
 
 478             wxAlphaPixelData::Iterator rowStart = p;
 
 479             for (int x=0; x<width; x++) {
 
 481                 p.Red()   = wxPy_premultiply(*(data++), a);
 
 482                 p.Green() = wxPy_premultiply(*(data++), a);
 
 483                 p.Blue()  = wxPy_premultiply(*(data++), a);
 
 484                 p.Alpha() = a; data++;
 
 488             p.OffsetY(pixData, 1);
 
 495 def BitmapFromBufferRGBA(width, height, dataBuffer):
 
 497     Creates a `wx.Bitmap` from the data in dataBuffer.  The dataBuffer
 
 498     parameter must be a Python object that implements the buffer
 
 499     interface, such as a string, array, etc.  The dataBuffer object is
 
 500     expected to contain a series of RGBA bytes (red, green, blue and
 
 501     alpha) and be width*height*4 bytes long.  On Windows the RGB
 
 502     values are 'premultiplied' by the alpha values.  (The other
 
 503     platforms do the multiplication themselves.)
 
 505     Unlike `wx.ImageFromBuffer` the bitmap created with this function
 
 506     does not share the memory buffer with the buffer object.  This is
 
 507     because the native pixel buffer format varies on different
 
 508     platforms, and so instead an efficient as possible copy of the
 
 509     data is made from the buffer object to the bitmap's native pixel
 
 510     buffer.  For direct access to a bitmap's pixel buffer see
 
 511     `wx.NativePixelData` and `wx.AlphaPixelData`.
 
 513     :see: `wx.Bitmap`, `wx.BitmapFromBuffer`, `wx.NativePixelData`,
 
 514           `wx.AlphaPixelData`, `wx.ImageFromBuffer`
 
 516     return _gdi_._BitmapFromBufferRGBA(width, height, dataBuffer)
 
 520 //---------------------------------------------------------------------------
 
 522 class wxPixelDataBase
 
 525     // origin of the rectangular region we represent
 
 526     wxPoint GetOrigin() const { return m_ptOrigin; }
 
 528     // width and height of the region we represent
 
 529     int GetWidth() const { return m_width; }
 
 530     int GetHeight() const { return m_height; }
 
 532     wxSize GetSize() const { return wxSize(m_width, m_height); }
 
 534     // the distance between two rows
 
 535     int GetRowStride() const { return m_stride; }
 
 537     %property(Height, GetHeight, doc="See `GetHeight`");
 
 538     %property(Origin, GetOrigin, doc="See `GetOrigin`");
 
 539     %property(RowStride, GetRowStride, doc="See `GetRowStride`");
 
 540     %property(Size, GetSize, doc="See `GetSize`");
 
 541     %property(Width, GetWidth, doc="See `GetWidth`");
 
 545 // Both wxNativePixelData and wxAlphaPixelData have the same interface, so
 
 546 // make a macro to declare them both.
 
 548 %define PIXELDATA(PixelData)
 
 550     typedef PixelData##::Iterator PixelData##_Accessor;
 
 552 class PixelData##_Accessor;
 
 553 class PixelData : public wxPixelDataBase
 
 558     PixelData(wxBitmap& bmp);
 
 559     PixelData(wxBitmap& bmp, const wxRect& rect);
 
 560     PixelData(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz);
 
 564     PixelData##_Accessor GetPixels() const;
 
 568         bool __nonzero__() { return self->operator bool(); }
 
 574         Create and return an iterator object for this pixel data
 
 575         object.  (It's really a generator but I won't tell if you
 
 578         width  = self.GetWidth()
 
 579         height = self.GetHeight()
 
 580         pixels = self.GetPixels()
 
 582         # This class is a facade over the pixels object (using the one
 
 583         # in the enclosing scope) that only allows Get() and Set() to
 
 585         class PixelFacade(object):
 
 588             def Set(self, *args, **kw):
 
 589                 return pixels.Set(*args, **kw)
 
 591                 return str(self.Get())
 
 593                 return 'pixel(%d,%d): %s' % (x,y,self.Get())
 
 594             X = property(lambda self: x)
 
 595             Y = property(lambda self: y)
 
 598         for y in xrange(height):
 
 599             for x in xrange(width):
 
 600                 # We always generate the same pf instance, but it
 
 601                 # accesses the pixels object which we use to iterate
 
 602                 # over the pixel buffer.
 
 605             pixels.MoveTo(self, 0, y)
 
 608     %property(Pixels, GetPixels, doc="See `GetPixels`");
 
 613 class PixelData##_Accessor
 
 616     %nokwargs PixelData##_Accessor;
 
 618     PixelData##_Accessor(PixelData& data);
 
 619     PixelData##_Accessor(wxBitmap& bmp, PixelData& data);
 
 620     PixelData##_Accessor();
 
 622     ~PixelData##_Accessor();
 
 624     void Reset(const PixelData& data);
 
 628         // PixelData##_Accessor& nextPixel() { return ++(*self); }
 
 629         void nextPixel() { ++(*self); }
 
 632     void Offset(const PixelData& data, int x, int y);
 
 633     void OffsetX(const PixelData& data, int x);
 
 634     void OffsetY(const PixelData& data, int y);
 
 635     void MoveTo(const PixelData& data, int x, int y);
 
 637 // NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha
 
 638 // functions because I can't hide the premultiplying needed on wxMSW
 
 639 // if only the individual components are wrapped, plus it would mean 3
 
 640 // or 4 trips per pixel from Python to C++ instead of just one.
 
 641 // Instead I've added the Set and Get functions and put the
 
 642 // premultiplying in there.
 
 645 //         byte _get_Red()   { return self->Red(); }
 
 646 //         byte _get_Green() { return self->Green(); }
 
 647 //         byte _get_Blue()  { return self->Blue(); }
 
 649 //         void _set_Red(byte val)   { self->Red() = val; }
 
 650 //         void _set_Green(byte val) { self->Green() = val; }
 
 651 //         void _set_Blue(byte val)  { self->Blue() = val; }
 
 655 //         Red   = property(_get_Red,   _set_Red)
 
 656 //         Green = property(_get_Green, _set_Green)
 
 657 //         Blue  = property(_get_Blue,  _set_Blue)
 
 663 %pythonAppend wxAlphaPixelData::wxAlphaPixelData "self.UseAlpha()"
 
 666 PIXELDATA(wxNativePixelData)
 
 667 PIXELDATA(wxAlphaPixelData)    
 
 670 // Add in a few things that are different between the wxNativePixelData and
 
 671 // wxAlphaPixelData and the iterator classes and so are not included in our
 
 674 %extend wxNativePixelData_Accessor {
 
 675     void Set(byte red, byte green, byte blue) {
 
 677         self->Green() = green;
 
 682         PyObject* rv = PyTuple_New(3);
 
 683         PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red()));
 
 684         PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green()));
 
 685         PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue()));
 
 690 %extend wxAlphaPixelData_Accessor {
 
 691 //     byte _get_Alpha()         { return self->Alpha(); }
 
 692 //     void _set_Alpha(byte val) { self->Alpha() = val; }
 
 695 //         Alpha = property(_get_Alpha, _set_Alpha)
 
 698     void Set(byte red, byte green, byte blue, byte alpha) {
 
 699         self->Red()   = wxPy_premultiply(red,   alpha);
 
 700         self->Green() = wxPy_premultiply(green, alpha);
 
 701         self->Blue()  = wxPy_premultiply(blue,  alpha);
 
 702         self->Alpha() = alpha;
 
 706         PyObject* rv = PyTuple_New(4);
 
 707         int red   = self->Red();
 
 708         int green = self->Green();
 
 709         int blue  = self->Blue();
 
 710         int alpha = self->Alpha();
 
 712         PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red,   alpha) ));
 
 713         PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
 
 714         PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue,  alpha) ));
 
 715         PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha ));
 
 721 //---------------------------------------------------------------------------
 
 724 "This class encapsulates a monochrome mask bitmap, where the masked
 
 725 area is black and the unmasked area is white. When associated with a
 
 726 bitmap and drawn in a device context, the unmasked area of the bitmap
 
 727 will be drawn, and the masked area will not be drawn.
 
 729 A mask may be associated with a `wx.Bitmap`. It is used in
 
 730 `wx.DC.DrawBitmap` or `wx.DC.Blit` when the source device context is a
 
 731 `wx.MemoryDC` with a `wx.Bitmap` selected into it that contains a
 
 736 class wxMask : public wxObject {
 
 740            "Constructs a mask from a `wx.Bitmap` and a `wx.Colour` in that bitmap
 
 741 that indicates the transparent portions of the mask.  In other words,
 
 742 the pixels in ``bitmap`` that match ``colour`` will be the transparent
 
 743 portions of the mask.  If no ``colour`` or an invalid ``colour`` is
 
 744 passed then BLACK is used.
 
 746 :see: `wx.Bitmap`, `wx.Colour`", "");
 
 749         wxMask(const wxBitmap& bitmap, const wxColour& colour = wxNullColour) {
 
 750             if ( !colour.IsOk() )
 
 751                 return new wxMask(bitmap, *wxBLACK);
 
 753                 return new wxMask(bitmap, colour);
 
 760 %pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") }
 
 762 //---------------------------------------------------------------------------
 
 763 //---------------------------------------------------------------------------
 
 765 // Turn GIL acquisition back on.