1 #ifndef lint
2 static char sccsid[] = "@(#)pltroff.c 3.2 (CWI) 85/08/15";
3 #endif lint
4
5 #include <stdio.h>
6 #include <math.h>
7 #include "pic.h"
8 extern int dbg;
9
10 #define abs(n) (n >= 0 ? n : -(n))
11 #define max(x,y) ((x)>(y) ? (x) : (y))
12
13 char *textshift = "\\v'.2m'"; /* move text this far down */
14
15 /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */
16 /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
17 /* default output is 6x6 inches */
18
19
20 float xscale;
21 float yscale;
22
23 float hpos = 0; /* current horizontal position in output coordinate system */
24 float vpos = 0; /* current vertical position; 0 is top of page */
25
26 float htrue = 0; /* where we really are */
27 float vtrue = 0;
28
29 float X0, Y0; /* left bottom of input */
30 float X1, Y1; /* right top of input */
31
32 float hmax; /* right end of output */
33 float vmax; /* top of output (down is positive) */
34
35 extern float deltx;
36 extern float delty;
37 extern float xmin, ymin, xmax, ymax;
38
39 float xconv(), yconv(), xsc(), ysc();
40
openpl(s)41 openpl(s) /* initialize device */
42 char *s; /* residue of .PS invocation line */
43 {
44 float maxdelt;
45
46 hpos = vpos = 0;
47 if (deltx > 8.5 || delty > 11) { /* 8.5x11 inches max */
48 fprintf(stderr, "pic: %g X %g picture shrunk to", deltx, delty);
49 maxdelt = max(deltx, delty);
50 deltx *= 7/maxdelt;
51 delty *= 7/maxdelt;
52 fprintf(stderr, " %g X %g\n", deltx, delty);
53 }
54 space(xmin, ymin, xmax, ymax);
55 printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax);
56 printf("... %.3fi %.3fi %.3fi %.3fi\n",
57 xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
58 printf(".nr 00 \\n(.u\n");
59 printf(".nf\n");
60 printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
61 /* assumes \n comes as part of s */
62 }
63
space(x0,y0,x1,y1)64 space(x0, y0, x1, y1) /* set limits of page */
65 float x0, y0, x1, y1;
66 {
67 X0 = x0;
68 Y0 = y0;
69 X1 = x1;
70 Y1 = y1;
71 xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0);
72 yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0);
73 }
74
xconv(x)75 float xconv(x) /* convert x from external to internal form */
76 float x;
77 {
78 return (x-X0) * xscale;
79 }
80
xsc(x)81 float xsc(x) /* convert x from external to internal form, scaling only */
82 float x;
83 {
84
85 return (x) * xscale;
86 }
87
yconv(y)88 float yconv(y) /* convert y from external to internal form */
89 float y;
90 {
91 return (Y1-y) * yscale;
92 }
93
ysc(y)94 float ysc(y) /* convert y from external to internal form, scaling only */
95 float y;
96 {
97 return (y) * yscale;
98 }
99
closepl(type)100 closepl(type) /* clean up after finished */
101 int type;
102 {
103 movehv(0.0, 0.0); /* get back to where we started */
104 if (type == 'F')
105 printf(".PF\n");
106 else {
107 printf(".sp 1+%.3fi\n", yconv(ymin));
108 printf(".PE\n");
109 }
110 printf(".if \\n(00 .fi\n");
111 }
112
move(x,y)113 move(x, y) /* go to position x, y in external coords */
114 float x, y;
115 {
116 hgoto(xconv(x));
117 vgoto(yconv(y));
118 }
119
movehv(h,v)120 movehv(h, v) /* go to internal position h, v */
121 float h, v;
122 {
123 hgoto(h);
124 vgoto(v);
125 }
126
hmot(n)127 hmot(n) /* generate n units of horizontal motion */
128 float n;
129 {
130 hpos += n;
131 }
132
vmot(n)133 vmot(n) /* generate n units of vertical motion */
134 float n;
135 {
136 vpos += n;
137 }
138
hgoto(n)139 hgoto(n)
140 float n;
141 {
142 hpos = n;
143 }
144
vgoto(n)145 vgoto(n)
146 float n;
147 {
148 vpos = n;
149 }
150
hvflush()151 hvflush() /* get to proper point for output */
152 {
153 if (hpos != htrue) {
154 printf("\\h'%.3fi'", hpos - htrue);
155 htrue = hpos;
156 }
157 if (vpos != vtrue) {
158 printf("\\v'%.3fi'", vpos - vtrue);
159 vtrue = vpos;
160 }
161 }
162
flyback()163 flyback() /* return to upper left corner (entry point) */
164 {
165 printf(".sp -1\n");
166 htrue = vtrue = 0;
167 }
168
troff(s)169 troff(s) /* output troff right here */
170 char *s;
171 {
172 printf("%s\n", s);
173 }
174
label(s,t,nh)175 label(s, t, nh) /* text s of type t nh half-lines up */
176 char *s;
177 int t, nh;
178 {
179 int q;
180 char *p;
181
182 hvflush();
183 dprintf("label: %s %o %d\n", s, t, nh);
184 printf("%s", textshift); /* shift down and left */
185 if (t & ABOVE)
186 nh++;
187 else if (t & BELOW)
188 nh--;
189 if (nh)
190 printf("\\v'%du*\\n(.vu/2u'", -nh);
191 /* just in case the text contains a quote: */
192 q = 0;
193 for (p = s; *p; p++)
194 if (*p == '\'') {
195 q = 1;
196 break;
197 }
198 t &= ~(ABOVE|BELOW);
199 if (t & LJUST) {
200 printf("%s", s);
201 } else if (t & RJUST) {
202 if (q)
203 printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s, s);
204 else
205 printf("\\h'-\\w'%s'u'%s", s, s);
206 } else { /* CENTER */
207 if (q)
208 printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts", s, s, s);
209 else
210 printf("\\h'-\\w'%s'u/2u'%s\\h'-\\w'%s'u/2u'", s, s, s);
211 }
212 printf("\n");
213 flyback();
214 }
215
line(x0,y0,x1,y1)216 line(x0, y0, x1, y1) /* draw line from x0,y0 to x1,y1 */
217 float x0, y0, x1, y1;
218 {
219 move(x0, y0);
220 cont(x1, y1);
221 }
222
arrow(x0,y0,x1,y1,w,h,ang,nhead)223 arrow(x0, y0, x1, y1, w, h, ang, nhead) /* draw arrow (without shaft) */
224 float x0, y0, x1, y1, w, h, ang; /* head wid w, len h, rotated ang */
225 int nhead; /* and drawn with nhead lines */
226 {
227 double alpha, rot, drot, hyp;
228 float dx, dy;
229 int i;
230
231 rot = atan2(w / 2, h);
232 hyp = sqrt(w/2 * w/2 + h * h);
233 alpha = atan2(y1-y0, x1-x0) + ang;
234 if (nhead < 2)
235 nhead = 2;
236 dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha);
237 for (i = nhead-1; i >= 0; i--) {
238 drot = 2 * rot / (float) (nhead-1) * (float) i;
239 dx = hyp * cos(alpha + PI - rot + drot);
240 dy = hyp * sin(alpha + PI - rot + drot);
241 dprintf("dx,dy = %g,%g\n", dx, dy);
242 line(x1+dx, y1+dy, x1, y1);
243 }
244 }
245
box(x0,y0,x1,y1)246 box(x0, y0, x1, y1)
247 float x0, y0, x1, y1;
248 {
249 move(x0, y0);
250 cont(x0, y1);
251 cont(x1, y1);
252 cont(x1, y0);
253 cont(x0, y0);
254 }
255
cont(x,y)256 cont(x, y) /* continue line from here to x,y */
257 float x, y;
258 {
259 float h1, v1;
260 float dh, dv;
261
262 h1 = xconv(x);
263 v1 = yconv(y);
264 dh = h1 - hpos;
265 dv = v1 - vpos;
266 hvflush();
267 printf("\\D'l%.3fi %.3fi'\n", dh, dv);
268 flyback(); /* expensive */
269 hpos = h1;
270 vpos = v1;
271 }
272
circle(x,y,r)273 circle(x, y, r)
274 float x, y, r;
275 {
276 move(x-r, y);
277 hvflush();
278 printf("\\D'c%.3fi'\n", xsc(2 * r));
279 flyback();
280 }
281
spline(x,y,n,p,dashed,ddval)282 spline(x, y, n, p, dashed, ddval)
283 float x, y, *p;
284 float n; /* sic */
285 int dashed;
286 float ddval;
287 {
288 int i;
289 float dx, dy;
290 float xerr, yerr;
291
292 if (dashed && ddval)
293 printf(".nr 99 %.3fi\n", ddval);
294 move(x, y);
295 hvflush();
296 xerr = yerr = 0.0;
297 if (dashed) {
298 if (ddval)
299 printf("\\X'Pd \\n(99'\\D'q 0 0");
300 else
301 printf("\\X'Pd'\\D'q 0 0");
302 } else
303 printf("\\D'~");
304 for (i = 0; i < 2 * n; i += 2) {
305 dx = xsc(xerr += p[i]);
306 xerr -= dx/xscale;
307 dy = ysc(yerr += p[i+1]);
308 yerr -= dy/yscale;
309 printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */
310 }
311 if (dashed)
312 printf(" 0 0'\\X'Ps'\n");
313 else
314 printf("'\n");
315 flyback();
316 }
317
ellipse(x,y,r1,r2)318 ellipse(x, y, r1, r2)
319 float x, y, r1, r2;
320 {
321 float ir1, ir2;
322
323 move(x-r1, y);
324 hvflush();
325 ir1 = xsc(r1);
326 ir2 = ysc(r2);
327 printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2));
328 flyback();
329 }
330
arc(x,y,x0,y0,x1,y1)331 arc(x, y, x0, y0, x1, y1) /* draw arc with center x,y */
332 float x, y, x0, y0, x1, y1;
333 {
334
335 move(x0, y0);
336 hvflush();
337 printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n",
338 xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */
339 flyback();
340 }
341
dot()342 dot() {
343 hvflush();
344 /* what character to draw here depends on what's available. */
345 /* on the 202, l. is good but small. */
346 /* in general, use a smaller, shifted period and hope */
347
348 printf("\\&\\f1\\h'-.05m'\\v'.03m'\\s-3.\\s+3\\fP\n");
349 flyback();
350 }
351