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