// Not a %module
+%{
+#include <wx/rawbmp.h>
+%}
+
+
+// Turn off the aquisition of the Global Interpreter Lock for this file
+%threadWrapperOff
//---------------------------------------------------------------------------
:todo: Find a way to do very efficient PIL Image <--> wx.Bitmap
converstions.
+
+:see: `wx.EmptyBitmap`, `wx.BitmapFromIcon`, `wx.BitmapFromImage`,
+ `wx.BitmapFromXPMData`, `wx.BitmapFromBits`, `wx.BitmapFromBuffer`,
+ `wx.BitmapFromBufferRGBA`, `wx.Image`
");
wxBitmap(int width, int height, int depth=-1),
"Creates a new bitmap of the given size. A depth of -1 indicates the
depth of the current screen or visual. Some platforms only support 1
-for monochrome and -1 for the current colour setting.", "",
+for monochrome and -1 for the current display depth.", "",
EmptyBitmap);
DocCtorStrName(
%extend {
- DocStr(wxBitmap(PyObject* listOfStrings),
- "Construct a Bitmap from a list of strings formatted as XPM data.", "");
-
- %RenameCtor(BitmapFromXPMData, wxBitmap(PyObject* listOfStrings))
- {
- char** cArray = NULL;
- wxBitmap* bmp;
-
- cArray = ConvertListOfStrings(listOfStrings);
- if (! cArray)
- return NULL;
- bmp = new wxBitmap(cArray);
- delete [] cArray;
- return bmp;
- }
-
- DocStr(wxBitmap(PyObject* bits, int width, int height, int depth=1 ),
- "Creates a bitmap from an array of bits. You should only use this
+ %RenameDocCtor(
+ BitmapFromXPMData,
+ "Construct a Bitmap from a list of strings formatted as XPM data.", "",
+ wxBitmap(PyObject* listOfStrings))
+ {
+ char** cArray = NULL;
+ wxBitmap* bmp;
+
+ cArray = ConvertListOfStrings(listOfStrings);
+ if (! cArray)
+ return NULL;
+ bmp = new wxBitmap(cArray);
+ delete [] cArray;
+ return bmp;
+ }
+
+
+ %RenameDocCtor(
+ BitmapFromBits,
+ "Creates a bitmap from an array of bits. You should only use this
function for monochrome bitmaps (depth 1) in portable programs: in
this case the bits parameter should contain an XBM image. For other
-bit depths, the behaviour is platform dependent.", "");
-
- %RenameCtor(BitmapFromBits, wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
- {
- char* buf;
- int length;
- PyString_AsStringAndSize(bits, &buf, &length);
- return new wxBitmap(buf, width, height, depth);
- }
+bit depths, the behaviour is platform dependent.", "",
+ wxBitmap(PyObject* bits, int width, int height, int depth=1 ))
+ {
+ char* buf;
+ Py_ssize_t length;
+ PyString_AsStringAndSize(bits, &buf, &length);
+ return new wxBitmap(buf, width, height, depth);
+ }
}
be converted back and forth without loss in that respect.", "");
+
DocDeclStr(
virtual wxMask* , GetMask() const,
"Gets the associated mask (if any) which may have been loaded from a
// MSW only? wxBitmap GetMaskBitmap() const;
+ %disownarg(wxMask*);
DocDeclStr(
virtual void , SetMask(wxMask* mask),
"Sets the mask for this bitmap.
:see: `GetMask`, `wx.Mask`
", "");
-
+ %cleardisown(wxMask*);
%extend {
DocStr(SetMaskColour,
#ifdef __WXMSW__
bool CopyFromCursor(const wxCursor& cursor);
+
+// WXWIN_COMPATIBILITY_2_4
+ #if 0
int GetQuality();
void SetQuality(int q);
+ %pythoncode { GetQuality = wx._deprecated(GetQuality) }
+ %pythoncode { SetQuality = wx._deprecated(SetQuality) }
+ #endif
#endif
%pythoncode { def __nonzero__(self): return self.Ok() }
};
+//---------------------------------------------------------------------------
+// Factory functions for creating wxBitmaps from Python buffer objects. They
+// use the Abstract Pixel API to be able to set RGB and A bytes directly into
+// the wxBitmap's pixel buffer.
+
+%{
+// See http://tinyurl.com/e5adr for what premultiplying alpha means. It
+// appears to me that the other platforms are already doing it, so I'll just
+// automatically do it for wxMSW here.
+#ifdef __WXMSW__
+#define wxPy_premultiply(p, a) ((p) * (a) / 256)
+#define wxPy_unpremultiply(p, a) ((a) ? ((p) * 256 / (a)) : (p))
+#else
+#define wxPy_premultiply(p, a) (p)
+#define wxPy_unpremultiply(p, a) (p)
+#endif
+%}
+
+
+%newobject _BitmapFromBufferAlpha;
+%newobject _BitmapFromBuffer;
+%inline %{
+ wxBitmap* _BitmapFromBufferAlpha(int width, int height,
+ buffer data, int DATASIZE,
+ buffer alpha, int ALPHASIZE)
+ {
+ if (DATASIZE != width*height*3) {
+ wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
+ return NULL;
+ }
+
+ if (ALPHASIZE != width*height) {
+ wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
+ return NULL;
+ }
+
+ wxBitmap* bmp = new wxBitmap(width, height, 32);
+ wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
+ if (! pixData) {
+ // raise an exception...
+ wxPyErr_SetString(PyExc_RuntimeError,
+ "Failed to gain raw access to bitmap data.");
+ return NULL;
+ }
+
+ pixData.UseAlpha();
+ wxAlphaPixelData::Iterator p(pixData);
+ for (int y=0; y<height; y++) {
+ wxAlphaPixelData::Iterator rowStart = p;
+ for (int x=0; x<width; x++) {
+ byte a = *(alpha++);
+ p.Red() = wxPy_premultiply(*(data++), a);
+ p.Green() = wxPy_premultiply(*(data++), a);
+ p.Blue() = wxPy_premultiply(*(data++), a);
+ p.Alpha() = a;
+ ++p;
+ }
+ p = rowStart;
+ p.OffsetY(pixData, 1);
+ }
+ return bmp;
+ }
+
+ wxBitmap* _BitmapFromBuffer(int width, int height, buffer data, int DATASIZE)
+ {
+ if (DATASIZE != width*height*3) {
+ wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
+ return NULL;
+ }
+
+ wxBitmap* bmp = new wxBitmap(width, height, 24);
+ wxNativePixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
+ if (! pixData) {
+ // raise an exception...
+ wxPyErr_SetString(PyExc_RuntimeError,
+ "Failed to gain raw access to bitmap data.");
+ return NULL;
+ }
+
+ wxNativePixelData::Iterator p(pixData);
+ for (int y=0; y<height; y++) {
+ wxNativePixelData::Iterator rowStart = p;
+ for (int x=0; x<width; x++) {
+ p.Red() = *(data++);
+ p.Green() = *(data++);
+ p.Blue() = *(data++);
+ ++p;
+ }
+ p = rowStart;
+ p.OffsetY(pixData, 1);
+ }
+ return bmp;
+ }
+%}
+
+
+%pythoncode {
+def BitmapFromBuffer(width, height, dataBuffer, alphaBuffer=None):
+ """
+ Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
+ parameter must be a Python object that implements the buffer interface, or
+ is convertable to a buffer object, such as a string, array, etc. The
+ dataBuffer object is expected to contain a series of RGB bytes and be
+ width*height*3 bytes long. A buffer object can optionally be supplied for
+ the image's alpha channel data, and it is expected to be width*height
+ bytes long. On Windows the RGB values are 'premultiplied' by the alpha
+ values. (The other platforms appear to already be premultiplying the
+ alpha.)
+
+ Unlike `wx.ImageFromBuffer` the bitmap created with this function does not
+ share the memory buffer with the buffer object. This is because the
+ native pixel buffer format varies on different platforms, and so instead
+ an efficient as possible copy of the data is made from the buffer objects
+ to the bitmap's native pixel buffer. For direct access to a bitmap's
+ pixel buffer see `wx.NativePixelData` and `wx.AlphaPixelData`.
+
+ :see: `wx.Bitmap`, `wx.BitmapFromBufferRGBA`, `wx.NativePixelData`,
+ `wx.AlphaPixelData`, `wx.ImageFromBuffer`
+ """
+ if not isinstance(dataBuffer, buffer):
+ dataBuffer = buffer(dataBuffer)
+ if alphaBuffer is not None and not isinstance(alphaBuffer, buffer):
+ alphaBuffer = buffer(alphaBuffer)
+ if alphaBuffer is not None:
+ return _gdi_._BitmapFromBufferAlpha(width, height, dataBuffer, alphaBuffer)
+ else:
+ return _gdi_._BitmapFromBuffer(width, height, dataBuffer)
+}
+
+
+
+%newobject _BitmapFromBufferRGBA;
+%inline %{
+ wxBitmap* _BitmapFromBufferRGBA(int width, int height, buffer data, int DATASIZE)
+ {
+ if (DATASIZE != width*height*4) {
+ wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
+ return NULL;
+ }
+
+ wxBitmap* bmp = new wxBitmap(width, height, 32);
+ wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
+ if (! pixData) {
+ // raise an exception...
+ wxPyErr_SetString(PyExc_RuntimeError,
+ "Failed to gain raw access to bitmap data.");
+ return NULL;
+ }
+
+ pixData.UseAlpha();
+ wxAlphaPixelData::Iterator p(pixData);
+ for (int y=0; y<height; y++) {
+ wxAlphaPixelData::Iterator rowStart = p;
+ for (int x=0; x<width; x++) {
+ byte a = data[3];
+ p.Red() = wxPy_premultiply(*(data++), a);
+ p.Green() = wxPy_premultiply(*(data++), a);
+ p.Blue() = wxPy_premultiply(*(data++), a);
+ p.Alpha() = a; data++;
+ ++p;
+ }
+ p = rowStart;
+ p.OffsetY(pixData, 1);
+ }
+ return bmp;
+ }
+%}
+
+%pythoncode {
+def BitmapFromBufferRGBA(width, height, dataBuffer):
+ """
+ Creates a `wx.Bitmap` from the data in dataBuffer. The dataBuffer
+ parameter must be a Python object that implements the buffer interface, or
+ is convertable to a buffer object, such as a string, array, etc. The
+ dataBuffer object is expected to contain a series of RGBA bytes (red,
+ green, blue and alpha) and be width*height*4 bytes long. On Windows the
+ RGB values are 'premultiplied' by the alpha values. (The other platforms
+ appear to already be premultiplying the alpha.)
+
+ Unlike `wx.ImageFromBuffer` the bitmap created with this function does not
+ share the memory buffer with the buffer object. This is because the
+ native pixel buffer format varies on different platforms, and so instead
+ an efficient as possible copy of the data is made from the buffer object
+ to the bitmap's native pixel buffer. For direct access to a bitmap's
+ pixel buffer see `wx.NativePixelData` and `wx.AlphaPixelData`.
+
+ :see: `wx.Bitmap`, `wx.BitmapFromBuffer`, `wx.NativePixelData`,
+ `wx.AlphaPixelData`, `wx.ImageFromBuffer`
+ """
+ if not isinstance(dataBuffer, buffer):
+ dataBuffer = buffer(dataBuffer)
+ return _gdi_._BitmapFromBufferRGBA(width, height, dataBuffer)
+}
+
+
+//---------------------------------------------------------------------------
+
+class wxPixelDataBase
+{
+public:
+ // origin of the rectangular region we represent
+ wxPoint GetOrigin() const { return m_ptOrigin; }
+
+ // width and height of the region we represent
+ int GetWidth() const { return m_width; }
+ int GetHeight() const { return m_height; }
+
+ wxSize GetSize() const { return wxSize(m_width, m_height); }
+
+ // the distance between two rows
+ int GetRowStride() const { return m_stride; }
+
+};
+
+
+// Both wxNativePixelData and wxAlphaPixelData have the same interface, so
+// make a macro to declare them both.
+
+%define PIXELDATA(PixelData)
+%{
+ typedef PixelData##::Iterator PixelData##_Accessor;
+%}
+class PixelData##_Accessor;
+class PixelData : public wxPixelDataBase
+{
+public:
+ %nokwargs PixelData;
+
+ PixelData(wxBitmap& bmp);
+ PixelData(wxBitmap& bmp, const wxRect& rect);
+ PixelData(wxBitmap& bmp, const wxPoint& pt, const wxSize& sz);
+
+ ~PixelData();
+
+ PixelData##_Accessor GetPixels() const;
+ void UseAlpha();
+
+ %extend {
+ bool __nonzero__() { return self->operator bool(); }
+ }
+
+ %pythoncode {
+ def __iter__(self):
+ """Create and return an iterator object for this pixel data object."""
+ return self.PixelIterator(self)
+
+ class PixelIterator(object):
+ """
+ Sequential iterator which returns pixel accessor objects starting at the
+ the top-left corner, and going row-by-row until the bottom-right
+ corner is reached.
+ """
+
+ class PixelAccessor(object):
+ """
+ This class is what is returned by the iterator and allows the pixel
+ to be Get or Set.
+ """
+ def __init__(self, data, pixels, x, y):
+ self.data = data
+ self.pixels = pixels
+ self.x = x
+ self.y = y
+ def Set(self, *args, **kw):
+ self.pixels.MoveTo(self.data, self.x, self.y)
+ return self.pixels.Set(*args, **kw)
+ def Get(self):
+ self.pixels.MoveTo(self.data, self.x, self.y)
+ return self.pixels.Get()
+
+ def __init__(self, pixelData):
+ self.x = self.y = 0
+ self.w = pixelData.GetWidth()
+ self.h = pixelData.GetHeight()
+ self.data = pixelData
+ self.pixels = pixelData.GetPixels()
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.y >= self.h:
+ raise StopIteration
+ p = self.PixelAccessor(self.data, self.pixels, self.x, self.y)
+ self.x += 1
+ if self.x >= self.w:
+ self.x = 0
+ self.y += 1
+ return p
+ }
+};
+
+
+
+class PixelData##_Accessor
+{
+public:
+ %nokwargs PixelData##_Accessor;
+
+ PixelData##_Accessor(PixelData& data);
+ PixelData##_Accessor(wxBitmap& bmp, PixelData& data);
+ PixelData##_Accessor();
+
+ ~PixelData##_Accessor();
+
+ void Reset(const PixelData& data);
+ bool IsOk() const;
+
+ %extend {
+ // PixelData##_Accessor& nextPixel() { return ++(*self); }
+ void nextPixel() { ++(*self); }
+ }
+
+ void Offset(const PixelData& data, int x, int y);
+ void OffsetX(const PixelData& data, int x);
+ void OffsetY(const PixelData& data, int y);
+ void MoveTo(const PixelData& data, int x, int y);
+
+// NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha functions
+// because I can't hide the premultiplying needed on wxMSW if only the
+// individual components are wrapped. Instead I've added the Set and Get
+// functions and put the puemultiplying in there.
+
+// %extend {
+// byte _get_Red() { return self->Red(); }
+// byte _get_Green() { return self->Green(); }
+// byte _get_Blue() { return self->Blue(); }
+
+// void _set_Red(byte val) { self->Red() = val; }
+// void _set_Green(byte val) { self->Green() = val; }
+// void _set_Blue(byte val) { self->Blue() = val; }
+// }
+
+// %pythoncode {
+// Red = property(_get_Red, _set_Red)
+// Green = property(_get_Green, _set_Green)
+// Blue = property(_get_Blue, _set_Blue)
+// }
+};
+%enddef
+
+
+%pythonAppend wxAlphaPixelData::wxAlphaPixelData "self.UseAlpha()"
+
+// Make the classes
+PIXELDATA(wxNativePixelData)
+PIXELDATA(wxAlphaPixelData)
+
+
+// Add in a few things that are different between the wxNativePixelData and
+// wxAlphaPixelData and the iterator classes and so are not included in our
+// macro...
+
+%extend wxNativePixelData_Accessor {
+ void Set(byte red, byte green, byte blue) {
+ self->Red() = red;
+ self->Green() = green;
+ self->Blue() = blue;
+ }
+
+ PyObject* Get() {
+ PyObject* rv = PyTuple_New(3);
+ PyTuple_SetItem(rv, 0, PyInt_FromLong(self->Red()));
+ PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green()));
+ PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue()));
+ return rv;
+ }
+}
+
+%extend wxAlphaPixelData_Accessor {
+// byte _get_Alpha() { return self->Alpha(); }
+// void _set_Alpha(byte val) { self->Alpha() = val; }
+
+// %pythoncode {
+// Alpha = property(_get_Alpha, _set_Alpha)
+// }
+
+ void Set(byte red, byte green, byte blue, byte alpha) {
+ self->Red() = wxPy_premultiply(red, alpha);
+ self->Green() = wxPy_premultiply(green, alpha);
+ self->Blue() = wxPy_premultiply(blue, alpha);
+ self->Alpha() = alpha;
+ }
+
+ PyObject* Get() {
+ PyObject* rv = PyTuple_New(4);
+ int red = self->Red();
+ int green = self->Green();
+ int blue = self->Blue();
+ int alpha = self->Alpha();
+
+ PyTuple_SetItem(rv, 0, PyInt_FromLong( wxPy_unpremultiply(red, alpha) ));
+ PyTuple_SetItem(rv, 1, PyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
+ PyTuple_SetItem(rv, 2, PyInt_FromLong( wxPy_unpremultiply(blue, alpha) ));
+ PyTuple_SetItem(rv, 3, PyInt_FromLong( alpha ));
+ return rv;
+ }
+}
+
+
//---------------------------------------------------------------------------
DocStr(wxMask,
}
}
- //~wxMask();
+ ~wxMask();
};
%pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") }
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
+%threadWrapperOn