]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/pseudodc.cpp
Part of patch# 1570448, use dwRop for StretchBIBits too
[wxWidgets.git] / wxPython / src / pseudodc.cpp
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 #include "wx/wxPython/pseudodc.h"
16 #include <stdio.h>
17
18 // wxList based class definitions
19 #include <wx/listimpl.cpp>
20 WX_DEFINE_LIST(pdcOpList);
21 WX_DEFINE_LIST(pdcObjectList);
22
23 // ============================================================================
24 // various pdcOp class implementation methods
25 // ============================================================================
26
27 // ----------------------------------------------------------------------------
28 // pdcDrawPolyPolygonOp constructor
29 // ----------------------------------------------------------------------------
30 pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[],
31 wxCoord xoffset, wxCoord yoffset, int fillStyle)
32 {
33 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
34 int total_n=0;
35 if (n)
36 {
37 m_count = new int[n];
38 for(int i=0; i<n; i++)
39 {
40 total_n+=count[i];
41 m_count[i]=count[i];
42 }
43 if (total_n)
44 {
45 m_points = new wxPoint[total_n];
46 for(int j=0; j<total_n; j++)
47 m_points[j] = points[j];
48 }
49 else m_points=NULL;
50 }
51 else
52 {
53 m_points=NULL;
54 m_count=NULL;
55 }
56 m_totaln = total_n;
57 }
58
59 // ----------------------------------------------------------------------------
60 // pdcDrawPolyPolygonOp destructor
61 // ----------------------------------------------------------------------------
62 pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp()
63 {
64 if (m_points) delete m_points;
65 if (m_count) delete m_count;
66 m_points=NULL;
67 m_count=NULL;
68 }
69
70 // ----------------------------------------------------------------------------
71 // pdcDrawLinesOp constructor
72 // ----------------------------------------------------------------------------
73 pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[],
74 wxCoord xoffset, wxCoord yoffset)
75 {
76 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset;
77 if (n)
78 {
79 m_points = new wxPoint[n];
80 for (int i=0; i<n; i++)
81 m_points[i] = points[i];
82 }
83 else m_points=NULL;
84 }
85
86 // ----------------------------------------------------------------------------
87 // pdcDrawLinesOp destructor
88 // ----------------------------------------------------------------------------
89 pdcDrawLinesOp::~pdcDrawLinesOp()
90 {
91 if (m_points) delete m_points;
92 m_points=NULL;
93 }
94
95 // ----------------------------------------------------------------------------
96 // pdcDrawPolygonOp constructor
97 // ----------------------------------------------------------------------------
98 pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[],
99 wxCoord xoffset, wxCoord yoffset, int fillStyle)
100 {
101 m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle;
102 if (n)
103 {
104 m_points = new wxPoint[n];
105 for (int i=0; i<n; i++)
106 m_points[i] = points[i];
107 }
108 else m_points=NULL;
109 }
110
111 // ----------------------------------------------------------------------------
112 // pdcDrawPolygonOp destructor
113 // ----------------------------------------------------------------------------
114 pdcDrawPolygonOp::~pdcDrawPolygonOp()
115 {
116 if (m_points) delete m_points;
117 m_points=NULL;
118 }
119
120 #if wxUSE_SPLINES
121 // ----------------------------------------------------------------------------
122 // pdcDrawSplineOp constructor
123 // ----------------------------------------------------------------------------
124 pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[])
125 {
126 m_n=n;
127 if (n)
128 {
129 m_points = new wxPoint[n];
130 for(int i=0; i<n; i++)
131 m_points[i] = points[i];
132 }
133 else m_points=NULL;
134 }
135
136 // ----------------------------------------------------------------------------
137 // pdcDrawSplineOp destructor
138 // ----------------------------------------------------------------------------
139 pdcDrawSplineOp::~pdcDrawSplineOp()
140 {
141 if (m_points) delete m_points;
142 m_points=NULL;
143 }
144 #endif // wxUSE_SPLINES
145
146 // ============================================================================
147 // pdcObject implementation
148 // ============================================================================
149 // ----------------------------------------------------------------------------
150 // DrawToDC - play back the op list to the DC
151 // ----------------------------------------------------------------------------
152 void pdcObject::DrawToDC(wxDC *dc)
153 {
154 pdcOpList::Node *node = m_oplist.GetFirst();
155 while(node)
156 {
157 node->GetData()->DrawToDC(dc);
158 node = node->GetNext();
159 }
160 }
161
162 // ----------------------------------------------------------------------------
163 // Translate - translate all the operations by some dx,dy
164 // ----------------------------------------------------------------------------
165 void pdcObject::Translate(wxCoord dx, wxCoord dy)
166 {
167 pdcOpList::Node *node = m_oplist.GetFirst();
168 while(node)
169 {
170 node->GetData()->Translate(dx,dy);
171 node = node->GetNext();
172 }
173 if (m_bounded)
174 {
175 m_bounds.x += dx;
176 m_bounds.y += dy;
177 }
178 }
179
180 // ============================================================================
181 // wxPseudoDC implementation
182 // ============================================================================
183
184 // ----------------------------------------------------------------------------
185 // Destructor
186 // ----------------------------------------------------------------------------
187 wxPseudoDC::~wxPseudoDC()
188 {
189 // delete all the nodes in the list
190 RemoveAll();
191
192 }
193
194 // ----------------------------------------------------------------------------
195 // ClearAll - remove all nodes from list
196 // ----------------------------------------------------------------------------
197 void wxPseudoDC::RemoveAll(void)
198 {
199 m_objectlist.Clear();
200 m_currId = -1;
201 m_lastObjNode = NULL;
202 }
203
204 // ----------------------------------------------------------------------------
205 // GetLen - return the number of operations in the current op list
206 // ----------------------------------------------------------------------------
207 int wxPseudoDC::GetLen(void)
208 {
209 pdcObjectList::Node *pt = m_objectlist.GetFirst();
210 int len=0;
211 while (pt)
212 {
213 len += pt->GetData()->GetLen();
214 pt = pt->GetNext();
215 }
216 return len;
217 }
218
219 // ----------------------------------------------------------------------------
220 // FindObjNode - find and return an object node by id. If node doesn't exist
221 // and create is true then create one and return it. Otherwise
222 // return NULL.
223 // ----------------------------------------------------------------------------
224 pdcObjectList::Node *wxPseudoDC::FindObjNode(int id, bool create)
225 {
226 // see if last operation was for same id
227 if (m_lastObjNode && m_lastObjNode->GetData()->GetId() == id)
228 return m_lastObjNode;
229 // if not then search for it
230 pdcObjectList::Node *pt = m_objectlist.GetFirst();
231 while (pt)
232 {
233 if (pt->GetData()->GetId() == id)
234 {
235
236 // cache this node for future operations
237 m_lastObjNode = pt;
238 return pt;
239 }
240 pt = pt->GetNext();
241 }
242 // if create then create and return a new node
243 if (create)
244 {
245 // cache this node for future operations
246 m_lastObjNode = m_objectlist.Append(new pdcObject(id));
247 return m_lastObjNode;
248 }
249 // otherwise just return NULL
250 return NULL;
251 }
252
253 // ----------------------------------------------------------------------------
254 // AddToList - Add a node to the list at the end (preserve draw order)
255 // ----------------------------------------------------------------------------
256 void wxPseudoDC::AddToList(pdcOp *newOp)
257 {
258 pdcObjectList::Node *pt = FindObjNode(m_currId, true);
259 pt->GetData()->AddOp(newOp);
260 }
261
262 // ----------------------------------------------------------------------------
263 // ClearID - remove all the operations associated with a single ID
264 // ----------------------------------------------------------------------------
265 void wxPseudoDC::ClearId(int id)
266 {
267 pdcObjectList::Node *pt = FindObjNode(id);
268 if (pt) pt->GetData()->Clear();
269 }
270
271 // ----------------------------------------------------------------------------
272 // RemoveID - Remove the object node (and all operations) associated with an id
273 // ----------------------------------------------------------------------------
274 void wxPseudoDC::RemoveId(int id)
275 {
276 pdcObjectList::Node *pt = FindObjNode(id);
277 if (pt)
278 {
279 if (m_lastObjNode == pt)
280 m_lastObjNode = NULL;
281 m_objectlist.DeleteNode(pt);
282 }
283 }
284
285 // ----------------------------------------------------------------------------
286 // SetIdBounds - Set the bounding rect for a given id
287 // ----------------------------------------------------------------------------
288 void wxPseudoDC::SetIdBounds(int id, wxRect& rect)
289 {
290 pdcObjectList::Node *pt = FindObjNode(id, true);
291 pt->GetData()->SetBounds(rect);
292 }
293
294 // ----------------------------------------------------------------------------
295 // GetIdBounds - Get the bounding rect for a given id
296 // ----------------------------------------------------------------------------
297 void wxPseudoDC::GetIdBounds(int id, wxRect& rect)
298 {
299 pdcObjectList::Node *pt = FindObjNode(id);
300 if (pt && pt->GetData()->IsBounded())
301 rect = pt->GetData()->GetBounds();
302 else
303 rect.x = rect.y = rect.width = rect.height = 0;
304 }
305
306 // ----------------------------------------------------------------------------
307 // TranslateId - Translate all the operations of a single id
308 // ----------------------------------------------------------------------------
309 void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy)
310 {
311 pdcObjectList::Node *pt = FindObjNode(id);
312 if (pt) pt->GetData()->Translate(dx,dy);
313 }
314
315 // ----------------------------------------------------------------------------
316 // DrawIdToDC - Draw a specific id to the dc passed in
317 // ----------------------------------------------------------------------------
318 void wxPseudoDC::DrawIdToDC(int id, wxDC *dc)
319 {
320 pdcObjectList::Node *pt = FindObjNode(id);
321 if (pt) pt->GetData()->DrawToDC(dc);
322 }
323
324 // ----------------------------------------------------------------------------
325 // DrawToDCClipped - play back the op list to the DC but clip any objects
326 // known to be not in rect. This is a coarse level of
327 // clipping to speed things up when lots of objects are off
328 // screen and doesn't affect the dc level clipping
329 // ----------------------------------------------------------------------------
330 void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect)
331 {
332 pdcObjectList::Node *pt = m_objectlist.GetFirst();
333 pdcObject *obj;
334 while (pt)
335 {
336 obj = pt->GetData();
337 if (!obj->IsBounded() || rect.Intersects(obj->GetBounds()))
338 obj->DrawToDC(dc);
339 pt = pt->GetNext();
340 }
341 }
342 void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region)
343 {
344 pdcObjectList::Node *pt = m_objectlist.GetFirst();
345 pdcObject *obj;
346 while (pt)
347 {
348 obj = pt->GetData();
349 if (!obj->IsBounded() ||
350 (region.Contains(obj->GetBounds()) != wxOutRegion))
351 obj->DrawToDC(dc);
352 pt = pt->GetNext();
353 }
354 }
355
356 // ----------------------------------------------------------------------------
357 // DrawToDC - play back the op list to the DC
358 // ----------------------------------------------------------------------------
359 void wxPseudoDC::DrawToDC(wxDC *dc)
360 {
361 pdcObjectList::Node *pt = m_objectlist.GetFirst();
362 while (pt)
363 {
364 pt->GetData()->DrawToDC(dc);
365 pt = pt->GetNext();
366 }
367 }
368