]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: common/pseudodc.cpp | |
3 | // Purpose: Implementation of the wxPseudoDC Class | |
4 | // Author: Paul Lanier | |
5 | // Modified by: | |
6 | // Created: 05/25/06 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) wxWidgets team | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // For compilers that support precompilation, includes "wx.h". | |
13 | //include "wx/wxprec.h" | |
14 | ||
15 | #undef DEBUG | |
16 | #include <Python.h> | |
17 | #include "wx/wxPython/wxPython.h" | |
18 | #include "wx/wxPython/pseudodc.h" | |
19 | ||
20 | // wxList based class definitions | |
21 | #include <wx/listimpl.cpp> | |
22 | WX_DEFINE_LIST(pdcOpList); | |
23 | WX_DEFINE_LIST(pdcObjectList); | |
24 | ||
25 | //---------------------------------------------------------------------------- | |
26 | // Helper functions used for drawing greyed out versions of objects | |
27 | //---------------------------------------------------------------------------- | |
28 | wxColour &MakeColourGrey(const wxColour &c) | |
29 | { | |
30 | static wxColour rval; | |
31 | rval.Set(byte((230-c.Red())*0.7+c.Red()), | |
32 | byte((230-c.Green())*0.7+c.Green()), | |
33 | byte((230-c.Blue())*0.7+c.Blue())); | |
34 | return rval; | |
35 | } | |
36 | wxBrush &GetGreyBrush(wxBrush &brush) | |
37 | { | |
38 | static wxBrush b; | |
39 | wxColour c; | |
40 | b = brush; | |
41 | c = MakeColourGrey(brush.GetColour()); | |
42 | b.SetColour(c); | |
43 | return b; | |
44 | } | |
45 | ||
46 | wxPen &GetGreyPen(wxPen &pen) | |
47 | { | |
48 | static wxPen p; | |
49 | wxColour c; | |
50 | p = pen; | |
51 | c = MakeColourGrey(pen.GetColour()); | |
52 | p.SetColour(c); | |
53 | return p; | |
54 | } | |
55 | ||
56 | void GreyOutImage(wxImage &img) | |
57 | { | |
58 | unsigned char *data = img.GetData(); | |
59 | unsigned char r,g,b; | |
60 | unsigned char mr,mg,mb; | |
61 | int i, tst; | |
62 | int len = img.GetHeight()*img.GetWidth()*3; | |
63 | if (img.HasMask()) | |
64 | { | |
65 | mr = img.GetMaskRed(); | |
66 | mg = img.GetMaskGreen(); | |
67 | mb = img.GetMaskBlue(); | |
68 | } | |
69 | tst=0; | |
70 | for (i=0;i<len;i+=3) | |
71 | { | |
72 | r=data[i]; g=data[i+1]; b=data[i+2]; | |
73 | if (!img.HasMask() || | |
74 | r!=mr || g!=mg || b!=mb) | |
75 | { | |
76 | if (!tst) | |
77 | { | |
78 | tst=1; | |
79 | } | |
80 | r = (unsigned char)((230.0-r)*0.7+r); | |
81 | g = (unsigned char)((230.0-g)*0.7+g); | |
82 | b = (unsigned char)((230.0-b)*0.7+b); | |
83 | data[i]=r; data[i+1]=g; data[i+2]=b; | |
84 | } | |
85 | } | |
86 | } | |
87 | ||
88 | wxIcon &GetGreyIcon(wxIcon &icon) | |
89 | { | |
90 | wxBitmap bmp; | |
91 | bmp.CopyFromIcon(icon); | |
92 | wxImage img = bmp.ConvertToImage(); | |
93 | GreyOutImage(img); | |
94 | wxBitmap bmp2(img,32); | |
95 | static wxIcon rval; | |
96 | rval.CopyFromBitmap(bmp2); | |
97 | return rval; | |
98 | } | |
99 | ||
100 | wxBitmap &GetGreyBitmap(wxBitmap &bmp) | |
101 | { | |
102 | wxImage img = bmp.ConvertToImage(); | |
103 | GreyOutImage(img); | |
104 | static wxBitmap rval(img,32); | |
105 | return rval; | |
106 | } | |
107 | ||
108 | // ============================================================================ | |
109 | // various pdcOp class implementation methods | |
110 | // ============================================================================ | |
111 | ||
112 | // ---------------------------------------------------------------------------- | |
113 | // pdcDrawPolyPolygonOp constructor | |
114 | // ---------------------------------------------------------------------------- | |
115 | pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[], | |
116 | wxCoord xoffset, wxCoord yoffset, int fillStyle) | |
117 | { | |
118 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle; | |
119 | int total_n=0; | |
120 | if (n) | |
121 | { | |
122 | m_count = new int[n]; | |
123 | for(int i=0; i<n; i++) | |
124 | { | |
125 | total_n+=count[i]; | |
126 | m_count[i]=count[i]; | |
127 | } | |
128 | if (total_n) | |
129 | { | |
130 | m_points = new wxPoint[total_n]; | |
131 | for(int j=0; j<total_n; j++) | |
132 | m_points[j] = points[j]; | |
133 | } | |
134 | else m_points=NULL; | |
135 | } | |
136 | else | |
137 | { | |
138 | m_points=NULL; | |
139 | m_count=NULL; | |
140 | } | |
141 | m_totaln = total_n; | |
142 | } | |
143 | ||
144 | // ---------------------------------------------------------------------------- | |
145 | // pdcDrawPolyPolygonOp destructor | |
146 | // ---------------------------------------------------------------------------- | |
147 | pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp() | |
148 | { | |
149 | if (m_points) delete m_points; | |
150 | if (m_count) delete m_count; | |
151 | m_points=NULL; | |
152 | m_count=NULL; | |
153 | } | |
154 | ||
155 | // ---------------------------------------------------------------------------- | |
156 | // pdcDrawLinesOp constructor | |
157 | // ---------------------------------------------------------------------------- | |
158 | pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[], | |
159 | wxCoord xoffset, wxCoord yoffset) | |
160 | { | |
161 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; | |
162 | if (n) | |
163 | { | |
164 | m_points = new wxPoint[n]; | |
165 | for (int i=0; i<n; i++) | |
166 | m_points[i] = points[i]; | |
167 | } | |
168 | else m_points=NULL; | |
169 | } | |
170 | ||
171 | // ---------------------------------------------------------------------------- | |
172 | // pdcDrawLinesOp destructor | |
173 | // ---------------------------------------------------------------------------- | |
174 | pdcDrawLinesOp::~pdcDrawLinesOp() | |
175 | { | |
176 | if (m_points) delete m_points; | |
177 | m_points=NULL; | |
178 | } | |
179 | ||
180 | // ---------------------------------------------------------------------------- | |
181 | // pdcDrawPolygonOp constructor | |
182 | // ---------------------------------------------------------------------------- | |
183 | pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[], | |
184 | wxCoord xoffset, wxCoord yoffset, int fillStyle) | |
185 | { | |
186 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle; | |
187 | if (n) | |
188 | { | |
189 | m_points = new wxPoint[n]; | |
190 | for (int i=0; i<n; i++) | |
191 | m_points[i] = points[i]; | |
192 | } | |
193 | else m_points=NULL; | |
194 | } | |
195 | ||
196 | // ---------------------------------------------------------------------------- | |
197 | // pdcDrawPolygonOp destructor | |
198 | // ---------------------------------------------------------------------------- | |
199 | pdcDrawPolygonOp::~pdcDrawPolygonOp() | |
200 | { | |
201 | if (m_points) delete m_points; | |
202 | m_points=NULL; | |
203 | } | |
204 | ||
205 | #if wxUSE_SPLINES | |
206 | // ---------------------------------------------------------------------------- | |
207 | // pdcDrawSplineOp constructor | |
208 | // ---------------------------------------------------------------------------- | |
209 | pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[]) | |
210 | { | |
211 | m_n=n; | |
212 | if (n) | |
213 | { | |
214 | m_points = new wxPoint[n]; | |
215 | for(int i=0; i<n; i++) | |
216 | m_points[i] = points[i]; | |
217 | } | |
218 | else m_points=NULL; | |
219 | } | |
220 | ||
221 | // ---------------------------------------------------------------------------- | |
222 | // pdcDrawSplineOp destructor | |
223 | // ---------------------------------------------------------------------------- | |
224 | pdcDrawSplineOp::~pdcDrawSplineOp() | |
225 | { | |
226 | if (m_points) delete m_points; | |
227 | m_points=NULL; | |
228 | } | |
229 | #endif // wxUSE_SPLINES | |
230 | ||
231 | // ============================================================================ | |
232 | // pdcObject implementation | |
233 | // ============================================================================ | |
234 | // ---------------------------------------------------------------------------- | |
235 | // DrawToDC - play back the op list to the DC | |
236 | // ---------------------------------------------------------------------------- | |
237 | void pdcObject::DrawToDC(wxDC *dc) | |
238 | { | |
239 | pdcOpList::Node *node = m_oplist.GetFirst(); | |
240 | while(node) | |
241 | { | |
242 | node->GetData()->DrawToDC(dc, m_greyedout); | |
243 | node = node->GetNext(); | |
244 | } | |
245 | } | |
246 | ||
247 | // ---------------------------------------------------------------------------- | |
248 | // Translate - translate all the operations by some dx,dy | |
249 | // ---------------------------------------------------------------------------- | |
250 | void pdcObject::Translate(wxCoord dx, wxCoord dy) | |
251 | { | |
252 | pdcOpList::Node *node = m_oplist.GetFirst(); | |
253 | while(node) | |
254 | { | |
255 | node->GetData()->Translate(dx,dy); | |
256 | node = node->GetNext(); | |
257 | } | |
258 | if (m_bounded) | |
259 | { | |
260 | m_bounds.x += dx; | |
261 | m_bounds.y += dy; | |
262 | } | |
263 | } | |
264 | ||
265 | // ---------------------------------------------------------------------------- | |
266 | // SetGreyedOut - set the greyout member and cache grey versions of everything | |
267 | // if greyout is true | |
268 | // ---------------------------------------------------------------------------- | |
269 | void pdcObject::SetGreyedOut(bool greyout) | |
270 | { | |
271 | m_greyedout=greyout; | |
272 | if (greyout) | |
273 | { | |
274 | pdcOpList::Node *node = m_oplist.GetFirst(); | |
275 | pdcOp *obj; | |
276 | while(node) | |
277 | { | |
278 | ||
279 | obj = node->GetData(); | |
280 | obj->CacheGrey(); | |
281 | node = node->GetNext(); | |
282 | } | |
283 | } | |
284 | } | |
285 | ||
286 | // ============================================================================ | |
287 | // wxPseudoDC implementation | |
288 | // ============================================================================ | |
289 | ||
290 | // ---------------------------------------------------------------------------- | |
291 | // Destructor | |
292 | // ---------------------------------------------------------------------------- | |
293 | wxPseudoDC::~wxPseudoDC() | |
294 | { | |
295 | // delete all the nodes in the list | |
296 | RemoveAll(); | |
297 | ||
298 | } | |
299 | ||
300 | // ---------------------------------------------------------------------------- | |
301 | // ClearAll - remove all nodes from list | |
302 | // ---------------------------------------------------------------------------- | |
303 | void wxPseudoDC::RemoveAll(void) | |
304 | { | |
305 | m_objectlist.Clear(); | |
306 | m_currId = -1; | |
307 | m_lastObjNode = NULL; | |
308 | } | |
309 | ||
310 | // ---------------------------------------------------------------------------- | |
311 | // GetLen - return the number of operations in the current op list | |
312 | // ---------------------------------------------------------------------------- | |
313 | int wxPseudoDC::GetLen(void) | |
314 | { | |
315 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
316 | int len=0; | |
317 | while (pt) | |
318 | { | |
319 | len += pt->GetData()->GetLen(); | |
320 | pt = pt->GetNext(); | |
321 | } | |
322 | return len; | |
323 | } | |
324 | ||
325 | // ---------------------------------------------------------------------------- | |
326 | // FindObjNode - find and return an object node by id. If node doesn't exist | |
327 | // and create is true then create one and return it. Otherwise | |
328 | // return NULL. | |
329 | // ---------------------------------------------------------------------------- | |
330 | pdcObjectList::Node *wxPseudoDC::FindObjNode(int id, bool create) | |
331 | { | |
332 | // see if last operation was for same id | |
333 | if (m_lastObjNode && m_lastObjNode->GetData()->GetId() == id) | |
334 | return m_lastObjNode; | |
335 | // if not then search for it | |
336 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
337 | while (pt) | |
338 | { | |
339 | if (pt->GetData()->GetId() == id) | |
340 | { | |
341 | ||
342 | // cache this node for future operations | |
343 | m_lastObjNode = pt; | |
344 | return pt; | |
345 | } | |
346 | pt = pt->GetNext(); | |
347 | } | |
348 | // if create then create and return a new node | |
349 | if (create) | |
350 | { | |
351 | // cache this node for future operations | |
352 | m_lastObjNode = m_objectlist.Append(new pdcObject(id)); | |
353 | return m_lastObjNode; | |
354 | } | |
355 | // otherwise just return NULL | |
356 | return NULL; | |
357 | } | |
358 | ||
359 | // ---------------------------------------------------------------------------- | |
360 | // AddToList - Add a node to the list at the end (preserve draw order) | |
361 | // ---------------------------------------------------------------------------- | |
362 | void wxPseudoDC::AddToList(pdcOp *newOp) | |
363 | { | |
364 | pdcObjectList::Node *pt = FindObjNode(m_currId, true); | |
365 | pt->GetData()->AddOp(newOp); | |
366 | } | |
367 | ||
368 | // ---------------------------------------------------------------------------- | |
369 | // ClearID - remove all the operations associated with a single ID | |
370 | // ---------------------------------------------------------------------------- | |
371 | void wxPseudoDC::ClearId(int id) | |
372 | { | |
373 | pdcObjectList::Node *pt = FindObjNode(id); | |
374 | if (pt) pt->GetData()->Clear(); | |
375 | } | |
376 | ||
377 | // ---------------------------------------------------------------------------- | |
378 | // RemoveID - Remove the object node (and all operations) associated with an id | |
379 | // ---------------------------------------------------------------------------- | |
380 | void wxPseudoDC::RemoveId(int id) | |
381 | { | |
382 | pdcObjectList::Node *pt = FindObjNode(id); | |
383 | if (pt) | |
384 | { | |
385 | if (m_lastObjNode == pt) | |
386 | m_lastObjNode = NULL; | |
387 | m_objectlist.DeleteNode(pt); | |
388 | } | |
389 | } | |
390 | ||
391 | // ---------------------------------------------------------------------------- | |
392 | // SetIdBounds - Set the bounding rect for a given id | |
393 | // ---------------------------------------------------------------------------- | |
394 | void wxPseudoDC::SetIdBounds(int id, wxRect& rect) | |
395 | { | |
396 | pdcObjectList::Node *pt = FindObjNode(id, true); | |
397 | pt->GetData()->SetBounds(rect); | |
398 | } | |
399 | ||
400 | // ---------------------------------------------------------------------------- | |
401 | // GetIdBounds - Get the bounding rect for a given id | |
402 | // ---------------------------------------------------------------------------- | |
403 | void wxPseudoDC::GetIdBounds(int id, wxRect& rect) | |
404 | { | |
405 | pdcObjectList::Node *pt = FindObjNode(id); | |
406 | if (pt && pt->GetData()->IsBounded()) | |
407 | rect = pt->GetData()->GetBounds(); | |
408 | else | |
409 | rect.x = rect.y = rect.width = rect.height = 0; | |
410 | } | |
411 | ||
412 | // ---------------------------------------------------------------------------- | |
413 | // TranslateId - Translate all the operations of a single id | |
414 | // ---------------------------------------------------------------------------- | |
415 | void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy) | |
416 | { | |
417 | pdcObjectList::Node *pt = FindObjNode(id); | |
418 | if (pt) pt->GetData()->Translate(dx,dy); | |
419 | } | |
420 | ||
421 | // ---------------------------------------------------------------------------- | |
422 | // DrawIdToDC - Draw a specific id to the dc passed in | |
423 | // ---------------------------------------------------------------------------- | |
424 | void wxPseudoDC::DrawIdToDC(int id, wxDC *dc) | |
425 | { | |
426 | pdcObjectList::Node *pt = FindObjNode(id); | |
427 | if (pt) pt->GetData()->DrawToDC(dc); | |
428 | } | |
429 | ||
430 | // ---------------------------------------------------------------------------- | |
431 | // SetIdGreyedOut - Set the greyedout member of id | |
432 | // ---------------------------------------------------------------------------- | |
433 | void wxPseudoDC::SetIdGreyedOut(int id, bool greyout) | |
434 | { | |
435 | pdcObjectList::Node *pt = FindObjNode(id); | |
436 | if (pt) pt->GetData()->SetGreyedOut(greyout); | |
437 | } | |
438 | ||
439 | // ---------------------------------------------------------------------------- | |
440 | // GetIdGreyedOut - Get the greyedout member of id | |
441 | // ---------------------------------------------------------------------------- | |
442 | bool wxPseudoDC::GetIdGreyedOut(int id) | |
443 | { | |
444 | pdcObjectList::Node *pt = FindObjNode(id); | |
445 | if (pt) return pt->GetData()->GetGreyedOut(); | |
446 | else return false; | |
447 | } | |
448 | ||
449 | // ---------------------------------------------------------------------------- | |
450 | // FindObjectsByBBox - Return a list of all the ids whose bounding boxes | |
451 | // contain (x,y) | |
452 | // ---------------------------------------------------------------------------- | |
453 | PyObject *wxPseudoDC::FindObjectsByBBox(wxCoord x, wxCoord y) | |
454 | { | |
455 | //wxPyBlock_t blocked = wxPyBeginBlockThreads(); | |
456 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
457 | pdcObject *obj; | |
458 | PyObject* pyList = NULL; | |
459 | pyList = PyList_New(0); | |
460 | wxRect r; | |
461 | while (pt) | |
462 | { | |
463 | obj = pt->GetData(); | |
464 | r = obj->GetBounds(); | |
465 | if (obj->IsBounded() && r.Contains(x,y)) | |
466 | { | |
467 | PyObject* pyObj = PyInt_FromLong((long)obj->GetId()); | |
468 | PyList_Insert(pyList, 0, pyObj); | |
469 | Py_DECREF(pyObj); | |
470 | } | |
471 | pt = pt->GetNext(); | |
472 | } | |
473 | //wxPyEndBlockThreads(blocked); | |
474 | return pyList; | |
475 | } | |
476 | ||
477 | // ---------------------------------------------------------------------------- | |
478 | // FindObjects - Return a list of all the ids that draw to (x,y) | |
479 | // ---------------------------------------------------------------------------- | |
480 | PyObject *wxPseudoDC::FindObjects(wxCoord x, wxCoord y, | |
481 | wxCoord radius, const wxColor& bg) | |
482 | { | |
483 | //wxPyBlock_t blocked = wxPyBeginBlockThreads(); | |
484 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
485 | pdcObject *obj; | |
486 | PyObject* pyList = NULL; | |
487 | pyList = PyList_New(0); | |
488 | wxBrush bgbrush(bg); | |
489 | wxPen bgpen(bg); | |
490 | // special case radius = 0 | |
491 | if (radius == 0) | |
492 | { | |
493 | wxBitmap bmp(4,4,24); | |
494 | wxMemoryDC memdc; | |
495 | wxColor pix; | |
496 | wxRect viewrect(x-2,y-2,4,4); | |
497 | // setup the memdc for rendering | |
498 | memdc.SelectObject(bmp); | |
499 | memdc.SetBackground(bgbrush); | |
500 | memdc.Clear(); | |
501 | memdc.SetDeviceOrigin(2-x,2-y); | |
502 | while (pt) | |
503 | { | |
504 | obj = pt->GetData(); | |
505 | if (obj->IsBounded() && obj->GetBounds().Contains(x,y)) | |
506 | { | |
507 | // start clean | |
508 | memdc.SetBrush(bgbrush); | |
509 | memdc.SetPen(bgpen); | |
510 | memdc.DrawRectangle(viewrect); | |
511 | // draw the object | |
512 | obj->DrawToDC(&memdc); | |
513 | memdc.GetPixel(x,y,&pix); | |
514 | // clear and update rgn2 | |
515 | if (pix != bg) | |
516 | { | |
517 | PyObject* pyObj = PyInt_FromLong((long)obj->GetId()); | |
518 | PyList_Insert(pyList, 0, pyObj); | |
519 | Py_DECREF(pyObj); | |
520 | } | |
521 | } | |
522 | pt = pt->GetNext(); | |
523 | } | |
524 | memdc.SelectObject(wxNullBitmap); | |
525 | } | |
526 | else | |
527 | { | |
528 | wxRect viewrect(x-radius,y-radius,2*radius,2*radius); | |
529 | wxBitmap maskbmp(2*radius,2*radius,24); | |
530 | wxMemoryDC maskdc; | |
531 | // create bitmap with circle for masking | |
532 | maskdc.SelectObject(maskbmp); | |
533 | maskdc.SetBackground(*wxBLACK_BRUSH); | |
534 | maskdc.Clear(); | |
535 | maskdc.SetBrush(*wxWHITE_BRUSH); | |
536 | maskdc.SetPen(*wxWHITE_PEN); | |
537 | maskdc.DrawCircle(radius,radius,radius); | |
538 | // now setup a memdc for rendering our object | |
539 | wxBitmap bmp(2*radius,2*radius,24); | |
540 | wxMemoryDC memdc; | |
541 | memdc.SelectObject(bmp); | |
542 | // set the origin so (x,y) is in the bmp center | |
543 | memdc.SetDeviceOrigin(radius-x,radius-y); | |
544 | // a region will be used to see if the result is empty | |
545 | wxRegion rgn2; | |
546 | while (pt) | |
547 | { | |
548 | obj = pt->GetData(); | |
549 | if (obj->IsBounded() && viewrect.Intersects(obj->GetBounds())) | |
550 | { | |
551 | // start clean | |
552 | //memdc.Clear(); | |
553 | memdc.SetBrush(bgbrush); | |
554 | memdc.SetPen(bgpen); | |
555 | memdc.DrawRectangle(viewrect); | |
556 | // draw the object | |
557 | obj->DrawToDC(&memdc); | |
558 | // remove background color | |
559 | memdc.SetLogicalFunction(wxXOR); | |
560 | memdc.SetBrush(bgbrush); | |
561 | memdc.SetPen(bgpen); | |
562 | memdc.DrawRectangle(viewrect); | |
563 | memdc.SetLogicalFunction(wxCOPY); | |
564 | #ifdef __WXMAC__ | |
565 | // wxAND is not supported on wxMac, but it doesn't seem to | |
566 | // hurt anything to use wxCOPY instead... | |
567 | memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxCOPY); | |
568 | #else | |
569 | // AND with circle bitmap | |
570 | memdc.Blit(x-radius,y-radius,2*radius,2*radius,&maskdc,0,0,wxAND); | |
571 | #endif | |
572 | // clear and update rgn2 | |
573 | memdc.SelectObject(wxNullBitmap); | |
574 | rgn2.Clear(); | |
575 | rgn2.Union(bmp, *wxBLACK); | |
576 | //rgn2.Intersect(rgn); | |
577 | memdc.SelectObject(bmp); | |
578 | if (!rgn2.IsEmpty()) | |
579 | { | |
580 | PyObject* pyObj = PyInt_FromLong((long)obj->GetId()); | |
581 | PyList_Insert(pyList, 0, pyObj); | |
582 | Py_DECREF(pyObj); | |
583 | } | |
584 | } | |
585 | pt = pt->GetNext(); | |
586 | } | |
587 | maskdc.SelectObject(wxNullBitmap); | |
588 | memdc.SelectObject(wxNullBitmap); | |
589 | } | |
590 | //wxPyEndBlockThreads(blocked); | |
591 | return pyList; | |
592 | } | |
593 | ||
594 | // ---------------------------------------------------------------------------- | |
595 | // DrawToDCClipped - play back the op list to the DC but clip any objects | |
596 | // known to be not in rect. This is a coarse level of | |
597 | // clipping to speed things up when lots of objects are off | |
598 | // screen and doesn't affect the dc level clipping | |
599 | // ---------------------------------------------------------------------------- | |
600 | void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect) | |
601 | { | |
602 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
603 | pdcObject *obj; | |
604 | while (pt) | |
605 | { | |
606 | obj = pt->GetData(); | |
607 | if (!obj->IsBounded() || rect.Intersects(obj->GetBounds())) | |
608 | obj->DrawToDC(dc); | |
609 | pt = pt->GetNext(); | |
610 | } | |
611 | } | |
612 | void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region) | |
613 | { | |
614 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
615 | pdcObject *obj; | |
616 | while (pt) | |
617 | { | |
618 | obj = pt->GetData(); | |
619 | if (!obj->IsBounded() || | |
620 | (region.Contains(obj->GetBounds()) != wxOutRegion)) | |
621 | obj->DrawToDC(dc); | |
622 | pt = pt->GetNext(); | |
623 | } | |
624 | } | |
625 | ||
626 | // ---------------------------------------------------------------------------- | |
627 | // DrawToDC - play back the op list to the DC | |
628 | // ---------------------------------------------------------------------------- | |
629 | void wxPseudoDC::DrawToDC(wxDC *dc) | |
630 | { | |
631 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
632 | while (pt) | |
633 | { | |
634 | pt->GetData()->DrawToDC(dc); | |
635 | pt = pt->GetNext(); | |
636 | } | |
637 | } | |
638 |