|
|
1.1 root 1: #include <stdio.h>
2: #include <ctype.h>
3:
4: #define DEV202 1
5: #define DEVAPS 2
6: #define DEVCAT 3
7: #define DEV450 4
8: int devtype = DEV202;
9:
10: float deltx; /* max x value in output, for scaling */
11: float delty; /* max y value in output, for scaling */
12: int dbg = 0;
13: int res = 972; /* 202 is default */
14: FILE *fin; /* input file pointer */
15: char *cmdname;
16: int crop = 1; /* trim off exterior white space if non-zero */
17: float hshift = 0.3; /* move this far left for text (in em's) */
18: float vshift = 0.3; /* this far down */
19: /* these values are suitable for circuit diagrams */
20: int linetype = 's'; /* solid is normal */
21:
22: char buf[20000];
23: char *bp = buf;
24:
25: int sxmin; /* lower limit from s command */
26: int symin;
27: int sxmax = 4096; /* upper */
28: int symax = 4096;
29: int xmin = 30000; /* min values found in actual data */
30: int ymin = 30000;
31: int xmax = -30000; /* max */
32: int ymax = -30000;
33:
34: main(argc,argv)
35: char **argv;
36: {
37: float atof();
38: int c;
39:
40: cmdname = argv[0];
41: while (argc > 1 && *argv[1] == '-') {
42: switch (c = argv[1][1]) {
43: case 'T':
44: if (strcmp(&argv[1][2], "aps") == 0) {
45: res = 720;
46: devtype = DEVAPS;
47: } else if (strcmp(&argv[1][2], "cat") == 0) {
48: res = 432;
49: devtype = DEVCAT;
50: }
51: break;
52: case 'c':
53: crop = 0;
54: break;
55: case 'l':
56: delty = atof(&argv[1][2]);
57: break;
58: case 'w':
59: case 's': /* set size */
60: if (argv[1][2] == 0) {
61: argv++;
62: argc--;
63: deltx = atof(&argv[1][0]);
64: } else
65: deltx = atof(&argv[1][2]);
66: if (c == 's')
67: delty = deltx;
68: break;
69: case 'd':
70: dbg = 1;
71: break;
72: }
73: argc--;
74: argv++;
75: }
76: if (argc <= 1) {
77: fin = stdin;
78: getdata();
79: } else
80: while (argc-- > 1) {
81: if ((fin = fopen(*++argv, "r")) == NULL) {
82: fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
83: exit(1);
84: }
85: getdata();
86: fclose(fin);
87: }
88: print();
89: exit(0);
90: }
91:
92: getdata() /* read the file, collect max, min sizes, etc. */
93: {
94: char s[100], s1[20], *p;
95: int x, y, x1, y1, x2, y2, r, c;
96:
97: while ((c = getc(fin)) != EOF) {
98: switch (c) {
99: case 'M':
100: case 'N':
101: case 'P':
102: fscanf(fin, "%d %d", &x, &y);
103: extreme(x, y);
104: ctobuf(tolower(c));
105: xytobuf(x, y);
106: break;
107: case 'm':
108: case 'n':
109: case 'p':
110: x = getsi(fin);
111: y = getsi(fin);
112: extreme(x, y);
113: ctobuf(c);
114: xytobuf(x, y);
115: break;
116: case 'L':
117: case 'B':
118: fscanf(fin, "%d %d %d %d", &x, &y, &x1, &y1);
119: extreme(x, y);
120: extreme(x1, y1);
121: ctobuf(tolower(c));
122: xytobuf(x, y);
123: xytobuf(x1, y1);
124: break;
125: case 'l':
126: case 'b':
127: x = getsi(fin);
128: y = getsi(fin);
129: x1 = getsi(fin);
130: y1 = getsi(fin);
131: extreme(x, y);
132: extreme(x1, y1);
133: ctobuf(c);
134: xytobuf(x, y);
135: xytobuf(x1, y1);
136: break;
137: case 'S':
138: fscanf(fin, "%d %d %d %d", &sxmin, &symin, &sxmax, &symax);
139: break; /* BUG -- ignoring this because it overrides -c */
140: ctobuf('s');
141: xytobuf(sxmin, symin);
142: xytobuf(sxmax, symax);
143: break;
144: case 's':
145: sxmin = getsi(fin);
146: symin = getsi(fin);
147: sxmax = getsi(fin);
148: symax = getsi(fin);
149: break; /* BUG -- ignoring this because it overrides -c */
150: ctobuf(c);
151: xytobuf(sxmin, symin);
152: xytobuf(sxmax, symax);
153: break;
154: case 'T':
155: case 't':
156: fgets(s, sizeof s, fin);
157: for (p = s; *p != '\n'; p++)
158: ;
159: *p = 0; /* zap newline */
160: ctobuf('t');
161: stobuf(s);
162: break;
163: case 'E':
164: case 'e':
165: ctobuf('e');
166: break;
167: case 'A':
168: fscanf(fin, "%d %d %d %d %d %d", &x, &y, &x1, &y1, &x2, &y2);
169: extreme(x, y); /* should use radius */
170: ctobuf('a');
171: xytobuf(x, y);
172: xytobuf(x1, y1);
173: xytobuf(x2, y2);
174: break;
175: case 'a':
176: x = getsi(fin);
177: y = getsi(fin);
178: x1 = getsi(fin);
179: y1 = getsi(fin);
180: x2 = getsi(fin);
181: y2 = getsi(fin);
182: extreme(x, y); /* should use radius */
183: ctobuf('a');
184: xytobuf(x, y);
185: xytobuf(x1, y1);
186: xytobuf(x2, y2);
187: break;
188: case 'C':
189: fscanf(fin, "%d %d %d", &x, &y, &r);
190: extreme(x+r, y+r);
191: extreme(x-r, y-r);
192: ctobuf('c');
193: xytobuf(x, y);
194: xtobuf(r);
195: break;
196: case 'c':
197: x = getsi(fin);
198: y = getsi(fin);
199: r = getsi(fin);
200: extreme(x+r, y+r);
201: extreme(x-r, y-r);
202: ctobuf('c');
203: xytobuf(x, y);
204: xtobuf(r);
205: break;
206: case 'F':
207: case 'f':
208: fgets(s, sizeof s, fin);
209: ctobuf('f');
210: sscanf(s, "%s", s1);
211: if (strcmp(s1, "solid") == 0)
212: c = 's';
213: else if (strcmp(s1, "dotted") == 0)
214: c = '.';
215: else if (strcmp(s1, "longdashed") == 0)
216: c = '_';
217: else if (strcmp(s1, "shortdashed") == 0)
218: c = '-';
219: else
220: c = '!'; /* would you believe dotdashed? */
221: ctobuf(c);
222: break;
223: case 'd':
224: case 'D':
225: fgets(s, 100, fin);
226: /* ignore */
227: break;
228: default:
229: break;
230: }
231: if (bp >= buf + sizeof buf) {
232: fprintf(stderr, "pltroff: input too big to handle\n");
233: exit(1);
234: }
235: }
236: *bp = 0;
237: }
238:
239: extreme(x, y) /* record max and min x and y values */
240: {
241: if (x > xmax)
242: xmax = x;
243: if (y > ymax)
244: ymax = y;
245: if (x < xmin)
246: xmin = x;
247: if (y < ymin)
248: ymin = y;
249: }
250:
251: ctobuf(c)
252: {
253: *bp++ = c;
254: }
255:
256: stobuf(s)
257: char *s;
258: {
259: while (*bp++ = *s++)
260: ;
261: }
262:
263: xytobuf(x, y)
264: {
265: *bp++ = x >> 8;
266: *bp++ = x & 0377;
267: *bp++ = y >> 8;
268: *bp++ = y & 0377;
269: }
270:
271: xtobuf(x)
272: {
273: *bp++ = x >> 8;
274: *bp++ = x & 0377;
275: }
276:
277: print()
278: {
279: char s[100], *p;
280: int x, y, x1, y1, x2, y2, r, c;
281:
282: openpl("\n"); /* outputs .PS\n */
283: for (bp = buf; *bp; ) {
284: switch (c = *bp++) {
285: case 'm':
286: x = getbuf();
287: y = getbuf();
288: move(x, y);
289: break;
290: case 'f': /* line mode */
291: linetype = *bp++;
292: break;
293: case 'l':
294: x = getbuf();
295: y = getbuf();
296: x1 = getbuf();
297: y1 = getbuf();
298: if (linetype == 's')
299: line(x, y, x1, y1);
300: else
301: dotline(x, y, x1, y1, linetype);
302: break;
303: case 't':
304: for (p = s; *p++ = *bp++; )
305: ;
306: label(s, 'L', 0);
307: break;
308: case 'e':
309: erase();
310: break;
311: case 'p':
312: x = getbuf();
313: y = getbuf();
314: point(x, y);
315: break;
316: case 'n':
317: x = getbuf();
318: y = getbuf();
319: cont(x, y);
320: break;
321: case 's':
322: x = getbuf();
323: y = getbuf();
324: x1 = getbuf();
325: y1 = getbuf();
326: space(x, y, x1, y1);
327: break;
328: case 'a':
329: x = getbuf();
330: y = getbuf();
331: x1 = getbuf();
332: y1 = getbuf();
333: x2 = getbuf();
334: y2 = getbuf();
335: arc(x, y, x1, y1, x2, y2);
336: break;
337: case 'c':
338: x = getbuf();
339: y = getbuf();
340: r = getbuf();
341: circle(x, y, r);
342: break;
343: case 'b':
344: x = getbuf();
345: y = getbuf();
346: x1 = getbuf();
347: y1 = getbuf();
348: box(x, y, x1, y1);
349: break;
350: default:
351: break;
352: }
353: }
354: closepl();
355: }
356:
357: dotline(x0, y0, x1, y1, type) /* dotted or dashed line */
358: int x0, y0, x1, y1;
359: int type;
360: {
361: int prevval = 10;
362: int i, numdots;
363: double a, b, sqrt(), dx, dy;
364:
365: dx = x1 - x0;
366: dy = y1 - y0;
367: if (type == '.') {
368: numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
369: for (i = 0; i <= numdots; i++) {
370: a = (float) i / (float) numdots;
371: move(x0 + (int)(a * dx), y0 + (int)(a * dy));
372: dot();
373: }
374: } else { /* all others */
375: double d, dashsize, spacesize;
376: d = sqrt(dx*dx + dy*dy) + 0.5;
377: if (d <= 2 * prevval) {
378: line(x0, y0, x1, y1);
379: return;
380: }
381: numdots = d / (2 * prevval - 1) + 1; /* ceiling */
382: dashsize = prevval;
383: spacesize = (d - numdots * dashsize) / (numdots - 1);
384: for (i = 0; i < numdots-1; i++) {
385: a = i * (dashsize + spacesize) / d;
386: b = a + dashsize / d;
387: line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy));
388: a = b;
389: b = a + spacesize / d;
390: move(x0 + (int)(a*dx), y0 + (int)(a*dy));
391: }
392: line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1);
393: }
394: }
395:
396: getbuf()
397: {
398: int n;
399:
400: n = *bp++ << 8;
401: n |= (*bp++ & 0377);
402: return(n);
403: }
404:
405: getsi(fin) FILE *fin; { /* get an integer stored in 2 ascii bytes. */
406: short a, b;
407: if((b = getc(fin)) == EOF)
408: return(EOF);
409: if((a = getc(fin)) == EOF)
410: return(EOF);
411: a = a<<8;
412: return(a|b);
413: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.