X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a72f4631fe5ab7ebeefdacf8ec9c826ea962133f..64e941edd4c6ff84e75e98ec551c42096f31ec77:/wxPython/src/_bitmap.i diff --git a/wxPython/src/_bitmap.i b/wxPython/src/_bitmap.i index a89b83b968..f6ee5a0c8d 100644 --- a/wxPython/src/_bitmap.i +++ b/wxPython/src/_bitmap.i @@ -12,6 +12,13 @@ // Not a %module +%{ +#include +%} + + +// Turn off the aquisition of the Global Interpreter Lock for this file +%threadWrapperOff //--------------------------------------------------------------------------- @@ -62,6 +69,10 @@ converted to a wx.Bitmap, so any image file format supported by :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` "); @@ -107,7 +118,7 @@ public: 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( @@ -126,38 +137,39 @@ that a colour reduction may have to take place.", "", %extend { - DocStr(wxBitmap(PyObject* listOfStrings), - "Construct a Bitmap from a list of strings formatted as XPM data.", ""); - %name(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.", ""); - %name(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); + } } -#ifdef __WXMSW__ - void SetPalette(wxPalette& palette); -#endif - // wxGDIImage methods #ifdef __WXMSW__ long GetHandle(); @@ -201,6 +213,7 @@ bitmap. This preserves mask information so that bitmaps and images can 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 @@ -208,15 +221,17 @@ file or explpicitly set for the bitmap. :see: `SetMask`, `wx.Mask` ", ""); - + // 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, @@ -249,8 +264,8 @@ the ``type`` parameter.", ""); -#if wxUSE_PALETTE virtual wxPalette *GetPalette() const; +#ifdef __WXMSW__ virtual void SetPalette(const wxPalette& palette); #endif @@ -282,8 +297,14 @@ the ``type`` parameter.", ""); #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() } @@ -295,6 +316,406 @@ the ``type`` parameter.", ""); }; +//--------------------------------------------------------------------------- +// 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; yoperator 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, @@ -331,10 +752,11 @@ passed then BLACK is used. } } - //~wxMask(); + ~wxMask(); }; %pythoncode { MaskColour = wx._deprecated(Mask, "wx.MaskColour is deprecated, use `wx.Mask` instead.") } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- +%threadWrapperOn