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