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"
25 void wxDCBase::DoDrawCheckMark(wxCoord x1
, wxCoord y1
,
26 wxCoord width
, wxCoord height
)
28 wxCHECK_RET( Ok(), wxT("invalid window dc") );
30 wxCoord x2
= x1
+ width
,
33 // this is to yield width of 3 for width == height == 10
34 SetPen(wxPen(GetTextForeground(), (width
+ height
+ 1) / 7, wxSOLID
));
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
);
42 CalcBoundingBox(x1
, y1
);
43 CalcBoundingBox(x2
, y2
);
46 void wxDCBase::DrawLines(const wxList
*list
, wxCoord xoffset
, wxCoord yoffset
)
48 int n
= list
->Number();
49 wxPoint
*points
= new wxPoint
[n
];
52 for ( wxNode
*node
= list
->First(); node
; node
= node
->Next(), i
++ )
54 wxPoint
*point
= (wxPoint
*)node
->Data();
55 points
[i
].x
= point
->x
;
56 points
[i
].y
= point
->y
;
59 DoDrawLines(n
, points
, xoffset
, yoffset
);
65 void wxDCBase::DrawPolygon(const wxList
*list
,
66 wxCoord xoffset
, wxCoord yoffset
,
69 int n
= list
->Number();
70 wxPoint
*points
= new wxPoint
[n
];
73 for ( wxNode
*node
= list
->First(); node
; node
= node
->Next(), i
++ )
75 wxPoint
*point
= (wxPoint
*)node
->Data();
76 points
[i
].x
= point
->x
;
77 points
[i
].y
= point
->y
;
80 DoDrawPolygon(n
, points
, xoffset
, yoffset
, fillStyle
);
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
)
93 wxPoint
*point1
= new wxPoint
;
94 point1
->x
= x1
; point1
->y
= y1
;
95 point_list
.Append((wxObject
*)point1
);
97 wxPoint
*point2
= new wxPoint
;
98 point2
->x
= x2
; point2
->y
= y2
;
99 point_list
.Append((wxObject
*)point2
);
101 wxPoint
*point3
= new wxPoint
;
102 point3
->x
= x3
; point3
->y
= y3
;
103 point_list
.Append((wxObject
*)point3
);
105 DrawSpline(&point_list
);
107 for( wxNode
*node
= point_list
.First(); node
; node
= node
->Next() )
109 wxPoint
*p
= (wxPoint
*)node
->Data();
114 void wxDCBase::DrawSpline(int n
, wxPoint points
[])
117 for (int i
=0; i
< n
; i
++)
119 list
.Append((wxObject
*)&points
[i
]);
125 // ----------------------------------- spline code ----------------------------------------
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
);
137 wxList wx_spline_point_list
;
139 #define half(z1, z2) ((z1+z2)/2.0)
142 /* iterative version */
144 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
147 register double xmid
, ymid
;
148 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
151 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
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
);
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
);
169 /* utilities used by spline drawing routines */
171 typedef struct wx_spline_stack_struct
{
172 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
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
;
180 void wx_clear_stack()
182 wx_stack_top
= wx_spline_stack
;
186 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
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
;
200 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
201 double *x3
, double *y3
, double *x4
, double *y4
)
203 if (wx_stack_count
== 0)
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
;
218 static bool wx_spline_add_point(double x
, double y
)
220 wxPoint
*point
= new wxPoint
;
223 wx_spline_point_list
.Append((wxObject
*)point
);
227 static void wx_spline_draw_point_array(wxDCBase
*dc
)
229 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
230 wxNode
*node
= wx_spline_point_list
.First();
233 wxPoint
*point
= (wxPoint
*)node
->Data();
236 node
= wx_spline_point_list
.First();
240 void wxDCBase::DoDrawSpline( wxList
*points
)
242 wxCHECK_RET( Ok(), wxT("invalid window dc") );
245 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
246 double x1
, y1
, x2
, y2
;
248 wxNode
*node
= points
->First();
249 p
= (wxPoint
*)node
->Data();
255 p
= (wxPoint
*)node
->Data();
259 cx1
= (double)((x1
+ x2
) / 2);
260 cy1
= (double)((y1
+ y2
) / 2);
261 cx2
= (double)((cx1
+ x2
) / 2);
262 cy2
= (double)((cy1
+ y2
) / 2);
264 wx_spline_add_point(x1
, y1
);
266 while ((node
= node
->Next()) != NULL
)
268 p
= (wxPoint
*)node
->Data();
273 cx4
= (double)(x1
+ x2
) / 2;
274 cy4
= (double)(y1
+ y2
) / 2;
275 cx3
= (double)(x1
+ cx4
) / 2;
276 cy3
= (double)(y1
+ cy4
) / 2;
278 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
282 cx2
= (double)(cx1
+ x2
) / 2;
283 cy2
= (double)(cy1
+ y2
) / 2;
286 wx_spline_add_point( cx1
, cy1
);
287 wx_spline_add_point( x2
, y2
);
289 wx_spline_draw_point_array( this );
292 #endif // wxUSE_SPLINES