1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dcbase.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
,
28 wxCoord width
, wxCoord height
)
30 wxCHECK_RET( Ok(), wxT("invalid window dc") );
32 wxCoord x2
= x1
+ width
,
35 // this is to yield width of 3 for width == height == 10
36 SetPen(wxPen(GetTextForeground(), (width
+ height
+ 1) / 7, wxSOLID
));
38 // we're drawing a scaled version of wx/generic/tick.xpm here
39 wxCoord x3
= x1
+ (4*width
) / 10, // x of the tick bottom
40 y3
= y1
+ height
/ 2; // y of the left tick branch
41 DoDrawLine(x1
, y3
, x3
, y2
);
42 DoDrawLine(x3
, y2
, x2
, y1
);
44 CalcBoundingBox(x1
, y1
);
45 CalcBoundingBox(x2
, y2
);
48 void wxDCBase::DrawLines(const wxList
*list
, wxCoord xoffset
, wxCoord yoffset
)
50 int n
= list
->Number();
51 wxPoint
*points
= new wxPoint
[n
];
54 for ( wxNode
*node
= list
->First(); node
; node
= node
->Next(), i
++ )
56 wxPoint
*point
= (wxPoint
*)node
->Data();
57 points
[i
].x
= point
->x
;
58 points
[i
].y
= point
->y
;
61 DoDrawLines(n
, points
, xoffset
, yoffset
);
67 void wxDCBase::DrawPolygon(const wxList
*list
,
68 wxCoord xoffset
, wxCoord yoffset
,
71 int n
= list
->Number();
72 wxPoint
*points
= new wxPoint
[n
];
75 for ( wxNode
*node
= list
->First(); node
; node
= node
->Next(), i
++ )
77 wxPoint
*point
= (wxPoint
*)node
->Data();
78 points
[i
].x
= point
->x
;
79 points
[i
].y
= point
->y
;
82 DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
);
90 // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
91 void wxDCBase::DrawSpline(wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord x3
, wxCoord y3
)
95 wxPoint
*point1
= new wxPoint
;
96 point1
->x
= x1
; point1
->y
= y1
;
97 point_list
.Append((wxObject
*)point1
);
99 wxPoint
*point2
= new wxPoint
;
100 point2
->x
= x2
; point2
->y
= y2
;
101 point_list
.Append((wxObject
*)point2
);
103 wxPoint
*point3
= new wxPoint
;
104 point3
->x
= x3
; point3
->y
= y3
;
105 point_list
.Append((wxObject
*)point3
);
107 DrawSpline(&point_list
);
109 for( wxNode
*node
= point_list
.First(); node
; node
= node
->Next() )
111 wxPoint
*p
= (wxPoint
*)node
->Data();
116 void wxDCBase::DrawSpline(int n
, wxPoint points
[])
119 for (int i
=0; i
< n
; i
++)
121 list
.Append((wxObject
*)&points
[i
]);
127 // ----------------------------------- spline code ----------------------------------------
129 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
130 double a3
, double b3
, double a4
, double b4
);
131 void wx_clear_stack();
132 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
133 double *y3
, double *x4
, double *y4
);
134 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
135 double x4
, double y4
);
136 static bool wx_spline_add_point(double x
, double y
);
137 static void wx_spline_draw_point_array(wxDCBase
*dc
);
139 wxList wx_spline_point_list
;
141 #define half(z1, z2) ((z1+z2)/2.0)
144 /* iterative version */
146 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
149 register double xmid
, ymid
;
150 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
153 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
155 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
156 xmid
= (double)half(x2
, x3
);
157 ymid
= (double)half(y2
, y3
);
158 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
159 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
160 wx_spline_add_point( x1
, y1
);
161 wx_spline_add_point( xmid
, ymid
);
163 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
164 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
165 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
166 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
171 /* utilities used by spline drawing routines */
173 typedef struct wx_spline_stack_struct
{
174 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
177 #define SPLINE_STACK_DEPTH 20
178 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
179 static Stack
*wx_stack_top
;
180 static int wx_stack_count
;
182 void wx_clear_stack()
184 wx_stack_top
= wx_spline_stack
;
188 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
190 wx_stack_top
->x1
= x1
;
191 wx_stack_top
->y1
= y1
;
192 wx_stack_top
->x2
= x2
;
193 wx_stack_top
->y2
= y2
;
194 wx_stack_top
->x3
= x3
;
195 wx_stack_top
->y3
= y3
;
196 wx_stack_top
->x4
= x4
;
197 wx_stack_top
->y4
= y4
;
202 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
203 double *x3
, double *y3
, double *x4
, double *y4
)
205 if (wx_stack_count
== 0)
209 *x1
= wx_stack_top
->x1
;
210 *y1
= wx_stack_top
->y1
;
211 *x2
= wx_stack_top
->x2
;
212 *y2
= wx_stack_top
->y2
;
213 *x3
= wx_stack_top
->x3
;
214 *y3
= wx_stack_top
->y3
;
215 *x4
= wx_stack_top
->x4
;
216 *y4
= wx_stack_top
->y4
;
220 static bool wx_spline_add_point(double x
, double y
)
222 wxPoint
*point
= new wxPoint
;
225 wx_spline_point_list
.Append((wxObject
*)point
);
229 static void wx_spline_draw_point_array(wxDCBase
*dc
)
231 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
232 wxNode
*node
= wx_spline_point_list
.First();
235 wxPoint
*point
= (wxPoint
*)node
->Data();
238 node
= wx_spline_point_list
.First();
242 void wxDCBase::DoDrawSpline( wxList
*points
)
244 wxCHECK_RET( Ok(), wxT("invalid window dc") );
247 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
248 double x1
, y1
, x2
, y2
;
250 wxNode
*node
= points
->First();
251 p
= (wxPoint
*)node
->Data();
257 p
= (wxPoint
*)node
->Data();
261 cx1
= (double)((x1
+ x2
) / 2);
262 cy1
= (double)((y1
+ y2
) / 2);
263 cx2
= (double)((cx1
+ x2
) / 2);
264 cy2
= (double)((cy1
+ y2
) / 2);
266 wx_spline_add_point(x1
, y1
);
268 while ((node
= node
->Next()) != NULL
)
270 p
= (wxPoint
*)node
->Data();
275 cx4
= (double)(x1
+ x2
) / 2;
276 cy4
= (double)(y1
+ y2
) / 2;
277 cx3
= (double)(x1
+ cx4
) / 2;
278 cy3
= (double)(y1
+ cy4
) / 2;
280 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
284 cx2
= (double)(cx1
+ x2
) / 2;
285 cy2
= (double)(cy1
+ y2
) / 2;
288 wx_spline_add_point( cx1
, cy1
);
289 wx_spline_add_point( x2
, y2
);
291 wx_spline_draw_point_array( this );
294 #endif // wxUSE_SPLINES