Blob


1 #include <stdio.h>
2 #include <math.h>
3 #include <string.h>
4 #include "pic.h"
5 extern int dbg;
7 #define abs(n) (n >= 0 ? n : -(n))
8 #define max(x,y) ((x)>(y) ? (x) : (y))
10 char *textshift = "\\v'.2m'"; /* move text this far down */
12 /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */
13 /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
14 /* default output is 6x6 inches */
17 double xscale;
18 double yscale;
20 double hpos = 0; /* current horizontal position in output coordinate system */
21 double vpos = 0; /* current vertical position; 0 is top of page */
23 double htrue = 0; /* where we really are */
24 double vtrue = 0;
26 double X0, Y0; /* left bottom of input */
27 double X1, Y1; /* right top of input */
29 double hmax; /* right end of output */
30 double vmax; /* top of output (down is positive) */
32 extern double deltx;
33 extern double delty;
34 extern double xmin, ymin, xmax, ymax;
36 double xconv(double), yconv(double), xsc(double), ysc(double);
37 void space(double, double, double, double);
38 void hgoto(double), vgoto(double), hmot(double), vmot(double);
39 void move(double, double), movehv(double, double);
41 char svgfill[40] = "transparent";
42 char svgstroke[40] = "black";
44 void openpl(char *s) /* initialize device; s is residue of .PS invocation line */
45 {
46 double maxw, maxh, ratio = 1;
47 double odeltx = deltx, odelty = delty;
49 hpos = vpos = 0;
50 maxw = getfval("maxpswid");
51 maxh = getfval("maxpsht");
52 if (deltx > maxw) { /* shrink horizontal */
53 ratio = maxw / deltx;
54 deltx *= ratio;
55 delty *= ratio;
56 }
57 if (delty > maxh) { /* shrink vertical */
58 ratio = maxh / delty;
59 deltx *= ratio;
60 delty *= ratio;
61 }
62 if (ratio != 1) {
63 fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty);
64 fprintf(stderr, " %g X %g\n", deltx, delty);
65 }
66 space(xmin, ymin, xmax, ymax);
68 printf("<svg height=\"%.3f\" width=\"%.3f\"\n", yconv(ymin)+10, xconv(xmax)+10);
69 printf(" xmlns=\"http://www.w3.org/2000/svg\">\n");
70 printf("<g transform=\"translate(5 5)\">\n");
72 /*
73 printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax);
74 printf("... %.3fi %.3fi %.3fi %.3fi\n",
75 xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
76 printf(".nr 00 \\n(.u\n");
77 printf(".nf\n");
78 printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
79 */
80 }
82 void space(double x0, double y0, double x1, double y1) /* set limits of page */
83 {
84 X0 = x0;
85 Y0 = y0;
86 X1 = x1;
87 Y1 = y1;
88 xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0);
89 yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0);
91 xscale *= 144;
92 yscale *= 144;
93 }
95 double xconv(double x) /* convert x from external to internal form */
96 {
97 return (x-X0) * xscale;
98 }
100 double xsc(double x) /* convert x from external to internal form, scaling only */
103 return (x) * xscale;
106 double yconv(double y) /* convert y from external to internal form */
108 return (Y1-y) * yscale;
111 double ysc(double y) /* convert y from external to internal form, scaling only */
113 return (y) * yscale;
116 void closepl(char *PEline) /* clean up after finished */
118 printf("</g>\n");
119 printf("</svg>\n");
122 void move(double x, double y) /* go to position x, y in external coords */
124 hgoto(xconv(x));
125 vgoto(yconv(y));
128 void movehv(double h, double v) /* go to internal position h, v */
130 hgoto(h);
131 vgoto(v);
134 void hmot(double n) /* generate n units of horizontal motion */
136 hpos += n;
139 void vmot(double n) /* generate n units of vertical motion */
141 vpos += n;
144 void hgoto(double n)
146 hpos = n;
149 void vgoto(double n)
151 vpos = n;
154 void hvflush(void) /* get to proper point for output */
156 /*
157 if (fabs(hpos-htrue) >= 0.0005) {
158 printf("\\h'%.3fi'", hpos - htrue);
159 htrue = hpos;
161 if (fabs(vpos-vtrue) >= 0.0005) {
162 printf("\\v'%.3fi'", vpos - vtrue);
163 vtrue = vpos;
165 */
168 void printlf(int n, char *f)
172 void troff(char *s) /* output troff right here */
174 printf("%s\n", s);
177 void label(char *s, int t, int nh) /* text s of type t nh half-lines up */
179 char *anchor;
181 if (!s)
182 return;
184 if (t & ABOVE)
185 nh++;
186 else if (t & BELOW)
187 nh--;
188 t &= ~(ABOVE|BELOW);
189 anchor = 0;
190 if (t & LJUST) {
191 // default
192 } else if (t & RJUST) {
193 anchor = "end";
194 } else { /* CENTER */
195 anchor = "middle";
197 printf("<text x=\"%.3f\" y=\"%.3f\"", hpos, vpos-(double)(nh-0.4)*(12.0/72)/2*144);
198 if(anchor)
199 printf(" text-anchor=\"%s\"", anchor);
200 printf(">%s</text>\n", s);
203 void line(double x0, double y0, double x1, double y1, int attr, double ddval) /* draw line from x0,y0 to x1,y1 */
205 printf("<path d=\"M %.3f %.3f L %.3f %.3f\" fill=\"transparent\" stroke=\"black\"", xconv(x0), yconv(y0), xconv(x1), yconv(y1));
206 if(attr & DASHBIT)
207 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
208 else if(attr & DOTBIT)
209 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
210 printf("/>\n");
213 void arrow(double x0, double y0, double x1, double y1, double w, double h,
214 double ang, int nhead) /* draw arrow (without shaft) */
216 double alpha, rot, drot, hyp;
217 double dx, dy;
218 int i;
220 rot = atan2(w / 2, h);
221 hyp = sqrt(w/2 * w/2 + h * h);
222 alpha = atan2(y1-y0, x1-x0) + ang;
223 if (nhead < 2)
224 nhead = 2;
225 dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha);
226 printf("<path d=\"");
227 for (i = 1; i >= 0; i--) {
228 drot = 2 * rot / (double) (2-1) * (double) i;
229 dx = hyp * cos(alpha + PI - rot + drot);
230 dy = hyp * sin(alpha + PI - rot + drot);
231 dprintf("dx,dy = %g,%g\n", dx, dy);
232 if(i == 1)
233 printf("M %.3f %.3f L %.3f %.3f", xconv(x1+dx), yconv(y1+dy), xconv(x1), yconv(y1));
234 else
235 printf(" L %.3f %.3f", xconv(x1+dx), yconv(y1+dy));
237 if (nhead > 2)
238 printf(" Z");
239 printf("\"");
240 if(nhead > 3)
241 printf(" fill=\"black\" stroke=\"black\"");
242 else if(nhead == 3)
243 printf(" fill=\"white\" stroke=\"black\"");
244 else
245 printf(" fill=\"transparent\" stroke=\"black\"");
246 printf("/>\n");
249 double lastgray = 0;
251 void fillstart(double v, int vis, int fill)
253 int x;
255 if(fill) {
256 x = (int)(v*255.0);
257 sprintf(svgfill, "#%02x%02x%02x", x, x, x);
258 } else
259 strcpy(svgfill, "transparent");
260 if(vis)
261 strcpy(svgstroke, "black");
262 else
263 strcpy(svgstroke, "transparent");
266 void fillend(void)
268 strcpy(svgfill, "transparent");
269 strcpy(svgstroke, "black");
272 void box(double x0, double y0, double x1, double y1, int attr, double ddval)
274 printf("<path d=\"M %.3f %.3f V %.3f H %.3f V %.3f Z\" fill=\"transparent\" stroke=\"black\"", xconv(x0), yconv(y0), yconv(y1), xconv(x1), yconv(y0));
275 if(attr & DASHBIT)
276 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
277 else if(attr & DOTBIT)
278 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
279 printf("/>\n");
283 void circle(double x, double y, double r)
285 printf("<circle cx=\"%.3f\" cy=\"%.3f\" r=\"%.3f\" fill=\"%s\" stroke=\"%s\"/>\n", xconv(x), yconv(y), xsc(r), svgfill, svgstroke);
288 void spline(double x, double y, double n, ofloat *p, int attr, double ddval)
290 int i;
291 double x1, y1;
293 printf("<path d=\"M %.3f %.3f", xconv(x), yconv(y));
294 x1 = 0;
295 y1 = 0;
296 for (i = 0; i < 2 * n; i += 2) {
297 x1 = x;
298 y1 = y;
299 x += p[i];
300 y += p[i+1];
301 if(i == 0)
302 printf(" L %.3f %.3f", xconv((x+x1)/2), yconv((y+y1)/2));
303 else
304 printf(" Q %.3f %.3f %.3f %.3f", xconv(x1), yconv(y1), xconv((x+x1)/2), yconv((y+y1)/2));
306 printf(" L %.3f %.3f", xconv(x), yconv(y));
307 printf("\" fill=\"%s\" stroke=\"%s\"", svgfill, svgstroke);
308 if(attr & DASHBIT)
309 printf(" stroke-dasharray=\"%.3f, %.3f\"", xsc(ddval), xsc(ddval));
310 else if(attr & DOTBIT)
311 printf(" stroke-dasharray=\"1, %.3f\"", xsc(ddval));
312 printf("/>\n");
315 void ellipse(double x, double y, double r1, double r2)
317 printf("<ellipse cx=\"%.3f\" cy=\"%.3f\" rx=\"%.3f\" ry=\"%.3f\" fill=\"%s\" stroke=\"%s\"/>\n", xconv(x), yconv(y), xsc(r1), ysc(r2), svgfill, svgstroke);
320 void arc(double x, double y, double x0, double y0, double x1, double y1, double r) /* draw arc with center x,y */
322 printf("<path d=\"M %.3f %.3f A %.3f %.3f %d %d %d %.3f %.3f\" fill=\"%s\" stroke=\"%s\"/>\n",
323 xconv(x0), yconv(y0),
324 xsc(r), ysc(r), 0, 0, 0, xconv(x1), yconv(y1),
325 svgfill, svgstroke);