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 //---------------------------------------------------------------------------
 
  27 // See http://tinyurl.com/e5adr for what premultiplying alpha means.  It
 
  28 // appears to me that the other platforms are already doing it, so I'll just
 
  29 // automatically do it for wxMSW here.
 
  31 #define wxPy_premultiply(p, a)   ((p) * (a) / 0xff)
 
  32 #define wxPy_unpremultiply(p, a) ((a) ? ((p) * 0xff / (a)) : (p))    
 
  34 #define wxPy_premultiply(p, a)   (p)
 
  35 #define wxPy_unpremultiply(p, a) (p)    
 
  39 //---------------------------------------------------------------------------
 
  45     static char** ConvertListOfStrings(PyObject* listOfStrings) {
 
  49         if (!PyList_Check(listOfStrings)) {
 
  50             PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
 
  53         count = PyList_Size(listOfStrings);
 
  54         cArray = new char*[count];
 
  56         for(int x=0; x<count; x++) {
 
  57             // TODO: Need some validation and error checking here
 
  58             cArray[x] = PyString_AsString(PyList_GET_ITEM(listOfStrings, x));
 
  65 //---------------------------------------------------------------------------
 
  67 // TODO:  When the API stabalizes and is available on other platforms, add
 
  68 // wrappers for the new wxBitmap, wxRawBitmap, wxDIB stuff...
 
  71 "The wx.Bitmap class encapsulates the concept of a platform-dependent
 
  72 bitmap.  It can be either monochrome or colour, and either loaded from
 
  73 a file or created dynamically.  A bitmap can be selected into a memory
 
  74 device context (instance of `wx.MemoryDC`). This enables the bitmap to
 
  75 be copied to a window or memory device context using `wx.DC.Blit`, or
 
  76 to be used as a drawing surface.", "
 
  78 The BMP and XMP image file formats are supported on all platforms by
 
  79 wx.Bitmap.  Other formats are automatically loaded by `wx.Image` and
 
  80 converted to a wx.Bitmap, so any image file format supported by
 
  81 `wx.Image` can be used.
 
  83 :todo: Add wrappers and support for raw bitmap data access.  Can this
 
  84        be be put into Python without losing the speed benefits of the
 
  85        teplates and iterators in rawbmp.h?
 
  87 :todo: Find a way to do very efficient PIL Image <--> wx.Bitmap
 
  90 :see: `wx.EmptyBitmap`, `wx.BitmapFromIcon`, `wx.BitmapFromImage`,
 
  91       `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, `wx.BitmapFromBuffer`,
 
  92       `wx.BitmapFromBufferRGBA`, `wx.Image`
 
  96 MustHaveApp(wxBitmap);
 
  98 class wxBitmap : public wxGDIObject
 
 102         wxBitmap(const wxString& name, wxBitmapType type=wxBITMAP_TYPE_ANY),
 
 103         "Loads a bitmap from a file.",
 
 105     :param name:  Name of the file to load the bitmap from.
 
 106     :param type: The type of image to expect.  Can be one of the following
 
 107         constants (assuming that the neccessary `wx.Image` handlers are
 
 119         * wx.BITMAP_TYPE_JPEG
 
 122         * wx.BITMAP_TYPE_PICT
 
 123         * wx.BITMAP_TYPE_ICON
 
 127 :see: Alternate constructors `wx.EmptyBitmap`, `wx.BitmapFromIcon`,
 
 128       `wx.BitmapFromImage`, `wx.BitmapFromXPMData`, `wx.BitmapFromBits`,
 
 129       `wx.BitmapFromBuffer`, `wx.BitmapFromBufferRGBA`,
 
 135         wxBitmap(int width, int height, int depth=-1),
 
 136         "Creates a new bitmap of the given size.  A depth of -1 indicates the
 
 137 depth of the current screen or visual. Some platforms only support 1
 
 138 for monochrome and -1 for the current display depth.", "",
 
 142         wxBitmap(const wxIcon& icon),
 
 143         "Create a new bitmap from a `wx.Icon` object.", "",
 
 147         wxBitmap(const wxImage& image, int depth=-1),
 
 148         "Creates bitmap object from a `wx.Image`. This has to be done to
 
 149 actually display a `wx.Image` as you cannot draw an image directly on
 
 150 a window. The resulting bitmap will use the provided colour depth (or
 
 151 that of the current screen colour depth if depth is -1) which entails
 
 152 that a colour reduction may have to take place.", "",
 
 159             "Construct a Bitmap from a list of strings formatted as XPM data.", "",
 
 160             wxBitmap(PyObject* listOfStrings))
 
 162                 char**    cArray = NULL;
 
 165                 cArray = ConvertListOfStrings(listOfStrings);
 
 168                 bmp = new wxBitmap(cArray);
 
 176             "Creates a bitmap from an array of bits.  You should only use this
 
 177 function for monochrome bitmaps (depth 1) in portable programs: in
 
 178 this case the bits parameter should contain an XBM image.  For other
 
 179 bit depths, the behaviour is platform dependent.", "",
 
 180             wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
 
 184                 PyString_AsStringAndSize(bits, &buf, &length);
 
 185                 return new wxBitmap(buf, width, height, depth);
 
 190     // wxGDIImage methods
 
 194         void SetHandle(long handle) { self->SetHandle((WXHANDLE)handle); }
 
 199     %pythoncode { Ok = IsOk }
 
 203         "Gets the width of the bitmap in pixels.", "");
 
 208         "Gets the height of the bitmap in pixels.", "");
 
 213         "Gets the colour depth of the bitmap. A value of 1 indicates a
 
 214 monochrome bitmap.", "");
 
 219         DocStr(GetSize, "Get the size of the bitmap.", "");
 
 221             wxSize size(self->GetWidth(), self->GetHeight());
 
 228         virtual wxImage , ConvertToImage() const,
 
 229         "Creates a platform-independent image from a platform-dependent
 
 230 bitmap. This preserves mask information so that bitmaps and images can
 
 231 be converted back and forth without loss in that respect.", "");
 
 235         virtual wxMask* , GetMask() const,
 
 236         "Gets the associated mask (if any) which may have been loaded from a
 
 237 file or explpicitly set for the bitmap.
 
 239 :see: `SetMask`, `wx.Mask`
 
 242     // MSW only?    wxBitmap GetMaskBitmap() const;
 
 246         virtual void , SetMask(wxMask* mask),
 
 247         "Sets the mask for this bitmap.
 
 249 :see: `GetMask`, `wx.Mask`
 
 251     %cleardisown(wxMask*);
 
 254         DocStr(SetMaskColour,
 
 255                "Create a Mask based on a specified colour in the Bitmap.", "");
 
 256         void SetMaskColour(const wxColour& colour) {
 
 257             wxMask *mask = new wxMask(*self, colour);
 
 264         virtual wxBitmap , GetSubBitmap(const wxRect& rect) const,
 
 265         "Returns a sub-bitmap of the current one as long as the rect belongs
 
 266 entirely to the bitmap. This function preserves bit depth and mask
 
 271         virtual bool , SaveFile(const wxString &name, wxBitmapType type,
 
 272                                 wxPalette *palette = NULL),
 
 273         "Saves a bitmap in the named file.  See `__init__` for a description of
 
 274 the ``type`` parameter.", "");
 
 278         virtual bool , LoadFile(const wxString &name, wxBitmapType type),
 
 279         "Loads a bitmap from a file.  See `__init__` for a description of the
 
 280 ``type`` parameter.", "");
 
 284     virtual wxPalette *GetPalette() const;
 
 286     virtual void SetPalette(const wxPalette& palette);
 
 290     virtual bool CopyFromIcon(const wxIcon& icon);
 
 293         virtual void , SetHeight(int height),
 
 294         "Set the height property (does not affect the existing bitmap data).", "");
 
 298         virtual void , SetWidth(int width),
 
 299         "Set the width property (does not affect the existing bitmap data).", "");
 
 303         virtual void , SetDepth(int depth),
 
 304         "Set the depth property (does not affect the existing bitmap data).", "");
 
 308         DocStr(SetSize, "Set the bitmap size (does not affect the existing bitmap data).", "");
 
 309         void SetSize(const wxSize& size) {
 
 310             self->SetWidth(size.x);
 
 311             self->SetHeight(size.y);
 
 316     bool CopyFromCursor(const wxCursor& cursor);
 
 320         DocStr(CopyFromBuffer,
 
 321                "Copy data from a RGB buffer object to replace the bitmap pixel data.
 
 322 See `wx.BitmapFromBuffer` for more details.", "");
 
 323         void CopyFromBuffer(buffer data, int DATASIZE)
 
 325             int height=self->GetHeight();
 
 326             int width=self->GetWidth();
 
 328             if (DATASIZE != width * height * 3) {
 
 329                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 331             wxNativePixelData pixData(*self, wxPoint(0,0), wxSize(width, height));
 
 333                 // raise an exception...
 
 334                 wxPyErr_SetString(PyExc_RuntimeError,
 
 335                                   "Failed to gain raw access to bitmap data.");
 
 339             wxNativePixelData::Iterator p(pixData);
 
 340             for (int y=0; y<height; y++) {
 
 341                 wxNativePixelData::Iterator rowStart = p;
 
 342                 for (int x=0; x<width; x++) {
 
 344                     p.Green() = *(data++);
 
 345                     p.Blue()  = *(data++);
 
 349                 p.OffsetY(pixData, 1);
 
 353         DocStr(CopyFromBufferRGBA,
 
 354                "Copy data from a RGBA buffer object to replace the bitmap pixel data.
 
 355 See `wx.BitmapFromBufferRGBA` for more details.", "");
 
 356         void CopyFromBufferRGBA(buffer data, int DATASIZE)
 
 358             int height=self->GetHeight();
 
 359             int width=self->GetWidth();
 
 361             if (DATASIZE != width * height * 4) {
 
 362                 wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 364             wxAlphaPixelData pixData(*self, wxPoint(0,0), wxSize(width, height));
 
 366                 // raise an exception...
 
 367                 wxPyErr_SetString(PyExc_RuntimeError,
 
 368                                   "Failed to gain raw access to bitmap data.");
 
 373             wxAlphaPixelData::Iterator p(pixData);
 
 374             for (int y=0; y<height; y++) {
 
 375                 wxAlphaPixelData::Iterator rowStart = p;
 
 376                 for (int x=0; x<width; x++) {
 
 378                     p.Red()   = wxPy_premultiply(*(data++), a);
 
 379                     p.Green() = wxPy_premultiply(*(data++), a);
 
 380                     p.Blue()  = wxPy_premultiply(*(data++), a);
 
 381                     p.Alpha() = a; data++;
 
 385                 p.OffsetY(pixData, 1);
 
 391     %pythoncode { def __nonzero__(self): return self.IsOk() }
 
 393     // TODO: Should these just be removed since the C++ operators are
 
 394     // gone?  Or is using IsSameAs for wxPython ok?    
 
 396         bool __eq__(const wxBitmap* other) { return other ? self->IsSameAs(*other) : false; }
 
 397         bool __ne__(const wxBitmap* other) { return other ? !self->IsSameAs(*other) : true;  }
 
 400     %property(Depth, GetDepth, SetDepth, doc="See `GetDepth` and `SetDepth`");
 
 401     %property(Height, GetHeight, SetHeight, doc="See `GetHeight` and `SetHeight`");
 
 402     %property(Mask, GetMask, SetMask, doc="See `GetMask` and `SetMask`");
 
 403     %property(Palette, GetPalette, doc="See `GetPalette`");
 
 404     %property(Size, GetSize, SetSize, doc="See `GetSize` and `SetSize`");
 
 405     %property(SubBitmap, GetSubBitmap, doc="See `GetSubBitmap`");
 
 406     %property(Width, GetWidth, SetWidth, doc="See `GetWidth` and `SetWidth`");
 
 411 //---------------------------------------------------------------------------
 
 412 // Factory functions for creating wxBitmaps from Python buffer objects.  They
 
 413 // use the Abstract Pixel API to be able to set RGB and A bytes directly into
 
 414 // the wxBitmap's pixel buffer.
 
 417 %newobject _BitmapFromBufferAlpha;
 
 418 %newobject _BitmapFromBuffer;
 
 420     wxBitmap* _BitmapFromBufferAlpha(int width, int height,
 
 421                                     buffer data, int DATASIZE,
 
 422                                     buffer alpha, int ALPHASIZE)
 
 424         if (DATASIZE != width*height*3) {
 
 425             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 429         if (ALPHASIZE != width*height) {
 
 430             wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
 
 434         wxBitmap* bmp = new wxBitmap(width, height, 32);
 
 435         wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 437             // raise an exception...
 
 438             wxPyErr_SetString(PyExc_RuntimeError,
 
 439                               "Failed to gain raw access to bitmap data.");
 
 444         wxAlphaPixelData::Iterator p(pixData);
 
 445         for (int y=0; y<height; y++) {
 
 446             wxAlphaPixelData::Iterator rowStart = p;
 
 447             for (int x=0; x<width; x++) {
 
 449                 p.Red()   = wxPy_premultiply(*(data++), a);
 
 450                 p.Green() = wxPy_premultiply(*(data++), a);
 
 451                 p.Blue()  = wxPy_premultiply(*(data++), a);
 
 456             p.OffsetY(pixData, 1);
 
 461     wxBitmap* _BitmapFromBuffer(int width, int height, buffer data, int DATASIZE)
 
 463         if (DATASIZE != width*height*3) {
 
 464             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 468         wxBitmap* bmp = new wxBitmap(width, height, 24);
 
 469         wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 471             // raise an exception...
 
 472             wxPyErr_SetString(PyExc_RuntimeError,
 
 473                               "Failed to gain raw access to bitmap data.");
 
 477         wxNativePixelData::Iterator p(pixData);
 
 478         for (int y=0; y<height; y++) {
 
 479             wxNativePixelData::Iterator rowStart = p;
 
 480             for (int x=0; x<width; x++) {
 
 482                 p.Green() = *(data++);
 
 483                 p.Blue()  = *(data++);
 
 487             p.OffsetY(pixData, 1);
 
 495 def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
 
 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 RGB bytes and be width*height*3
 
 501     bytes long.  A buffer object can optionally be supplied for the
 
 502     image's alpha channel data, and it is expected to be width*height
 
 503     bytes long.  On Windows the RGB values are 'premultiplied' by the
 
 504     alpha values.  (The other platforms do the multiplication
 
 507     Unlike `wx.ImageFromBuffer` the bitmap created with this function
 
 508     does not share the memory buffer with the buffer object.  This is
 
 509     because the native pixel buffer format varies on different
 
 510     platforms, and so instead an efficient as possible copy of the
 
 511     data is made from the buffer objects to the bitmap's native pixel
 
 512     buffer.  For direct access to a bitmap's pixel buffer see
 
 513     `wx.NativePixelData` and `wx.AlphaPixelData`.
 
 515     :see: `wx.Bitmap`, `wx.BitmapFromBufferRGBA`, `wx.NativePixelData`,
 
 516           `wx.AlphaPixelData`, `wx.ImageFromBuffer`
 
 518     if alphaBuffer is not None:
 
 519         return _gdi_._BitmapFromBufferAlpha(width, height, dataBuffer, alphaBuffer)
 
 521         return _gdi_._BitmapFromBuffer(width, height, dataBuffer)
 
 526 %newobject _BitmapFromBufferRGBA;
 
 528     wxBitmap* _BitmapFromBufferRGBA(int width, int height, buffer data, int DATASIZE)
 
 530         if (DATASIZE != width*height*4) {
 
 531             wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
 
 535         wxBitmap* bmp = new wxBitmap(width, height, 32);
 
 536         wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
 
 538             // raise an exception...
 
 539             wxPyErr_SetString(PyExc_RuntimeError,
 
 540                               "Failed to gain raw access to bitmap data.");
 
 545         wxAlphaPixelData::Iterator p(pixData);
 
 546         for (int y=0; y<height; y++) {
 
 547             wxAlphaPixelData::Iterator rowStart = p;
 
 548             for (int x=0; x<width; x++) {
 
 550                 p.Red()   = wxPy_premultiply(*(data++), a);
 
 551                 p.Green() = wxPy_premultiply(*(data++), a);
 
 552                 p.Blue()  = wxPy_premultiply(*(data++), a);
 
 553                 p.Alpha() = a; data++;
 
 557             p.OffsetY(pixData, 1);
 
 564 def BitmapFromBufferRGBA(width, height, dataBuffer):
 
 566     Creates a `wx.Bitmap` from the data in dataBuffer.  The dataBuffer
 
 567     parameter must be a Python object that implements the buffer
 
 568     interface, such as a string, array, etc.  The dataBuffer object is
 
 569     expected to contain a series of RGBA bytes (red, green, blue and
 
 570     alpha) and be width*height*4 bytes long.  On Windows the RGB
 
 571     values are 'premultiplied' by the alpha values.  (The other
 
 572     platforms do the multiplication themselves.)
 
 574     Unlike `wx.ImageFromBuffer` the bitmap created with this function
 
 575     does not share the memory buffer with the buffer object.  This is
 
 576     because the native pixel buffer format varies on different
 
 577     platforms, and so instead an efficient as possible copy of the
 
 578     data is made from the buffer object to the bitmap's native pixel
 
 579     buffer.  For direct access to a bitmap's pixel buffer see
 
 580     `wx.NativePixelData` and `wx.AlphaPixelData`.
 
 582     :see: `wx.Bitmap`, `wx.BitmapFromBuffer`, `wx.NativePixelData`,
 
 583           `wx.AlphaPixelData`, `wx.ImageFromBuffer`
 
 585     return _gdi_._BitmapFromBufferRGBA(width, height, dataBuffer)
 
 589 //---------------------------------------------------------------------------
 
 591 class wxPixelDataBase
 
 594     // origin of the rectangular region we represent
 
 595     wxPoint GetOrigin() const { return m_ptOrigin; }
 
 597     // width and height of the region we represent
 
 598     int GetWidth() const { return m_width; }
 
 599     int GetHeight() const { return m_height; }
 
 601     wxSize GetSize() const { return wxSize(m_width, m_height); }
 
 603     // the distance between two rows
 
 604     int GetRowStride() const { return m_stride; }
 
 606     %property(Height, GetHeight, doc="See `GetHeight`");
 
 607     %property(Origin, GetOrigin, doc="See `GetOrigin`");
 
 608     %property(RowStride, GetRowStride, doc="See `GetRowStride`");
 
 609     %property(Size, GetSize, doc="See `GetSize`");
 
 610     %property(Width, GetWidth, doc="See `GetWidth`");
 
 614 // Both wxNativePixelData and wxAlphaPixelData have the same interface, so
 
 615 // make a macro to declare them both.
 
 617 %define PIXELDATA(PixelData)
 
 619     typedef PixelData##::Iterator PixelData##_Accessor;
 
 621 class PixelData##_Accessor;
 
 622 class PixelData : public wxPixelDataBase
 
 627     PixelData(wxBitmap& bmp);
 
 628     PixelData(wxBitmap& bmp, const wxRect& rect);
 
 629     PixelData(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz);
 
 633     PixelData##_Accessor GetPixels() const;
 
 637         bool __nonzero__() { return self->operator bool(); }
 
 643         Create and return an iterator object for this pixel data
 
 644         object.  (It's really a generator but I won't tell if you
 
 647         width  = self.GetWidth()
 
 648         height = self.GetHeight()
 
 649         pixels = self.GetPixels()
 
 651         # This class is a facade over the pixels object (using the one
 
 652         # in the enclosing scope) that only allows Get() and Set() to
 
 654         class PixelFacade(object):
 
 657             def Set(self, *args, **kw):
 
 658                 return pixels.Set(*args, **kw)
 
 660                 return str(self.Get())
 
 662                 return 'pixel(%d,%d): %s' % (x,y,self.Get())
 
 663             X = property(lambda self: x)
 
 664             Y = property(lambda self: y)
 
 667         for y in xrange(height):
 
 668             for x in xrange(width):
 
 669                 # We always generate the same pf instance, but it
 
 670                 # accesses the pixels object which we use to iterate
 
 671                 # over the pixel buffer.
 
 674             pixels.MoveTo(self, 0, y)
 
 677     %property(Pixels, GetPixels, doc="See `GetPixels`");
 
 682 class PixelData##_Accessor
 
 685     %nokwargs PixelData##_Accessor;
 
 687     PixelData##_Accessor(PixelData& data);
 
 688     PixelData##_Accessor(wxBitmap& bmp, PixelData& data);
 
 689     PixelData##_Accessor();
 
 691     ~PixelData##_Accessor();
 
 693     void Reset(const PixelData& data);
 
 697         // PixelData##_Accessor& nextPixel() { return ++(*self); }
 
 698         void nextPixel() { ++(*self); }
 
 701     void Offset(const PixelData& data, int x, int y);
 
 702     void OffsetX(const PixelData& data, int x);
 
 703     void OffsetY(const PixelData& data, int y);
 
 704     void MoveTo(const PixelData& data, int x, int y);
 
 706 // NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha
 
 707 // functions because I can't hide the premultiplying needed on wxMSW
 
 708 // if only the individual components are wrapped, plus it would mean 3
 
 709 // or 4 trips per pixel from Python to C++ instead of just one.
 
 710 // Instead I've added the Set and Get functions and put the
 
 711 // premultiplying in there.
 
 714 //         byte _get_Red()   { return self->Red(); }
 
 715 //         byte _get_Green() { return self->Green(); }
 
 716 //         byte _get_Blue()  { return self->Blue(); }
 
 718 //         void _set_Red(byte val)   { self->Red() = val; }
 
 719 //         void _set_Green(byte val) { self->Green() = val; }
 
 720 //         void _set_Blue(byte val)  { self->Blue() = val; }
 
 724 //         Red   = property(_get_Red,   _set_Red)
 
 725 //         Green = property(_get_Green, _set_Green)
 
 726 //         Blue  = property(_get_Blue,  _set_Blue)
 
 732 %pythonAppend wxAlphaPixelData::wxAlphaPixelData "self.UseAlpha()"
 
 735 PIXELDATA(wxNativePixelData)
 
 736 PIXELDATA(wxAlphaPixelData)    
 
 739 // Add in a few things that are different between the wxNativePixelData and
 
 740 // wxAlphaPixelData and the iterator classes and so are not included in our
 
 743 %extend wxNativePixelData_Accessor {
 
 744     void Set(byte red, byte green, byte blue) {
 
 746         self->Green() = green;
 
 751         PyObject* rv = PyTuple_New(3);
 
 752         PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red()));
 
 753         PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green()));
 
 754         PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue()));
 
 759 %extend wxAlphaPixelData_Accessor {
 
 760 //     byte _get_Alpha()         { return self->Alpha(); }
 
 761 //     void _set_Alpha(byte val) { self->Alpha() = val; }
 
 764 //         Alpha = property(_get_Alpha, _set_Alpha)
 
 767     void Set(byte red, byte green, byte blue, byte alpha) {
 
 768         self->Red()   = wxPy_premultiply(red,   alpha);
 
 769         self->Green() = wxPy_premultiply(green, alpha);
 
 770         self->Blue()  = wxPy_premultiply(blue,  alpha);
 
 771         self->Alpha() = alpha;
 
 775         PyObject* rv = PyTuple_New(4);
 
 776         int red   = self->Red();
 
 777         int green = self->Green();
 
 778         int blue  = self->Blue();
 
 779         int alpha = self->Alpha();
 
 781         PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red,   alpha) ));
 
 782         PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
 
 783         PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue,  alpha) ));
 
 784         PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha ));
 
 790 //---------------------------------------------------------------------------
 
 793 "This class encapsulates a monochrome mask bitmap, where the masked
 
 794 area is black and the unmasked area is white. When associated with a
 
 795 bitmap and drawn in a device context, the unmasked area of the bitmap
 
 796 will be drawn, and the masked area will not be drawn.
 
 798 A mask may be associated with a `wx.Bitmap`. It is used in
 
 799 `wx.DC.DrawBitmap` or `wx.DC.Blit` when the source device context is a
 
 800 `wx.MemoryDC` with a `wx.Bitmap` selected into it that contains a
 
 805 class wxMask : public wxObject {
 
 809            "Constructs a mask from a `wx.Bitmap` and a `wx.Colour` in that bitmap
 
 810 that indicates the transparent portions of the mask.  In other words,
 
 811 the pixels in ``bitmap`` that match ``colour`` will be the transparent
 
 812 portions of the mask.  If no ``colour`` or an invalid ``colour`` is
 
 813 passed then BLACK is used.
 
 815 :see: `wx.Bitmap`, `wx.Colour`", "");
 
 818         wxMask(const wxBitmap& bitmap, const wxColour& colour = wxNullColour) {
 
 819             if ( !colour.IsOk() )
 
 820                 return new wxMask(bitmap, *wxBLACK);
 
 822                 return new wxMask(bitmap, colour);
 
 829 %pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") }
 
 831 //---------------------------------------------------------------------------
 
 832 //---------------------------------------------------------------------------
 
 834 // Turn GIL acquisition back on.