From 281c54cc42f9ca2578f08218b1eed8d5208db8f7 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 11 Oct 2006 04:42:49 +0000 Subject: [PATCH] helpers and typemaps for new GraphicsContext methods git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41929 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/include/wx/wxPython/wxPython.h | 3 + wxPython/include/wx/wxPython/wxPython_int.h | 6 + wxPython/src/_core_api.i | 4 +- wxPython/src/_graphics.i | 77 ++++++-- wxPython/src/helpers.cpp | 205 ++++++++++++++++---- wxPython/src/my_typemaps.i | 46 +++-- 6 files changed, 271 insertions(+), 70 deletions(-) diff --git a/wxPython/include/wx/wxPython/wxPython.h b/wxPython/include/wx/wxPython/wxPython.h index 1cf05fc148..efdb2e0df4 100644 --- a/wxPython/include/wx/wxPython/wxPython.h +++ b/wxPython/include/wx/wxPython/wxPython.h @@ -119,6 +119,9 @@ inline wxPyCoreAPI* wxPyGetCoreAPIPtr() #define wxPyCheckForApp() (wxPyGetCoreAPIPtr()->p_wxPyCheckForApp()) +#define wxArrayDouble2PyList_helper(a) (wxPyGetCoreAPIPtr()->p_wxArrayDoublePyList_helper(a)) +#define wxPoint2D_LIST_helper(a,b) (wxPyGetCoreAPIPtr()->p_wxPoint2D_LIST_helper(a, b)) + //---------------------------------------------------------------------- #endif diff --git a/wxPython/include/wx/wxPython/wxPython_int.h b/wxPython/include/wx/wxPython/wxPython_int.h index cfba4e7fdb..863f5c0f68 100644 --- a/wxPython/include/wx/wxPython/wxPython_int.h +++ b/wxPython/include/wx/wxPython/wxPython_int.h @@ -235,6 +235,7 @@ int* int_LIST_helper(PyObject* source); long* long_LIST_helper(PyObject* source); char** string_LIST_helper(PyObject* source); wxPoint* wxPoint_LIST_helper(PyObject* source, int* npoints); +wxPoint2D* wxPoint2D_LIST_helper(PyObject* source, size_t* npoints); wxBitmap** wxBitmap_LIST_helper(PyObject* source); wxString* wxString_LIST_helper(PyObject* source); wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source); @@ -261,6 +262,7 @@ bool wxPy4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4); PyObject* wxArrayString2PyList_helper(const wxArrayString& arr); PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr); +PyObject* wxArrayDouble2PyList_helper(const wxArrayDouble& arr); #endif // wxPyUSE_EXPORTED_API @@ -422,8 +424,12 @@ struct wxPyCoreAPI { bool (*p_wxPyCheckForApp)(); + // Add all new items at the end... + PyObject* (*p_wxArrayDoublePyList_helper)(const wxArrayDouble& arr); + wxPoint2D* (*p_wxPoint2D_LIST_helper)(PyObject* source, size_t* npoints); }; + #ifdef wxPyUSE_EXPORTED_API // Notice that this is static, not extern. This is by design, each module // needs one, but doesn't have to use it. diff --git a/wxPython/src/_core_api.i b/wxPython/src/_core_api.i index 0669d1fcbb..94050287b9 100644 --- a/wxPython/src/_core_api.i +++ b/wxPython/src/_core_api.i @@ -235,8 +235,10 @@ static wxPyCoreAPI API = { wxPyInstance_Check, wxPySwigInstance_Check, - wxPyCheckForApp + wxPyCheckForApp, + wxArrayDouble2PyList_helper, + wxPoint2D_LIST_helper }; #endif diff --git a/wxPython/src/_graphics.i b/wxPython/src/_graphics.i index 9533e3696f..9a761ed4ee 100644 --- a/wxPython/src/_graphics.i +++ b/wxPython/src/_graphics.i @@ -20,6 +20,10 @@ #include %} +// Turn off the aquisition of the Global Interpreter Lock for the classes and +// functions in this file +%threadWrapperOff + //--------------------------------------------------------------------------- @@ -140,6 +144,17 @@ public: //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- + +%typemap(in) (size_t points, wxPoint2D* points_array ) { + $2 = wxPoint2D_LIST_helper($input, &$1); + if ($2 == NULL) SWIG_fail; +} +%typemap(freearg) (size_t points, wxPoint2D* points_array ) { + if ($2) delete [] $2; +} + + + MustHaveApp(wxGraphicsPath); MustHaveApp(wxGraphicsContext); MustHaveApp(wxGCDC); @@ -210,7 +225,7 @@ point and an end point", ""); DocDeclStr( virtual void , AddCircle( wxDouble x, wxDouble y, wxDouble r ), - "Appends an ellipsis as a new closed subpath fitting the passed rectangle", ""); + "Appends a circle as a new closed subpath with the given radius.", ""); DocDeclStr( @@ -351,23 +366,32 @@ public: "", ""); - DocDeclStr( + DocDeclStrName( virtual void , DrawText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle ), - "", ""); + "", "", + DrawRotatedText); - DocDeclStr( + DocDeclAStr( virtual void , GetTextExtent( const wxString &text, wxDouble *OUTPUT /*width*/, wxDouble *OUTPUT /*height*/, wxDouble *OUTPUT /*descent*/, wxDouble *OUTPUT /*externalLeading*/ ) const , + "GetTextExtend(self, text) --> (width, height, descent, externalLeading)", "", ""); - DocDeclStr( - virtual void , GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const, - "", ""); + %extend { + DocAStr(GetPartialTextExtents, + "GetPartialTextExtents(self, text) -> [widths]", + "", ""); + wxArrayDouble GetPartialTextExtents(const wxString& text) { + wxArrayDouble widths; + self->GetPartialTextExtents(text, widths); + return widths; + } + } // @@ -392,23 +416,39 @@ public: DocDeclStr( virtual void , StrokeLine( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2), "", ""); - + // stroke lines connecting each of the points - DocDeclStr( - virtual void , StrokeLines( size_t n, const wxPoint2D *points), + DocDeclAStr( + virtual void , StrokeLines( size_t points, const wxPoint2D *points_array), + "StrokeLines(self, List points)", "", ""); - // stroke disconnected lines from begin to end points - DocDeclStr( - virtual void , StrokeLines( size_t n, const wxPoint2D *beginPoints, const wxPoint2D *endPoints), - "", ""); - +// // stroke disconnected lines from begin to end points +// virtual void StrokeLines( size_t n, const wxPoint2D *beginPoints, const wxPoint2D *endPoints); + + // is there a better name for this? + %extend { + void StrokeDisconnectedLines(PyObject* beginPoints, PyObject* endPoints) + { + size_t c1, c2, count; + wxPoint2D* beginP = wxPoint2D_LIST_helper(beginPoints, &c1); + wxPoint2D* endP = wxPoint2D_LIST_helper(endPoints, &c2); + + if ( beginP != NULL && endP != NULL ) + { + count = wxMin(c1, c2); + self->StrokeLines(count, beginP, endP); + } + delete [] beginP; + delete [] endP; + } + } // draws a polygon DocDeclStr( - virtual void , DrawLines( size_t n, const wxPoint2D *points, int fillStyle = wxWINDING_RULE ), + virtual void , DrawLines( size_t points, const wxPoint2D *points_array, int fillStyle = wxWINDING_RULE ), "", ""); @@ -429,7 +469,6 @@ public: virtual void , DrawRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius), "", ""); - }; @@ -449,6 +488,8 @@ public: }; +//--------------------------------------------------------------------------- +// Turn GIL acquisition back on. +%threadWrapperOn -//--------------------------------------------------------------------------- diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index eee5e107f6..7bfbb60175 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -2058,37 +2058,73 @@ char** string_LIST_helper(PyObject* source) { return temp; } -//-------------------------------- -// Part of patch from Tim Hochberg -static inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point) { - if (PyInt_Check(o1) && PyInt_Check(o2)) { - point->x = PyInt_AS_LONG(o1); - point->y = PyInt_AS_LONG(o2); - return true; - } - if (PyFloat_Check(o1) && PyFloat_Check(o2)) { +//--------------------------------------------------------------------------- +// NOTE: The following functions could really use some refactoring using +// templates to make things somewhat simpler... + +inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point) +{ + // get the x value + if (PyInt_Check(o1)) + point->x = (int)PyInt_AS_LONG(o1); + else if (PyFloat_Check(o1)) point->x = (int)PyFloat_AS_DOUBLE(o1); + else if (PyNumber_Check(o1)) + point->x = (int)PyInt_AsLong(o1); + else + return false; + + // get the y value + if (PyInt_Check(o2)) + point->y = (int)PyInt_AS_LONG(o2); + else if (PyFloat_Check(o2)) point->y = (int)PyFloat_AS_DOUBLE(o2); - return true; - } - if (wxPySwigInstance_Check(o1) || wxPySwigInstance_Check(o2)) { // TODO: Why??? - // Disallow instances because they can cause havok + else if (PyNumber_Check(o2)) + point->y = (int)PyInt_AsLong(o2); + else return false; - } - if (PyNumber_Check(o1) && PyNumber_Check(o2)) { - // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2 - point->x = PyInt_AsLong(o1); - point->y = PyInt_AsLong(o2); - return true; - } - return false; + + return true; + +// NOTE: This function used to have this code in it, but I don't know why it +// is a problem nor what havok it will cause, so removing for now... +// if (wxPySwigInstance_Check(o1) || wxPySwigInstance_Check(o2)) { +// // Disallow instances because they can cause havok +// return false; +// } +} + + +inline bool wxPoint2DFromObjects(PyObject* o1, PyObject* o2, wxPoint2D* point) +{ + // get the x value + if (PyInt_Check(o1)) + point->m_x = (double)PyInt_AS_LONG(o1); + else if (PyFloat_Check(o1)) + point->m_x = (double)PyFloat_AS_DOUBLE(o1); + else if (PyNumber_Check(o1)) + point->m_x = (double)PyFloat_AsDouble(o1); + else + return false; + + // get the y value + if (PyInt_Check(o2)) + point->m_y = (double)PyInt_AS_LONG(o2); + else if (PyFloat_Check(o2)) + point->m_y = (double)PyFloat_AS_DOUBLE(o2); + else if (PyNumber_Check(o2)) + point->m_y = (double)PyFloat_AsDouble(o2); + else + return false; + + return true; } -wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) { - // Putting all of the declarations here allows - // us to put the error handling all in one place. - int x; + +wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) +{ + int idx; wxPoint* temp; PyObject *o, *o1, *o2; bool isFast = PyList_Check(source) || PyTuple_Check(source); @@ -2108,13 +2144,13 @@ wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) { PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array"); return NULL; } - for (x=0; x<*count; x++) { + for (idx=0; idx<*count; idx++) { // Get an item: try fast way first. if (isFast) { - o = PySequence_Fast_GET_ITEM(source, x); + o = PySequence_Fast_GET_ITEM(source, idx); } else { - o = PySequence_GetItem(source, x); + o = PySequence_GetItem(source, idx); if (o == NULL) { goto error1; } @@ -2125,7 +2161,7 @@ wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) { (PyList_Check(o) && PyList_GET_SIZE(o) == 2)) { o1 = PySequence_Fast_GET_ITEM(o, 0); o2 = PySequence_Fast_GET_ITEM(o, 1); - if (!wxPointFromObjects(o1, o2, &temp[x])) { + if (!wxPointFromObjects(o1, o2, &temp[idx])) { goto error2; } } @@ -2134,12 +2170,12 @@ wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) { if (! wxPyConvertSwigPtr(o, (void **)&pt, wxT("wxPoint"))) { goto error2; } - temp[x] = *pt; + temp[idx] = *pt; } else if (PySequence_Check(o) && PySequence_Length(o) == 2) { o1 = PySequence_GetItem(o, 0); o2 = PySequence_GetItem(o, 1); - if (!wxPointFromObjects(o1, o2, &temp[x])) { + if (!wxPointFromObjects(o1, o2, &temp[idx])) { goto error3; } Py_DECREF(o1); @@ -2166,8 +2202,91 @@ error0: PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoints."); return NULL; } -// end of patch -//------------------------------ + + + +wxPoint2D* wxPoint2D_LIST_helper(PyObject* source, size_t *count) +{ + size_t idx; + wxPoint2D* temp; + PyObject *o, *o1, *o2; + bool isFast = PyList_Check(source) || PyTuple_Check(source); + + if (!PySequence_Check(source)) { + goto error0; + } + + // The length of the sequence is returned in count. + *count = PySequence_Length(source); + if (*count < 0) { + goto error0; + } + + temp = new wxPoint2D[*count]; + if (!temp) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array"); + return NULL; + } + for (idx=0; idx<*count; idx++) { + // Get an item: try fast way first. + if (isFast) { + o = PySequence_Fast_GET_ITEM(source, idx); + } + else { + o = PySequence_GetItem(source, idx); + if (o == NULL) { + goto error1; + } + } + + // Convert o to wxPoint. + if ((PyTuple_Check(o) && PyTuple_GET_SIZE(o) == 2) || + (PyList_Check(o) && PyList_GET_SIZE(o) == 2)) { + o1 = PySequence_Fast_GET_ITEM(o, 0); + o2 = PySequence_Fast_GET_ITEM(o, 1); + if (!wxPoint2DFromObjects(o1, o2, &temp[idx])) { + goto error2; + } + } + else if (wxPySwigInstance_Check(o)) { + wxPoint2D* pt; + if (! wxPyConvertSwigPtr(o, (void **)&pt, wxT("wxPoint2D"))) { + goto error2; + } + temp[idx] = *pt; + } + else if (PySequence_Check(o) && PySequence_Length(o) == 2) { + o1 = PySequence_GetItem(o, 0); + o2 = PySequence_GetItem(o, 1); + if (!wxPoint2DFromObjects(o1, o2, &temp[idx])) { + goto error3; + } + Py_DECREF(o1); + Py_DECREF(o2); + } + else { + goto error2; + } + // Clean up. + if (!isFast) + Py_DECREF(o); + } + return temp; + +error3: + Py_DECREF(o1); + Py_DECREF(o2); +error2: + if (!isFast) + Py_DECREF(o); +error1: + delete [] temp; +error0: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoint2Ds."); + return NULL; +} + +//--------------------------------------------------------------------------- wxBitmap** wxBitmap_LIST_helper(PyObject* source) { @@ -2612,8 +2731,8 @@ bool wxPoint2D_helper(PyObject* source, wxPoint2D** obj) { //---------------------------------------------------------------------- -PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) { - +PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) +{ PyObject* list = PyList_New(0); for (size_t i=0; i < arr.GetCount(); i++) { #if wxUSE_UNICODE @@ -2628,8 +2747,8 @@ PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) { } -PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) { - +PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) +{ PyObject* list = PyList_New(0); for (size_t i=0; i < arr.GetCount(); i++) { PyObject* number = PyInt_FromLong(arr[i]); @@ -2640,6 +2759,18 @@ PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) { } +PyObject* wxArrayDouble2PyList_helper(const wxArrayDouble& arr) +{ + PyObject* list = PyList_New(0); + for (size_t i=0; i < arr.GetCount(); i++) { + PyObject* number = PyFloat_FromDouble(arr[i]); + PyList_Append(list, number); + Py_DECREF(number); + } + return list; +} + + //---------------------------------------------------------------------- // wxPyImageHandler methods // diff --git a/wxPython/src/my_typemaps.i b/wxPython/src/my_typemaps.i index 70cca8ce18..8a96849e48 100644 --- a/wxPython/src/my_typemaps.i +++ b/wxPython/src/my_typemaps.i @@ -243,24 +243,42 @@ MAKE_INT_ARRAY_TYPEMAPS(styles, styles_field) //--------------------------------------------------------------------------- // Typemaps to convert an array of ints to a list for return values +// %typemap(out) wxArrayInt& { +// $result = PyList_New(0); +// size_t idx; +// for (idx = 0; idx < $1->GetCount(); idx += 1) { +// PyObject* val = PyInt_FromLong( $1->Item(idx) ); +// PyList_Append($result, val); +// Py_DECREF(val); +// } +// } + +// %typemap(out) wxArrayInt { +// $result = PyList_New(0); +// size_t idx; +// for (idx = 0; idx < $1.GetCount(); idx += 1) { +// PyObject* val = PyInt_FromLong( $1.Item(idx) ); +// PyList_Append($result, val); +// Py_DECREF(val); +// } +// } + %typemap(out) wxArrayInt& { - $result = PyList_New(0); - size_t idx; - for (idx = 0; idx < $1->GetCount(); idx += 1) { - PyObject* val = PyInt_FromLong( $1->Item(idx) ); - PyList_Append($result, val); - Py_DECREF(val); - } + $result = wxArrayInt2PyList_helper(*$1); } %typemap(out) wxArrayInt { - $result = PyList_New(0); - size_t idx; - for (idx = 0; idx < $1.GetCount(); idx += 1) { - PyObject* val = PyInt_FromLong( $1.Item(idx) ); - PyList_Append($result, val); - Py_DECREF(val); - } + $result = wxArrayInt2PyList_helper($1); +} + + +// convert array of doubles to a Python list +%typemap(out) wxArrayDouble& { + $result = wxArrayDouble2PyList_helper(*$1); +} + +%typemap(out) wxArrayDouble { + $result = wxArrayDouble2PyList_helper($1); } -- 2.45.2