1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Visual tracer service */
18
19 #include "math_.h"
20 #include "gxfixed.h"
21 #include "vdtrace.h"
22
23 /* Global data for all instances : */
24 vd_trace_interface * vd_trace0 = NULL, * vd_trace1 = NULL;
25 char vd_flags[128] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
26 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
27 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
28 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
29
30 static double px, py;
31
32 #define NullRET if(vd_trace1 == NULL) return
33
scale_x(vd_trace_interface * I,double x)34 static inline double scale_x(vd_trace_interface *I, double x)
35 { return (x - I->orig_x) * I->scale_x + I->shift_x;
36 }
37
scale_y(vd_trace_interface * I,double y)38 static inline double scale_y(vd_trace_interface *I, double y)
39 { return (y - I->orig_y) * I->scale_y + I->shift_y;
40 }
41
42 #define SX(x) scale_x(vd_trace1, x)
43 #define SY(y) scale_y(vd_trace1, y)
44
bezier_point(double p0,double p1,double p2,double p3,double t)45 static inline double bezier_point(double p0, double p1, double p2, double p3, double t)
46 { double s = 1-t;
47 return p0*s*s*s + 3*p1*s*s*t + 3*p2*s*t*t + p3*t*t*t;
48 }
49
vd_flatten(double p0x,double p0y,double p1x,double p1y,double p2x,double p2y,double p3x,double p3y)50 static void vd_flatten(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y, double p3x, double p3y)
51 {
52 #ifdef DEBUG
53 double flat = 0.5;
54 double d2x0 = (p0x - 2 * p1x + p2x), d2y0 = (p0y - 2 * p1y + p2y);
55 double d2x1 = (p1x - 2 * p2x + p3x), d2y1 = (p1y - 2 * p2y + p3y);
56 double d2norm0 = hypot(d2x0, d2y0);
57 double d2norm1 = hypot(d2x1, d2y1);
58 double D = max(d2norm0, d2norm1); /* This is half of maximum norm of 2nd derivative of the curve by parameter t. */
59 int NN = (int)ceil(sqrt(D * 3 / 4 / flat)); /* Number of output segments. */
60 int i;
61 int N = max(NN, 1); /* safety (if the curve degenerates to line) */
62 double e = 0.5 / N;
63
64 for (i = 0; i < N; i++) {
65 double t = (double)i / N + e;
66 double px = bezier_point(p0x, p1x, p2x, p3x, t);
67 double py = bezier_point(p0y, p1y, p2y, p3y, t);
68
69 vd_lineto(px, py);
70 }
71 vd_lineto(p3x, p3y);
72 #endif
73 }
74
vd_impl_moveto(double x,double y)75 void vd_impl_moveto(double x, double y)
76 { NullRET;
77 px = SX(x), py = SY(y);
78 vd_trace1->moveto(vd_trace1, px, py);
79 }
80
vd_impl_lineto(double x,double y)81 void vd_impl_lineto(double x, double y)
82 { NullRET;
83 px = SX(x), py = SY(y);
84 vd_trace1->lineto(vd_trace1, px, py);
85 }
86
vd_impl_lineto_multi(const struct gs_fixed_point_s * p,int n)87 void vd_impl_lineto_multi(const struct gs_fixed_point_s *p, int n)
88 { int i;
89 NullRET;
90 for (i = 0; i < n; i++) {
91 px = SX(p[i].x), py = SY(p[i].y);
92 vd_trace1->lineto(vd_trace1, px, py);
93 }
94 }
95
vd_impl_curveto(double x1,double y1,double x2,double y2,double x3,double y3)96 void vd_impl_curveto(double x1, double y1, double x2, double y2, double x3, double y3)
97 { double p1x, p1y, p2x, p2y, p3x, p3y;
98
99 NullRET;
100 p1x = SX(x1), p1y = SY(y1);
101 p2x = SX(x2), p2y = SY(y2);
102 p3x = SX(x3), p3y = SY(y3);
103 if (vd_trace1->curveto != NULL)
104 vd_trace1->curveto(vd_trace1, p1x, p1y, p2x, p2y, p3x, p3y);
105 else
106 vd_flatten(px, py, p1x, p1y, p2x, p2y, p3x, p3y);
107 px = p3x, py = p3y;
108 }
109
vd_impl_bar(double x0,double y0,double x1,double y1,int w,unsigned long c)110 void vd_impl_bar(double x0, double y0, double x1, double y1, int w, unsigned long c)
111 { NullRET;
112 vd_trace1->setcolor(vd_trace1, c);
113 vd_trace1->setlinewidth(vd_trace1, w);
114 vd_trace1->beg_path(vd_trace1);
115 vd_trace1->moveto(vd_trace1, SX(x0), SY(y0));
116 vd_trace1->lineto(vd_trace1, SX(x1), SY(y1));
117 vd_trace1->end_path(vd_trace1);
118 vd_trace1->stroke(vd_trace1);
119 }
120
vd_impl_square(double x,double y,int w,unsigned int c)121 void vd_impl_square(double x, double y, int w, unsigned int c)
122 { NullRET;
123 vd_trace1->setcolor(vd_trace1, c);
124 vd_trace1->setlinewidth(vd_trace1, 1);
125 vd_trace1->beg_path(vd_trace1);
126 vd_trace1->moveto(vd_trace1, SX(x) - w, SY(y) - w);
127 vd_trace1->lineto(vd_trace1, SX(x) + w, SY(y) - w);
128 vd_trace1->lineto(vd_trace1, SX(x) + w, SY(y) + w);
129 vd_trace1->lineto(vd_trace1, SX(x) - w, SY(y) + w);
130 vd_trace1->lineto(vd_trace1, SX(x) - w, SY(y) - w);
131 vd_trace1->end_path(vd_trace1);
132 vd_trace1->stroke(vd_trace1);
133 }
134
vd_impl_rect(double x0,double y0,double x1,double y1,int w,unsigned int c)135 void vd_impl_rect(double x0, double y0, double x1, double y1, int w, unsigned int c)
136 { NullRET;
137 vd_trace1->setcolor(vd_trace1, c);
138 vd_trace1->setlinewidth(vd_trace1, w);
139 vd_trace1->beg_path(vd_trace1);
140 vd_trace1->moveto(vd_trace1, SX(x0), SY(y0));
141 vd_trace1->lineto(vd_trace1, SX(x0), SY(y1));
142 vd_trace1->lineto(vd_trace1, SX(x1), SY(y1));
143 vd_trace1->lineto(vd_trace1, SX(x1), SY(y0));
144 vd_trace1->lineto(vd_trace1, SX(x0), SY(y0));
145 vd_trace1->end_path(vd_trace1);
146 vd_trace1->stroke(vd_trace1);
147 }
148
vd_impl_quad(double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3,int w,unsigned int c)149 void vd_impl_quad(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned int c)
150 { NullRET;
151 vd_trace1->setcolor(vd_trace1, c);
152 vd_trace1->setlinewidth(vd_trace1, w);
153 vd_trace1->beg_path(vd_trace1);
154 vd_trace1->moveto(vd_trace1, SX(x0), SY(y0));
155 vd_trace1->lineto(vd_trace1, SX(x1), SY(y1));
156 vd_trace1->lineto(vd_trace1, SX(x2), SY(y2));
157 vd_trace1->lineto(vd_trace1, SX(x3), SY(y3));
158 vd_trace1->lineto(vd_trace1, SX(x0), SY(y0));
159 vd_trace1->end_path(vd_trace1);
160 vd_trace1->stroke(vd_trace1);
161 }
162
vd_impl_curve(double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3,int w,unsigned long c)163 void vd_impl_curve(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned long c)
164 { NullRET;
165 vd_trace1->setcolor(vd_trace1, c);
166 vd_trace1->setlinewidth(vd_trace1, w);
167 vd_trace1->beg_path(vd_trace1);
168 vd_trace1->moveto(vd_trace1, SX(x0), SY(y0));
169 vd_impl_curveto(x1, y1, x2, y2, x3, y3);
170 vd_trace1->end_path(vd_trace1);
171 vd_trace1->stroke(vd_trace1);
172 }
173
vd_impl_circle(double x,double y,int r,unsigned long c)174 void vd_impl_circle(double x, double y, int r, unsigned long c)
175 { NullRET;
176 vd_trace1->setcolor(vd_trace1, c);
177 vd_trace1->setlinewidth(vd_trace1, 1);
178 vd_trace1->circle(vd_trace1, SX(x), SY(y), r);
179 }
180
vd_impl_round(double x,double y,int r,unsigned long c)181 void vd_impl_round(double x, double y, int r, unsigned long c)
182 { NullRET;
183 vd_trace1->setcolor(vd_trace1, c);
184 vd_trace1->setlinewidth(vd_trace1, 1);
185 vd_trace1->round(vd_trace1, SX(x), SY(y), r);
186 }
187
vd_impl_pixel(double x,double y,unsigned long c)188 void vd_impl_pixel(double x, double y, unsigned long c)
189 { NullRET;
190 vd_trace1->pixel(vd_trace1, SX(x), SY(y), c);
191 }
192
vd_impl_text(double x,double y,char * s,unsigned long c)193 void vd_impl_text(double x, double y, char *s, unsigned long c)
194 { NullRET;
195 vd_trace1->setcolor(vd_trace1, c);
196 vd_trace1->text(vd_trace1, SX(x), SY(y), s);
197 }
198
vd_setflag(char f,char v)199 void vd_setflag(char f, char v)
200 { vd_flags[f & 127] = v;
201 }
202