|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)vplot.c 4.3 (Berkeley) 8/11/83";
3: #endif
4:
5: /*
6: * Reads standard graphics input and produces a plot on the
7: * Varian or Versatec
8: */
9: #include <stdio.h>
10: #include <signal.h>
11: #include <vfont.h>
12:
13: #define LPR "/usr/ucb/lpr"
14:
15: #define mapx(x) ((DevRange*((x)-botx)/del)+centx)
16: #define mapy(y) ((DevRange*(del-(y)+boty)/del)-centy)
17: #define SOLID -1
18: #define DOTTED 014
19: #define SHORTDASHED 034
20: #define DOTDASHED 054
21: #define LONGDASHED 074
22:
23: char *Sid = "@(#)\t8/11/83";
24:
25: int linmod = SOLID;
26: int done1;
27: char chrtab[][16];
28: char *obuf;
29: int bufsize;
30: int lastx;
31: int lasty;
32: int radius, startx, starty, endx, endy;
33: double topx;
34: double topy;
35: double botx;
36: double boty;
37: int centx = 0;
38: int centy = 0;
39: double delx;
40: double dely;
41: double del;
42:
43: int warned = 0; /* Indicates whether the warning message about
44: * unimplemented routines has been printed */
45:
46: FILE *infile;
47: FILE *pfp; /* output file */
48: char picture[] = "/usr/tmp/rastAXXXXXX";
49: int run = 13; /* index of 'a' in picture[] */
50: int DevRange = 1536; /* output array size (square) in pixels */
51: int DevRange8 = 1536/8; /* output array size in bytes */
52: int BytesPerLine = 264; /* Bytes per raster line (physical) */
53: int lparg = 7; /* index into lpargs */
54:
55: char *lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" };
56:
57: /* variables for used to print from font file */
58: int fontSet = 0; /* Has the font file been read */
59: struct header header;
60: struct dispatch dispatch[256];
61: char *bits;
62: char *fontFile = "/usr/lib/vfont/R.6";
63:
64: main(argc, argv)
65: int argc;
66: char **argv;
67: {
68: extern int cleanup();
69: register char *cp1, *arg;
70: register i;
71: int again;
72:
73: infile = stdin;
74: while (argc > 1 && argv[1][0] == '-') {
75: argc--;
76: arg = *++argv;
77: switch (*++arg) {
78: case 'W':
79: DevRange = 2048;
80: DevRange8 = 2048/8;
81: BytesPerLine = 880;
82: lpargs[1] = "-Pversatec";
83: break;
84: case 'V':
85: DevRange = 1536;
86: DevRange8 = 1536/8;
87: BytesPerLine = 264;
88: lpargs[1] = "-Pvarian";
89: break;
90: case 'b':
91: if (argc-- > 1)
92: lpargs[lparg-1] = *++argv;
93: break;
94: default:
95: fprintf(stderr, "vplot: %s option unknown\n", *argv);
96: break;
97: }
98: }
99: if (argc > 1) {
100: if ((infile = fopen(*++argv, "r")) == NULL) {
101: perror(*argv);
102: cleanup();
103: }
104: }
105:
106: /* init constants for scaling */
107: topx = topy = DevRange;
108: botx = boty = 0;
109: delx = dely = del = DevRange;
110: centx = (DevRange - mapx(topx))/2;
111: centy = mapy(topy)/2;
112: signal(SIGTERM, cleanup);
113: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
114: signal(SIGINT, cleanup);
115: mktemp(picture);
116: if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
117: fprintf(stderr, "vplot: ran out of memory\n");
118: cleanup();
119: }
120: do {
121: if ((pfp = fopen(picture, "w")) == NULL) {
122: fprintf(stderr, "vplot: can't create %s\n", picture);
123: cleanup();
124: }
125: i = strlen(picture) + 1;
126: if ((arg = (char *) malloc(i)) == NULL) {
127: fprintf(stderr, "ran out of memory\n");
128: cleanup();
129: }
130: strcpy(arg, picture);
131: lpargs[lparg++] = arg;
132: picture[run]++;
133: arg = &obuf[bufsize];
134: for (cp1 = obuf; cp1 < arg; )
135: *cp1++ = 0;
136:
137: again = getpict();
138:
139: for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) {
140: fwrite(cp1, sizeof(char), DevRange8, pfp);
141: fseek(pfp, (long) BytesPerLine - DevRange8, 1);
142: }
143: fclose(pfp);
144: } while (again);
145: lpargs[lparg] = 0;
146: execv(LPR, lpargs);
147: fprintf(stderr, "can't exec %s\n", LPR);
148: cleanup();
149: }
150:
151: getpict()
152: {
153: register x1, y1;
154:
155: for (;;) switch (x1 = getc(infile)) {
156:
157: case '\n':
158: continue;
159:
160: case 's':
161: botx = getinteger(infile);
162: boty = getinteger(infile);
163: topx = getinteger(infile);
164: topy = getinteger(infile);
165: delx = topx-botx;
166: dely = topy-boty;
167: if (dely/delx > 1536./2048.)
168: del = dely;
169: else
170: del = delx;
171: centx = 0;
172: centx = (DevRange - mapx(topx))/2;
173: centy = 0;
174: centy = mapy(topy) / 2;
175: continue;
176:
177: case 'b':
178: x1 = getc(infile);
179: continue;
180:
181: case 'l':
182: done1 |= 01;
183: x1 = mapx(getinteger(infile));
184: y1 = mapy(getinteger(infile));
185: lastx = mapx(getinteger(infile));
186: lasty = mapy(getinteger(infile));
187: line(x1, y1, lastx, lasty);
188: continue;
189:
190: case 'c':
191: x1 = mapx(getinteger(infile));
192: y1 = mapy(getinteger(infile));
193: radius = mapx(getinteger(infile));
194: if (!warned) {
195: fprintf(stderr,"Circles are Implemented\n");
196: warned++;
197: }
198: circle(x1, y1, radius);
199: continue;
200:
201: case 'a':
202: x1 = mapx(getinteger(infile));
203: y1 = mapy(getinteger(infile));
204: startx = mapx(getinteger(infile));
205: starty = mapy(getinteger(infile));
206: endx = mapx(getinteger(infile));
207: endy = mapy(getinteger(infile));
208: if (!warned) {
209: fprintf(stderr,"Circles and Arcs are unimplemented\n");
210: warned++;
211: }
212: continue;
213:
214: case 'm':
215: lastx = mapx(getinteger(infile));
216: lasty = mapy(getinteger(infile));
217: continue;
218:
219: case 't':
220: lastx = lastx - 6;
221: lasty = lasty + 6;
222: done1 |= 01;
223: while ((x1 = getc(infile)) != '\n')
224: plotch(x1);
225: continue;
226:
227: case 'e':
228: if (done1)
229: return(1);
230: continue;
231:
232: case 'p':
233: done1 |= 01;
234: lastx = mapx(getinteger(infile));
235: lasty = mapy(getinteger(infile));
236: point(lastx, lasty);
237: point(lastx+1, lasty);
238: point(lastx, lasty+1);
239: point(lastx+1, lasty+1);
240: continue;
241:
242: case 'n':
243: done1 |= 01;
244: x1 = mapx(getinteger(infile));
245: y1 = mapy(getinteger(infile));
246: line(lastx, lasty, x1, y1);
247: lastx = x1;
248: lasty = y1;
249: continue;
250:
251: case 'f':
252: getinteger(infile);
253: getc(infile);
254: switch (getc(infile)) {
255: case 't':
256: linmod = DOTTED;
257: break;
258: default:
259: case 'i':
260: linmod = SOLID;
261: break;
262: case 'g':
263: linmod = LONGDASHED;
264: break;
265: case 'r':
266: linmod = SHORTDASHED;
267: break;
268: case 'd':
269: linmod = DOTDASHED;
270: break;
271: }
272: while ((x1 = getc(infile)) != '\n')
273: if (x1 == EOF)
274: return(0);
275: continue;
276:
277: case 'd':
278: getinteger(infile);
279: getinteger(infile);
280: getinteger(infile);
281: x1 = getinteger(infile);
282: while (--x1 >= 0)
283: getinteger(infile);
284: continue;
285:
286: case 0: /* ignore null characters */
287: continue;
288:
289: case 255:
290: case EOF:
291: return(0);
292:
293: default:
294: fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
295: cleanup();
296: }
297: }
298:
299: plotch(ch)
300: char ch;
301: {
302: register int i,j,k;
303: register char *ptr,c;
304: int nbytes;
305:
306: if (!fontSet)
307: InitFont(); /* Read font if not already read */
308:
309: ptr = bits + dispatch[ch].addr;
310:
311: for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) {
312: nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8;
313: for (j = 0; j < nbytes; j++) {
314: c = *ptr++;
315: for (k = 7; k >= 0; k--)
316: if ((c >> k) & 1)
317: point(lastx+7-k+j*8-dispatch[ch].left, lasty-i);
318: }
319: }
320: if (ch != ' ')
321: lastx += dispatch[ch].width;
322: else
323: lastx += dispatch['a'].width;
324: }
325:
326: InitFont()
327: {
328: char *s;
329: int fonts;
330: int i;
331:
332: fontSet = 1;
333: /* Get the font file */
334: s = fontFile;
335: if ((fonts = open(s, 0)) == -1) {
336: perror(s);
337: fprintf(stderr, "Can't get font file");
338: cleanup();
339: }
340: /* Get the header and check magic number */
341: if (read(fonts, &header, sizeof(header)) != sizeof(header)) {
342: perror(s);
343: fprintf(stderr, "Bad read in font file");
344: cleanup();
345: }
346: if (header.magic != 0436) {
347: fprintf(stderr,"Bad magic numer in font file");
348: cleanup();
349: }
350: /* Get dispatches */
351: if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) {
352: perror(s);
353: fprintf(stderr, "Bad read in font file");
354: cleanup();
355: }
356: /* Allocate space for bit map and read in bits */
357: bits = (char *) malloc(header.size);
358: if (read(fonts, bits, header.size) != header.size) {
359: perror(s);
360: fprintf(stderr,"Can't read bit map in font file");
361: cleanup();
362: }
363: /* Close font file */
364: if (close(fonts) != 0) {
365: perror(s);
366: fprintf(stderr,"Can't close font file");
367: cleanup();
368: }
369: }
370:
371: line(x0, y0, x1, y1)
372: register x0, y0;
373: {
374: int dx, dy;
375: int xinc, yinc;
376: register res1;
377: int res2;
378: int slope;
379:
380: xinc = 1;
381: yinc = 1;
382: if ((dx = x1-x0) < 0) {
383: xinc = -1;
384: dx = -dx;
385: }
386: if ((dy = y1-y0) < 0) {
387: yinc = -1;
388: dy = -dy;
389: }
390: slope = xinc*yinc;
391: res1 = 0;
392: res2 = 0;
393: if (dx >= dy) while (x0 != x1) {
394: if ((x0+slope*y0) & linmod)
395: point(x0, y0);
396: if (res1 > res2) {
397: res2 += dx - res1;
398: res1 = 0;
399: y0 += yinc;
400: }
401: res1 += dy;
402: x0 += xinc;
403: } else while (y0 != y1) {
404: if ((x0+slope*y0) & linmod)
405: point(x0, y0);
406: if (res1 > res2) {
407: res2 += dy - res1;
408: res1 = 0;
409: x0 += xinc;
410: }
411: res1 += dx;
412: y0 += yinc;
413: }
414: if ((x1+slope*y1) & linmod)
415: point(x1, y1);
416: }
417:
418: #define labs(a) (a >= 0 ? a : -a)
419:
420: circle(x,y,c)
421: {
422: register dx, dy;
423: long ep;
424: int de;
425:
426: dx = 0;
427: ep = 0;
428: for (dy=c; dy>=dx; dy--) {
429: for (;;) {
430: point(x+dx, y+dy);
431: point(x-dx, y+dy);
432: point(x+dx, y-dy);
433: point(x-dx, y-dy);
434: point(x+dy, y+dx);
435: point(x-dy, y+dx);
436: point(x+dy, y-dx);
437: point(x-dy, y-dx);
438: ep += 2*dx + 1;
439: de = -2*dy + 1;
440: dx++;
441: if (labs(ep) >= labs(ep+de)) {
442: ep += de;
443: break;
444: }
445: }
446: }
447: }
448:
449: /*
450: * Points should be in the range 0 <= x (or y) <= DevRange.
451: * The origin is the top left-hand corner with increasing x towards the
452: * right and increasing y going down.
453: */
454: point(x, y)
455: register int x, y;
456: {
457: register unsigned byte;
458:
459: byte = y * DevRange8 + (x >> 3);
460: if (byte < bufsize)
461: obuf[byte] |= 1 << (7 - (x & 07));
462: }
463:
464: cleanup()
465: {
466: while (picture[run] != 'a') {
467: unlink(picture);
468: picture[run]--;
469: }
470: exit(1);
471: }
472:
473: getinteger(f)
474: FILE *f;
475: {
476: register int low, high, result;
477:
478: low = getc(f);
479: high = getc(f);
480: result = ((high << 8) | low);
481: if (high > 127)
482: result |= ~0xffff;
483: return(result);
484: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.