]> git.saurik.com Git - wxWidgets.git/blob - src/common/dcbase.cpp
9cd65312e32085841ea565c1e74172520169c2f2
[wxWidgets.git] / src / common / dcbase.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dc.cpp
3 // Purpose: wxDC Class
4 // Author: Brian Macy
5 // Modified by:
6 // Created: 05/25/99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "dcbase.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/dc.h"
24
25 void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1,
26 wxCoord width, wxCoord height)
27 {
28 wxCHECK_RET( Ok(), wxT("invalid window dc") );
29
30 wxCoord x2 = x1 + width,
31 y2 = y1 + height;
32
33 // this is to yield width of 3 for width == height == 10
34 SetPen(wxPen(GetTextForeground(), (width + height + 1) / 7, wxSOLID));
35
36 // we're drawing a scaled version of wx/generic/tick.xpm here
37 wxCoord x3 = x1 + (4*width) / 10, // x of the tick bottom
38 y3 = y1 + height / 2; // y of the left tick branch
39 DoDrawLine(x1, y3, x3, y2);
40 DoDrawLine(x3, y2, x2, y1);
41
42 CalcBoundingBox(x1, y1);
43 CalcBoundingBox(x2, y2);
44 }
45
46 void wxDCBase::DrawLines(const wxList *list, wxCoord xoffset, wxCoord yoffset)
47 {
48 int n = list->Number();
49 wxPoint *points = new wxPoint[n];
50
51 int i = 0;
52 for ( wxNode *node = list->First(); node; node = node->Next(), i++ )
53 {
54 wxPoint *point = (wxPoint *)node->Data();
55 points[i].x = point->x;
56 points[i].y = point->y;
57 }
58
59 DoDrawLines(n, points, xoffset, yoffset);
60
61 delete [] points;
62 }
63
64
65 void wxDCBase::DrawPolygon(const wxList *list,
66 wxCoord xoffset, wxCoord yoffset,
67 int fillStyle)
68 {
69 int n = list->Number();
70 wxPoint *points = new wxPoint[n];
71
72 int i = 0;
73 for ( wxNode *node = list->First(); node; node = node->Next(), i++ )
74 {
75 wxPoint *point = (wxPoint *)node->Data();
76 points[i].x = point->x;
77 points[i].y = point->y;
78 }
79
80 DoDrawPolygon(n, points, xoffset, yoffset, fillStyle);
81
82 delete [] points;
83 }
84
85
86 #if wxUSE_SPLINES
87
88 // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
89 void wxDCBase::DrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3)
90 {
91 wxList point_list;
92
93 wxPoint *point1 = new wxPoint;
94 point1->x = x1; point1->y = y1;
95 point_list.Append((wxObject*)point1);
96
97 wxPoint *point2 = new wxPoint;
98 point2->x = x2; point2->y = y2;
99 point_list.Append((wxObject*)point2);
100
101 wxPoint *point3 = new wxPoint;
102 point3->x = x3; point3->y = y3;
103 point_list.Append((wxObject*)point3);
104
105 DrawSpline(&point_list);
106
107 for( wxNode *node = point_list.First(); node; node = node->Next() )
108 {
109 wxPoint *p = (wxPoint *)node->Data();
110 delete p;
111 }
112 }
113
114 void wxDCBase::DrawSpline(int n, wxPoint points[])
115 {
116 wxList list;
117 for (int i =0; i < n; i++)
118 {
119 list.Append((wxObject*)&points[i]);
120 }
121
122 DrawSpline(&list);
123 }
124
125 // ----------------------------------- spline code ----------------------------------------
126
127 void wx_quadratic_spline(double a1, double b1, double a2, double b2,
128 double a3, double b3, double a4, double b4);
129 void wx_clear_stack();
130 int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
131 double *y3, double *x4, double *y4);
132 void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
133 double x4, double y4);
134 static bool wx_spline_add_point(double x, double y);
135 static void wx_spline_draw_point_array(wxDCBase *dc);
136
137 wxList wx_spline_point_list;
138
139 #define half(z1, z2) ((z1+z2)/2.0)
140 #define THRESHOLD 5
141
142 /* iterative version */
143
144 void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
145 double b4)
146 {
147 register double xmid, ymid;
148 double x1, y1, x2, y2, x3, y3, x4, y4;
149
150 wx_clear_stack();
151 wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
152
153 while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
154 xmid = (double)half(x2, x3);
155 ymid = (double)half(y2, y3);
156 if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
157 fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
158 wx_spline_add_point( x1, y1 );
159 wx_spline_add_point( xmid, ymid );
160 } else {
161 wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
162 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
163 wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
164 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
165 }
166 }
167 }
168
169 /* utilities used by spline drawing routines */
170
171 typedef struct wx_spline_stack_struct {
172 double x1, y1, x2, y2, x3, y3, x4, y4;
173 } Stack;
174
175 #define SPLINE_STACK_DEPTH 20
176 static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
177 static Stack *wx_stack_top;
178 static int wx_stack_count;
179
180 void wx_clear_stack()
181 {
182 wx_stack_top = wx_spline_stack;
183 wx_stack_count = 0;
184 }
185
186 void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
187 {
188 wx_stack_top->x1 = x1;
189 wx_stack_top->y1 = y1;
190 wx_stack_top->x2 = x2;
191 wx_stack_top->y2 = y2;
192 wx_stack_top->x3 = x3;
193 wx_stack_top->y3 = y3;
194 wx_stack_top->x4 = x4;
195 wx_stack_top->y4 = y4;
196 wx_stack_top++;
197 wx_stack_count++;
198 }
199
200 int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
201 double *x3, double *y3, double *x4, double *y4)
202 {
203 if (wx_stack_count == 0)
204 return (0);
205 wx_stack_top--;
206 wx_stack_count--;
207 *x1 = wx_stack_top->x1;
208 *y1 = wx_stack_top->y1;
209 *x2 = wx_stack_top->x2;
210 *y2 = wx_stack_top->y2;
211 *x3 = wx_stack_top->x3;
212 *y3 = wx_stack_top->y3;
213 *x4 = wx_stack_top->x4;
214 *y4 = wx_stack_top->y4;
215 return (1);
216 }
217
218 static bool wx_spline_add_point(double x, double y)
219 {
220 wxPoint *point = new wxPoint ;
221 point->x = (int) x;
222 point->y = (int) y;
223 wx_spline_point_list.Append((wxObject*)point);
224 return TRUE;
225 }
226
227 static void wx_spline_draw_point_array(wxDCBase *dc)
228 {
229 dc->DrawLines(&wx_spline_point_list, 0, 0 );
230 wxNode *node = wx_spline_point_list.First();
231 while (node)
232 {
233 wxPoint *point = (wxPoint *)node->Data();
234 delete point;
235 delete node;
236 node = wx_spline_point_list.First();
237 }
238 }
239
240 void wxDCBase::DoDrawSpline( wxList *points )
241 {
242 wxCHECK_RET( Ok(), wxT("invalid window dc") );
243
244 wxPoint *p;
245 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
246 double x1, y1, x2, y2;
247
248 wxNode *node = points->First();
249 p = (wxPoint *)node->Data();
250
251 x1 = p->x;
252 y1 = p->y;
253
254 node = node->Next();
255 p = (wxPoint *)node->Data();
256
257 x2 = p->x;
258 y2 = p->y;
259 cx1 = (double)((x1 + x2) / 2);
260 cy1 = (double)((y1 + y2) / 2);
261 cx2 = (double)((cx1 + x2) / 2);
262 cy2 = (double)((cy1 + y2) / 2);
263
264 wx_spline_add_point(x1, y1);
265
266 while ((node = node->Next()) != NULL)
267 {
268 p = (wxPoint *)node->Data();
269 x1 = x2;
270 y1 = y2;
271 x2 = p->x;
272 y2 = p->y;
273 cx4 = (double)(x1 + x2) / 2;
274 cy4 = (double)(y1 + y2) / 2;
275 cx3 = (double)(x1 + cx4) / 2;
276 cy3 = (double)(y1 + cy4) / 2;
277
278 wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
279
280 cx1 = cx4;
281 cy1 = cy4;
282 cx2 = (double)(cx1 + x2) / 2;
283 cy2 = (double)(cy1 + y2) / 2;
284 }
285
286 wx_spline_add_point( cx1, cy1 );
287 wx_spline_add_point( x2, y2 );
288
289 wx_spline_draw_point_array( this );
290 }
291
292 #endif // wxUSE_SPLINES