need to do cc -c (or will try to load)
[unix-history] / usr / src / old / vplot / vplot.c
CommitLineData
17d1455f
SL
1#ifndef lint
2static char sccsid[] = "@(#)vplot.c 4.3 (Berkeley) %G%";
3#endif
4
5/*
e853d173
RC
6 * Reads standard graphics input and produces a plot on the
7 * Varian or Versatec
fddad162 8 */
e853d173 9#include <stdio.h>
fddad162 10#include <signal.h>
e853d173
RC
11#include <vfont.h>
12
13#define LPR "/usr/ucb/lpr"
fddad162 14
e853d173
RC
15#define mapx(x) ((DevRange*((x)-botx)/del)+centx)
16#define mapy(y) ((DevRange*(del-(y)+boty)/del)-centy)
fddad162
RC
17#define SOLID -1
18#define DOTTED 014
19#define SHORTDASHED 034
20#define DOTDASHED 054
21#define LONGDASHED 074
e853d173
RC
22
23char *Sid = "@(#)\t%G%";
fddad162
RC
24
25int linmod = SOLID;
fddad162
RC
26int done1;
27char chrtab[][16];
265c917a
RC
28char *obuf;
29int bufsize;
fddad162
RC
30int lastx;
31int lasty;
e853d173
RC
32int radius, startx, starty, endx, endy;
33double topx;
34double topy;
35double botx;
36double boty;
37int centx = 0;
38int centy = 0;
39double delx;
40double dely;
41double del;
42
43int warned = 0; /* Indicates whether the warning message about
44 * unimplemented routines has been printed */
fddad162 45
e853d173 46FILE *infile;
265c917a 47FILE *pfp; /* output file */
e853d173
RC
48char picture[] = "/usr/tmp/rastAXXXXXX";
49int run = 13; /* index of 'a' in picture[] */
50int DevRange = 1536; /* output array size (square) in pixels */
265c917a 51int DevRange8 = 1536/8; /* output array size in bytes */
e853d173
RC
52int BytesPerLine = 264; /* Bytes per raster line (physical) */
53int lparg = 7; /* index into lpargs */
54
55char *lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" };
56
57/* variables for used to print from font file */
58int fontSet = 0; /* Has the font file been read */
59struct header header;
60struct dispatch dispatch[256];
61char *bits;
62char *fontFile = "/usr/lib/vfont/R.6";
fddad162
RC
63
64main(argc, argv)
e853d173 65int argc;
fddad162
RC
66char **argv;
67{
e853d173 68 extern int cleanup();
265c917a
RC
69 register char *cp1, *arg;
70 register i;
e853d173 71 int again;
fddad162 72
e853d173
RC
73 infile = stdin;
74 while (argc > 1 && argv[1][0] == '-') {
75 argc--;
76 arg = *++argv;
77 switch (*++arg) {
78 case 'W':
265c917a
RC
79 DevRange = 2048;
80 DevRange8 = 2048/8;
e853d173
RC
81 BytesPerLine = 880;
82 lpargs[1] = "-Pversatec";
83 break;
84 case 'V':
85 DevRange = 1536;
265c917a 86 DevRange8 = 1536/8;
e853d173
RC
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 }
fddad162 98 }
e853d173
RC
99 if (argc > 1) {
100 if ((infile = fopen(*++argv, "r")) == NULL) {
101 perror(*argv);
102 cleanup();
fddad162 103 }
fddad162 104 }
e853d173
RC
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);
265c917a
RC
116 if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
117 fprintf(stderr, "vplot: ran out of memory\n");
118 cleanup();
119 }
e853d173 120 do {
265c917a
RC
121 if ((pfp = fopen(picture, "w")) == NULL) {
122 fprintf(stderr, "vplot: can't create %s\n", picture);
e853d173
RC
123 cleanup();
124 }
e853d173 125 i = strlen(picture) + 1;
265c917a 126 if ((arg = (char *) malloc(i)) == NULL) {
e853d173
RC
127 fprintf(stderr, "ran out of memory\n");
128 cleanup();
129 }
130 strcpy(arg, picture);
131 lpargs[lparg++] = arg;
132 picture[run]++;
265c917a
RC
133 arg = &obuf[bufsize];
134 for (cp1 = obuf; cp1 < arg; )
135 *cp1++ = 0;
e853d173
RC
136
137 again = getpict();
138
265c917a
RC
139 for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) {
140 fwrite(cp1, sizeof(char), DevRange8, pfp);
141 fseek(pfp, (long) BytesPerLine - DevRange8, 1);
e853d173 142 }
265c917a 143 fclose(pfp);
e853d173
RC
144 } while (again);
145 lpargs[lparg] = 0;
146 execv(LPR, lpargs);
147 fprintf(stderr, "can't exec %s\n", LPR);
148 cleanup();
fddad162
RC
149}
150
151getpict()
152{
153 register x1, y1;
154
e853d173
RC
155 for (;;) switch (x1 = getc(infile)) {
156
157 case '\n':
158 continue;
fddad162
RC
159
160 case 's':
e853d173
RC
161 botx = getinteger(infile);
162 boty = getinteger(infile);
163 topx = getinteger(infile);
164 topy = getinteger(infile);
fddad162
RC
165 delx = topx-botx;
166 dely = topy-boty;
167 if (dely/delx > 1536./2048.)
168 del = dely;
169 else
e853d173 170 del = delx;
fddad162 171 centx = 0;
e853d173 172 centx = (DevRange - mapx(topx))/2;
fddad162
RC
173 centy = 0;
174 centy = mapy(topy) / 2;
175 continue;
176
e853d173
RC
177 case 'b':
178 x1 = getc(infile);
179 continue;
180
fddad162
RC
181 case 'l':
182 done1 |= 01;
e853d173
RC
183 x1 = mapx(getinteger(infile));
184 y1 = mapy(getinteger(infile));
185 lastx = mapx(getinteger(infile));
186 lasty = mapy(getinteger(infile));
fddad162
RC
187 line(x1, y1, lastx, lasty);
188 continue;
189
e853d173
RC
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
fddad162 214 case 'm':
e853d173
RC
215 lastx = mapx(getinteger(infile));
216 lasty = mapy(getinteger(infile));
fddad162
RC
217 continue;
218
219 case 't':
e853d173
RC
220 lastx = lastx - 6;
221 lasty = lasty + 6;
fddad162 222 done1 |= 01;
e853d173 223 while ((x1 = getc(infile)) != '\n')
fddad162
RC
224 plotch(x1);
225 continue;
226
227 case 'e':
e853d173
RC
228 if (done1)
229 return(1);
fddad162
RC
230 continue;
231
232 case 'p':
233 done1 |= 01;
e853d173
RC
234 lastx = mapx(getinteger(infile));
235 lasty = mapy(getinteger(infile));
fddad162
RC
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;
e853d173
RC
244 x1 = mapx(getinteger(infile));
245 y1 = mapy(getinteger(infile));
fddad162
RC
246 line(lastx, lasty, x1, y1);
247 lastx = x1;
248 lasty = y1;
249 continue;
250
251 case 'f':
e853d173
RC
252 getinteger(infile);
253 getc(infile);
254 switch (getc(infile)) {
fddad162
RC
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 }
e853d173
RC
272 while ((x1 = getc(infile)) != '\n')
273 if (x1 == EOF)
274 return(0);
fddad162
RC
275 continue;
276
277 case 'd':
e853d173
RC
278 getinteger(infile);
279 getinteger(infile);
280 getinteger(infile);
281 x1 = getinteger(infile);
fddad162 282 while (--x1 >= 0)
e853d173 283 getinteger(infile);
fddad162
RC
284 continue;
285
e853d173
RC
286 case 0: /* ignore null characters */
287 continue;
288
289 case 255:
290 case EOF:
291 return(0);
fddad162
RC
292
293 default:
e853d173
RC
294 fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
295 cleanup();
fddad162
RC
296 }
297}
298
e853d173
RC
299plotch(ch)
300char ch;
fddad162 301{
e853d173
RC
302 register int i,j,k;
303 register char *ptr,c;
304 int nbytes;
fddad162 305
e853d173
RC
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 }
fddad162 319 }
e853d173
RC
320 if (ch != ' ')
321 lastx += dispatch[ch].width;
322 else
323 lastx += dispatch['a'].width;
fddad162
RC
324}
325
e853d173 326InitFont()
fddad162 327{
e853d173
RC
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();
fddad162 339 }
e853d173
RC
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();
fddad162
RC
368 }
369}
370
371line(x0, y0, x1, y1)
372register 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) {
e853d173
RC
394 if ((x0+slope*y0) & linmod)
395 point(x0, y0);
fddad162
RC
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) {
e853d173 404 if ((x0+slope*y0) & linmod)
fddad162
RC
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 }
e853d173 414 if ((x1+slope*y1) & linmod)
fddad162
RC
415 point(x1, y1);
416}
417
e853d173
RC
418#define labs(a) (a >= 0 ? a : -a)
419
420circle(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 */
fddad162 454point(x, y)
e853d173 455register int x, y;
fddad162 456{
265c917a 457 register unsigned byte;
fddad162 458
265c917a
RC
459 byte = y * DevRange8 + (x >> 3);
460 if (byte < bufsize)
461 obuf[byte] |= 1 << (7 - (x & 07));
fddad162
RC
462}
463
e853d173 464cleanup()
fddad162 465{
e853d173
RC
466 while (picture[run] != 'a') {
467 unlink(picture);
468 picture[run]--;
469 }
fddad162
RC
470 exit(1);
471}
472
e853d173
RC
473getinteger(f)
474FILE *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);
fddad162 484}