$search
00001 00002 // Name: drawlist.cpp 00003 // Purpose: Helper functions for optimized list drawing on a wxDC 00004 // 00005 // Author: Robin Dunn, Chris Barker 00006 // 00007 // Created: 00008 // RCS-ID: $Id: drawlist.cpp,v 1.12 2005/03/09 22:28:40 RD Exp $ 00009 // Copyright: (c) 2003 by Total Control Software 00010 // Licence: wxWindows license 00012 00013 00014 #undef DEBUG 00015 #include <Python.h> 00016 #include "wx/wxPython/wxPython.h" 00017 #include "wx/wxPython/pydrawxxx.h" 00018 00019 00020 //--------------------------------------------------------------------------- 00021 00022 00023 // Called from _gdiinit so we can do the API import while the GIL is held 00024 void wxPyDrawList_SetAPIPtr() 00025 { 00026 wxPyCoreAPI_IMPORT(); 00027 } 00028 00029 00030 PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw, 00031 PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) 00032 { 00033 wxPyBlock_t blocked = wxPyBeginBlockThreads(); 00034 00035 bool isFastSeq = PyList_Check(pyCoords) || PyTuple_Check(pyCoords); 00036 bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens); 00037 bool isFastBrushes = PyList_Check(pyBrushes) || PyTuple_Check(pyBrushes); 00038 int numObjs = 0; 00039 int numPens = 0; 00040 int numBrushes = 0; 00041 wxPen* pen; 00042 wxBrush* brush; 00043 PyObject* obj; 00044 PyObject* coords; 00045 int i = 0; 00046 PyObject* retval; 00047 00048 if (!PySequence_Check(pyCoords)) { 00049 goto err0; 00050 } 00051 if (!PySequence_Check(pyPens)) { 00052 goto err1; 00053 } 00054 if (!PySequence_Check(pyBrushes)) { 00055 goto err2; 00056 } 00057 numObjs = PySequence_Length(pyCoords); 00058 numPens = PySequence_Length(pyPens); 00059 numBrushes = PySequence_Length(pyBrushes); 00060 for (i = 0; i < numObjs; i++) { 00061 // Use a new pen? 00062 if (i < numPens) { 00063 if (isFastPens) { 00064 obj = PySequence_Fast_GET_ITEM(pyPens, i); 00065 } 00066 else { 00067 obj = PySequence_GetItem(pyPens, i); 00068 } 00069 if (! wxPyConvertSwigPtr(obj, (void **) &pen, wxT("wxPen"))) { 00070 if (!isFastPens) 00071 Py_DECREF(obj); 00072 goto err1; 00073 } 00074 00075 dc.SetPen(*pen); 00076 if (!isFastPens) 00077 Py_DECREF(obj); 00078 } 00079 // Use a new brush? 00080 if (i < numBrushes) { 00081 if (isFastBrushes) { 00082 obj = PySequence_Fast_GET_ITEM(pyBrushes, i); 00083 } 00084 else { 00085 obj = PySequence_GetItem(pyBrushes, i); 00086 } 00087 if (!wxPyConvertSwigPtr(obj, (void **) &brush, wxT("wxBrush"))) { 00088 if (!isFastBrushes) 00089 Py_DECREF(obj); 00090 goto err2; 00091 } 00092 00093 dc.SetBrush(*brush); 00094 if (!isFastBrushes) 00095 Py_DECREF(obj); 00096 } 00097 00098 // Get the Coordinates 00099 if (isFastSeq) { 00100 coords = PySequence_Fast_GET_ITEM(pyCoords, i); 00101 } 00102 else { 00103 coords = PySequence_GetItem(pyCoords, i); 00104 } 00105 00106 00107 // call the drawOp 00108 bool success = doDraw(dc, coords); 00109 if (!isFastSeq) 00110 Py_DECREF(coords); 00111 00112 if (! success) { 00113 retval = NULL; 00114 goto exit; 00115 } 00116 00117 } // end of main for loop 00118 00119 Py_INCREF(Py_None); 00120 retval = Py_None; 00121 goto exit; 00122 00123 00124 err0: 00125 PyErr_SetString(PyExc_TypeError, "Expected a sequence of coordinates"); 00126 retval = NULL; 00127 goto exit; 00128 00129 err1: 00130 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens"); 00131 retval = NULL; 00132 goto exit; 00133 00134 err2: 00135 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxBrushes"); 00136 retval = NULL; 00137 goto exit; 00138 00139 00140 exit: 00141 wxPyEndBlockThreads(blocked); 00142 return retval; 00143 } 00144 00145 00146 00147 bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords) 00148 { 00149 int x, y; 00150 00151 if (! wxPy2int_seq_helper(coords, &x, &y)) { 00152 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); 00153 return false; 00154 } 00155 dc.DrawPoint(x, y); 00156 return true; 00157 } 00158 00159 bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords) 00160 { 00161 int x1, y1, x2, y2; 00162 00163 if (! wxPy4int_seq_helper(coords, &x1, &y1, &x2, &y2)) { 00164 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x1,y2) sequences."); 00165 return false; 00166 } 00167 dc.DrawLine(x1,y1, x2,y2); 00168 return true; 00169 } 00170 00171 bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords) 00172 { 00173 int x, y, w, h; 00174 00175 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { 00176 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); 00177 return false; 00178 } 00179 dc.DrawRectangle(x, y, w, h); 00180 return true; 00181 } 00182 00183 bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords) 00184 { 00185 int x, y, w, h; 00186 00187 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { 00188 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); 00189 return false; 00190 } 00191 dc.DrawEllipse(x, y, w, h); 00192 return true; 00193 } 00194 00195 00196 bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords) 00197 { 00198 wxPoint* points; 00199 int numPoints; 00200 00201 points = wxPoint_LIST_helper(coords, &numPoints); 00202 if (! points) { 00203 PyErr_SetString(PyExc_TypeError, "Expected a sequence of sequences of (x,y) sequences."); 00204 return false; 00205 } 00206 dc.DrawPolygon(numPoints, points); 00207 delete [] points; 00208 return true; 00209 } 00210 00211 00212 //--------------------------------------------------------------------------- 00213 00214 00215 00216 PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList) 00217 { 00218 wxPyBlock_t blocked = wxPyBeginBlockThreads(); 00219 00220 bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints); 00221 bool isFastText = PyList_Check(textList) || PyTuple_Check(textList); 00222 bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList); 00223 bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList); 00224 int numText = 0; 00225 int numPoints = 0; 00226 int numForeground = 0; 00227 int numBackground = 0; 00228 PyObject* obj; 00229 int x1, y1; 00230 int i = 0; 00231 wxColor* color; 00232 PyObject* retval; 00233 wxString string; 00234 00235 if (!PySequence_Check(pyPoints)) { 00236 goto err0; 00237 } 00238 if (!PySequence_Check(textList)) { 00239 goto err1; 00240 } 00241 if (!PySequence_Check(foregroundList)) { 00242 goto err2; 00243 } 00244 if (!PySequence_Check(backgroundList)) { 00245 goto err3; 00246 } 00247 numPoints = PySequence_Length(pyPoints); 00248 numText = PySequence_Length(textList); 00249 numForeground = PySequence_Length(foregroundList); 00250 numBackground = PySequence_Length(backgroundList); 00251 00252 for (i = 0; i < numPoints; i++) { 00253 // Use a new string ? 00254 if (i < numText) { 00255 if ( isFastText ) { 00256 obj = PySequence_Fast_GET_ITEM(textList, i); 00257 } 00258 else { 00259 obj = PySequence_GetItem(textList, i); 00260 } 00261 if (! PyString_Check(obj) && !PyUnicode_Check(obj) ) { 00262 Py_DECREF(obj); 00263 goto err1; 00264 } 00265 string = Py2wxString(obj); 00266 if ( !isFastText ) 00267 Py_DECREF(obj); 00268 } 00269 00270 if (i < numForeground) { 00271 // Use a new foreground ? 00272 if ( isFastForeground ) { 00273 obj = PySequence_Fast_GET_ITEM(foregroundList, i); 00274 } 00275 else { 00276 obj = PySequence_GetItem(foregroundList, i); 00277 } 00278 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) { 00279 if (!isFastForeground) 00280 Py_DECREF(obj); 00281 goto err2; 00282 } 00283 dc.SetTextForeground(*color); 00284 if ( !isFastForeground ) 00285 Py_DECREF(obj); 00286 } 00287 00288 if (i < numBackground) { 00289 // Use a new background ? 00290 if ( isFastBackground ) { 00291 obj = PySequence_Fast_GET_ITEM(backgroundList, i); 00292 } 00293 else { 00294 obj = PySequence_GetItem(backgroundList, i); 00295 } 00296 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) { 00297 if (!isFastBackground) 00298 Py_DECREF(obj); 00299 goto err3; 00300 } 00301 dc.SetTextBackground(*color); 00302 if ( !isFastBackground ) 00303 Py_DECREF(obj); 00304 } 00305 00306 // Get the point coordinates 00307 if (isFastSeq) { 00308 obj = PySequence_Fast_GET_ITEM(pyPoints, i); 00309 } 00310 else { 00311 obj = PySequence_GetItem(pyPoints, i); 00312 } 00313 if (! wxPy2int_seq_helper(obj, &x1, &y1)) { 00314 if (! isFastSeq) 00315 Py_DECREF(obj); 00316 goto err0; 00317 } 00318 if (PyErr_Occurred()) { 00319 retval = NULL; 00320 if (!isFastSeq) 00321 Py_DECREF(obj); 00322 goto exit; 00323 } 00324 00325 00326 // Now draw the text 00327 dc.DrawText(string, x1, y1); 00328 00329 if (!isFastText) 00330 Py_DECREF(obj); 00331 } 00332 00333 Py_INCREF(Py_None); 00334 retval = Py_None; 00335 goto exit; 00336 00337 err0: 00338 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); 00339 retval = NULL; 00340 goto exit; 00341 err1: 00342 PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings"); 00343 retval = NULL; 00344 goto exit; 00345 00346 err2: 00347 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds"); 00348 retval = NULL; 00349 goto exit; 00350 00351 err3: 00352 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds"); 00353 retval = NULL; 00354 goto exit; 00355 00356 exit: 00357 wxPyEndBlockThreads(blocked); 00358 return retval; 00359 } 00360 00361 00362 00363 //---------------------------------------------------------------------------