]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/drawlist.cpp
moving and slightly extending the comment on CGState
[wxWidgets.git] / wxPython / src / drawlist.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: drawlist.cpp
3 // Purpose: Helper functions for optimized list drawing on a wxDC
4 //
5 // Author: Robin Dunn, Chris Barker
6 //
7 // Created:
8 // RCS-ID: $Id$
9 // Copyright: (c) 2003 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13
14 #undef DEBUG
15 #include <Python.h>
16 #include "wx/wxPython/wxPython.h"
17 #include "wx/wxPython/pydrawxxx.h"
18
19
20 //---------------------------------------------------------------------------
21
22
23 // Called from _gdiinit so we can do the API import while the GIL is held
24 void wxPyDrawList_SetAPIPtr()
25 {
26 wxPyCoreAPI_IMPORT();
27 }
28
29
30 PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw,
31 PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)
32 {
33 wxPyBlock_t blocked = wxPyBeginBlockThreads();
34
35 bool isFastSeq = PyList_Check(pyCoords) || PyTuple_Check(pyCoords);
36 bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens);
37 bool isFastBrushes = PyList_Check(pyBrushes) || PyTuple_Check(pyBrushes);
38 int numObjs = 0;
39 int numPens = 0;
40 int numBrushes = 0;
41 wxPen* pen;
42 wxBrush* brush;
43 PyObject* obj;
44 PyObject* coords;
45 int i = 0;
46 PyObject* retval;
47
48 if (!PySequence_Check(pyCoords)) {
49 goto err0;
50 }
51 if (!PySequence_Check(pyPens)) {
52 goto err1;
53 }
54 if (!PySequence_Check(pyBrushes)) {
55 goto err2;
56 }
57 numObjs = PySequence_Length(pyCoords);
58 numPens = PySequence_Length(pyPens);
59 numBrushes = PySequence_Length(pyBrushes);
60 for (i = 0; i < numObjs; i++) {
61 // Use a new pen?
62 if (i < numPens) {
63 if (isFastPens) {
64 obj = PySequence_Fast_GET_ITEM(pyPens, i);
65 }
66 else {
67 obj = PySequence_GetItem(pyPens, i);
68 }
69 if (! wxPyConvertSwigPtr(obj, (void **) &pen, wxT("wxPen"))) {
70 if (!isFastPens)
71 Py_DECREF(obj);
72 goto err1;
73 }
74
75 dc.SetPen(*pen);
76 if (!isFastPens)
77 Py_DECREF(obj);
78 }
79 // Use a new brush?
80 if (i < numBrushes) {
81 if (isFastBrushes) {
82 obj = PySequence_Fast_GET_ITEM(pyBrushes, i);
83 }
84 else {
85 obj = PySequence_GetItem(pyBrushes, i);
86 }
87 if (!wxPyConvertSwigPtr(obj, (void **) &brush, wxT("wxBrush"))) {
88 if (!isFastBrushes)
89 Py_DECREF(obj);
90 goto err2;
91 }
92
93 dc.SetBrush(*brush);
94 if (!isFastBrushes)
95 Py_DECREF(obj);
96 }
97
98 // Get the Coordinates
99 if (isFastSeq) {
100 coords = PySequence_Fast_GET_ITEM(pyCoords, i);
101 }
102 else {
103 coords = PySequence_GetItem(pyCoords, i);
104 }
105
106
107 // call the drawOp
108 bool success = doDraw(dc, coords);
109 if (!isFastSeq)
110 Py_DECREF(coords);
111
112 if (! success) {
113 retval = NULL;
114 goto exit;
115 }
116
117 } // end of main for loop
118
119 Py_INCREF(Py_None);
120 retval = Py_None;
121 goto exit;
122
123
124 err0:
125 PyErr_SetString(PyExc_TypeError, "Expected a sequence of coordinates");
126 retval = NULL;
127 goto exit;
128
129 err1:
130 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens");
131 retval = NULL;
132 goto exit;
133
134 err2:
135 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxBrushes");
136 retval = NULL;
137 goto exit;
138
139
140 exit:
141 wxPyEndBlockThreads(blocked);
142 return retval;
143 }
144
145
146
147 bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords)
148 {
149 int x, y;
150
151 if (! wxPy2int_seq_helper(coords, &x, &y)) {
152 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences.");
153 return false;
154 }
155 dc.DrawPoint(x, y);
156 return true;
157 }
158
159 bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords)
160 {
161 int x1, y1, x2, y2;
162
163 if (! wxPy4int_seq_helper(coords, &x1, &y1, &x2, &y2)) {
164 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x1,y2) sequences.");
165 return false;
166 }
167 dc.DrawLine(x1,y1, x2,y2);
168 return true;
169 }
170
171 bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords)
172 {
173 int x, y, w, h;
174
175 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) {
176 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences.");
177 return false;
178 }
179 dc.DrawRectangle(x, y, w, h);
180 return true;
181 }
182
183 bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords)
184 {
185 int x, y, w, h;
186
187 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) {
188 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences.");
189 return false;
190 }
191 dc.DrawEllipse(x, y, w, h);
192 return true;
193 }
194
195
196 bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords)
197 {
198 wxPoint* points;
199 int numPoints;
200
201 points = wxPoint_LIST_helper(coords, &numPoints);
202 if (! points) {
203 PyErr_SetString(PyExc_TypeError, "Expected a sequence of sequences of (x,y) sequences.");
204 return false;
205 }
206 dc.DrawPolygon(numPoints, points);
207 delete [] points;
208 return true;
209 }
210
211
212 //---------------------------------------------------------------------------
213
214
215
216 PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)
217 {
218 wxPyBlock_t blocked = wxPyBeginBlockThreads();
219
220 bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints);
221 bool isFastText = PyList_Check(textList) || PyTuple_Check(textList);
222 bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList);
223 bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList);
224 int numText = 0;
225 int numPoints = 0;
226 int numForeground = 0;
227 int numBackground = 0;
228 PyObject* obj;
229 int x1, y1;
230 int i = 0;
231 wxColor* color;
232 PyObject* retval;
233 wxString string;
234
235 if (!PySequence_Check(pyPoints)) {
236 goto err0;
237 }
238 if (!PySequence_Check(textList)) {
239 goto err1;
240 }
241 if (!PySequence_Check(foregroundList)) {
242 goto err2;
243 }
244 if (!PySequence_Check(backgroundList)) {
245 goto err3;
246 }
247 numPoints = PySequence_Length(pyPoints);
248 numText = PySequence_Length(textList);
249 numForeground = PySequence_Length(foregroundList);
250 numBackground = PySequence_Length(backgroundList);
251
252 for (i = 0; i < numPoints; i++) {
253 // Use a new string ?
254 if (i < numText) {
255 if ( isFastText ) {
256 obj = PySequence_Fast_GET_ITEM(textList, i);
257 }
258 else {
259 obj = PySequence_GetItem(textList, i);
260 }
261 if (! PyString_Check(obj) && !PyUnicode_Check(obj) ) {
262 Py_DECREF(obj);
263 goto err1;
264 }
265 string = Py2wxString(obj);
266 if ( !isFastText )
267 Py_DECREF(obj);
268 }
269
270 if (i < numForeground) {
271 // Use a new foreground ?
272 if ( isFastForeground ) {
273 obj = PySequence_Fast_GET_ITEM(foregroundList, i);
274 }
275 else {
276 obj = PySequence_GetItem(foregroundList, i);
277 }
278 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
279 if (!isFastForeground)
280 Py_DECREF(obj);
281 goto err2;
282 }
283 dc.SetTextForeground(*color);
284 if ( !isFastForeground )
285 Py_DECREF(obj);
286 }
287
288 if (i < numBackground) {
289 // Use a new background ?
290 if ( isFastBackground ) {
291 obj = PySequence_Fast_GET_ITEM(backgroundList, i);
292 }
293 else {
294 obj = PySequence_GetItem(backgroundList, i);
295 }
296 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
297 if (!isFastBackground)
298 Py_DECREF(obj);
299 goto err3;
300 }
301 dc.SetTextBackground(*color);
302 if ( !isFastBackground )
303 Py_DECREF(obj);
304 }
305
306 // Get the point coordinates
307 if (isFastSeq) {
308 obj = PySequence_Fast_GET_ITEM(pyPoints, i);
309 }
310 else {
311 obj = PySequence_GetItem(pyPoints, i);
312 }
313 if (! wxPy2int_seq_helper(obj, &x1, &y1)) {
314 if (! isFastSeq)
315 Py_DECREF(obj);
316 goto err0;
317 }
318 if (PyErr_Occurred()) {
319 retval = NULL;
320 if (!isFastSeq)
321 Py_DECREF(obj);
322 goto exit;
323 }
324
325
326 // Now draw the text
327 dc.DrawText(string, x1, y1);
328
329 if (!isFastText)
330 Py_DECREF(obj);
331 }
332
333 Py_INCREF(Py_None);
334 retval = Py_None;
335 goto exit;
336
337 err0:
338 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences.");
339 retval = NULL;
340 goto exit;
341 err1:
342 PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings");
343 retval = NULL;
344 goto exit;
345
346 err2:
347 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds");
348 retval = NULL;
349 goto exit;
350
351 err3:
352 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds");
353 retval = NULL;
354 goto exit;
355
356 exit:
357 wxPyEndBlockThreads(blocked);
358 return retval;
359 }
360
361
362
363 //---------------------------------------------------------------------------