]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/pseudodc.cpp
Part of patch# 1570448, use dwRop for StretchBIBits too
[wxWidgets.git] / wxPython / src / pseudodc.cpp
CommitLineData
7e664d85
RD
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>
20WX_DEFINE_LIST(pdcOpList);
21WX_DEFINE_LIST(pdcObjectList);
22
23// ============================================================================
24// various pdcOp class implementation methods
25// ============================================================================
26
27// ----------------------------------------------------------------------------
28// pdcDrawPolyPolygonOp constructor
29// ----------------------------------------------------------------------------
30pdcDrawPolyPolygonOp::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// ----------------------------------------------------------------------------
62pdcDrawPolyPolygonOp::~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// ----------------------------------------------------------------------------
73pdcDrawLinesOp::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// ----------------------------------------------------------------------------
89pdcDrawLinesOp::~pdcDrawLinesOp()
90{
91 if (m_points) delete m_points;
92 m_points=NULL;
93}
94
95// ----------------------------------------------------------------------------
96// pdcDrawPolygonOp constructor
97// ----------------------------------------------------------------------------
98pdcDrawPolygonOp::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// ----------------------------------------------------------------------------
114pdcDrawPolygonOp::~pdcDrawPolygonOp()
115{
116 if (m_points) delete m_points;
117 m_points=NULL;
118}
119
120#if wxUSE_SPLINES
121// ----------------------------------------------------------------------------
122// pdcDrawSplineOp constructor
123// ----------------------------------------------------------------------------
124pdcDrawSplineOp::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// ----------------------------------------------------------------------------
139pdcDrawSplineOp::~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// ----------------------------------------------------------------------------
152void 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// ----------------------------------------------------------------------------
165void 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// ----------------------------------------------------------------------------
187wxPseudoDC::~wxPseudoDC()
188{
189 // delete all the nodes in the list
190 RemoveAll();
191
192}
193
194// ----------------------------------------------------------------------------
195// ClearAll - remove all nodes from list
196// ----------------------------------------------------------------------------
197void 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// ----------------------------------------------------------------------------
207int 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// ----------------------------------------------------------------------------
224pdcObjectList::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// ----------------------------------------------------------------------------
256void 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// ----------------------------------------------------------------------------
265void 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// ----------------------------------------------------------------------------
274void 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// ----------------------------------------------------------------------------
288void 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// ----------------------------------------------------------------------------
297void 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// ----------------------------------------------------------------------------
309void 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// ----------------------------------------------------------------------------
318void 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// ----------------------------------------------------------------------------
330void 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}
342void 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// ----------------------------------------------------------------------------
359void 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