///////////////////////////////////////////////////////////////////////////// // Name: drawlist.cpp // Purpose: Helper functions for optimized list drawing on a wxDC // // Author: Robin Dunn Chris Barker // // Created: // RCS-ID: $Id$ // Copyright: (c) 2003 by Total Control Software // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #undef DEBUG #include #include "helpers.h" //---------------------------------------------------------------------- PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw, PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) { wxPyBeginBlockThreads(); // _DrawXXXList bool isFastSeq = PyList_Check(pyCoords) || PyTuple_Check(pyCoords); bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens); bool isFastBrushes = PyList_Check(pyBrushes) || PyTuple_Check(pyBrushes); int numObjs = 0; int numPens = 0; int numBrushes = 0; wxPen* pen; wxBrush* brush; PyObject* obj; PyObject* coords; int i = 0; PyObject* retval; if (!PySequence_Check(pyCoords)) { goto err0; } if (!PySequence_Check(pyPens)) { goto err1; } if (!PySequence_Check(pyBrushes)) { goto err2; } numObjs = PySequence_Length(pyCoords); numPens = PySequence_Length(pyPens); numBrushes = PySequence_Length(pyBrushes); for (i = 0; i < numObjs; i++) { // Use a new pen? if (i < numPens) { if (isFastPens) { obj = PySequence_Fast_GET_ITEM(pyPens, i); } else { obj = PySequence_GetItem(pyPens, i); } if (SWIG_GetPtrObj(obj, (void **) &pen, "_wxPen_p")) { if (!isFastPens) Py_DECREF(obj); goto err1; } dc.SetPen(*pen); if (!isFastPens) Py_DECREF(obj); } // Use a new brush? if (i < numBrushes) { if (isFastBrushes) { obj = PySequence_Fast_GET_ITEM(pyBrushes, i); } else { obj = PySequence_GetItem(pyBrushes, i); } if (SWIG_GetPtrObj(obj, (void **) &brush, "_wxBrush_p")) { if (!isFastBrushes) Py_DECREF(obj); goto err2; } dc.SetBrush(*brush); if (!isFastBrushes) Py_DECREF(obj); } // Get the Coordinates if (isFastSeq) { coords = PySequence_Fast_GET_ITEM(pyCoords, i); } else { coords = PySequence_GetItem(pyCoords, i); } // call the drawOp bool success = doDraw(dc, coords); if (!isFastSeq) Py_DECREF(coords); if (! success) { retval = NULL; goto exit; } } // end of main for loop Py_INCREF(Py_None); retval = Py_None; goto exit; err0: PyErr_SetString(PyExc_TypeError, "Expected a sequence of coordinates"); retval = NULL; goto exit; err1: PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens"); retval = NULL; goto exit; err2: PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxBrushes"); retval = NULL; goto exit; exit: wxPyEndBlockThreads(); return retval; } bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords) { int x, y; if (! wxPy2int_seq_helper(coords, &x, &y)) { PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); return FALSE; } dc.DrawPoint(x, y); return TRUE; } bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords) { int x1, y1, x2, y2; if (! wxPy4int_seq_helper(coords, &x1, &y1, &x2, &y2)) { PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x1,y2) sequences."); return FALSE; } dc.DrawLine(x1,y1, x2,y2); return TRUE; } bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords) { int x, y, w, h; if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); return FALSE; } dc.DrawRectangle(x, y, w, h); return TRUE; } bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords) { int x, y, w, h; if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); return FALSE; } dc.DrawEllipse(x, y, w, h); return TRUE; } bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords) { wxPoint* points; int numPoints; points = wxPoint_LIST_helper(coords, &numPoints); if (! points) { PyErr_SetString(PyExc_TypeError, "Expected a sequence of sequences of (x,y) sequences."); return FALSE; } dc.DrawPolygon(numPoints, points); return TRUE; } //---------------------------------------------------------------------- PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList) { wxPyBeginBlockThreads(); bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints); bool isFastText = PyList_Check(textList) || PyTuple_Check(textList); bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList); bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList); int numText = 0; int numPoints = 0; int numForeground = 0; int numBackground = 0; PyObject* obj; int x1, y1; int i = 0; wxColor* color; PyObject* retval; wxString string; if (!PySequence_Check(pyPoints)) { goto err0; } if (!PySequence_Check(textList)) { goto err1; } if (!PySequence_Check(foregroundList)) { goto err2; } if (!PySequence_Check(backgroundList)) { goto err3; } numPoints = PySequence_Length(pyPoints); numText = PySequence_Length(textList); numForeground = PySequence_Length(foregroundList); numBackground = PySequence_Length(backgroundList); for (i = 0; i < numPoints; i++) { // Use a new string ? if (i < numText) { if ( isFastText ) { obj = PySequence_Fast_GET_ITEM(textList, i); } else { obj = PySequence_GetItem(textList, i); } if (! PyString_Check(obj) ) { Py_DECREF(obj); goto err1; } string = Py2wxString(obj); if ( !isFastText ) Py_DECREF(obj); } if (i < numForeground) { // Use a new foreground ? if ( isFastForeground ) { obj = PySequence_Fast_GET_ITEM(foregroundList, i); } else { obj = PySequence_GetItem(foregroundList, i); } if (SWIG_GetPtrObj(obj, (void **) &color, "_wxColour_p")) { if (!isFastForeground) Py_DECREF(obj); goto err2; } dc.SetTextForeground(*color); if ( !isFastForeground ) Py_DECREF(obj); } if (i < numBackground) { // Use a new background ? if ( isFastBackground ) { obj = PySequence_Fast_GET_ITEM(backgroundList, i); } else { obj = PySequence_GetItem(backgroundList, i); } if (SWIG_GetPtrObj(obj, (void **) &color, "_wxColour_p")) { if (!isFastBackground) Py_DECREF(obj); goto err3; } dc.SetTextBackground(*color); if ( !isFastBackground ) Py_DECREF(obj); } // Get the point coordinates if (isFastSeq) { obj = PySequence_Fast_GET_ITEM(pyPoints, i); } else { obj = PySequence_GetItem(pyPoints, i); } if (! wxPy2int_seq_helper(obj, &x1, &y1)) { if (! isFastSeq) Py_DECREF(obj); goto err0; } if (PyErr_Occurred()) { retval = NULL; if (!isFastSeq) Py_DECREF(obj); goto exit; } // Now draw the text dc.DrawText(string, x1, y1); if (!isFastText) Py_DECREF(obj); } Py_INCREF(Py_None); retval = Py_None; goto exit; err0: PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); retval = NULL; goto exit; err1: PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings"); retval = NULL; goto exit; err2: PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds"); retval = NULL; goto exit; err3: PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds"); retval = NULL; goto exit; exit: wxPyEndBlockThreads(); return retval; } //----------------------------------------------------------------------