1*14500Ssam #ifndef lint
2*14500Ssam static char sccsid[] = "@(#)vplot.c 4.3 (Berkeley) 08/11/83";
3*14500Ssam #endif
4*14500Ssam
5*14500Ssam /*
611517Sralph * Reads standard graphics input and produces a plot on the
711517Sralph * Varian or Versatec
811516Sralph */
911517Sralph #include <stdio.h>
1011516Sralph #include <signal.h>
1111517Sralph #include <vfont.h>
1211516Sralph
1311517Sralph #define LPR "/usr/ucb/lpr"
1411517Sralph
1511517Sralph #define mapx(x) ((DevRange*((x)-botx)/del)+centx)
1611517Sralph #define mapy(y) ((DevRange*(del-(y)+boty)/del)-centy)
1711516Sralph #define SOLID -1
1811516Sralph #define DOTTED 014
1911516Sralph #define SHORTDASHED 034
2011516Sralph #define DOTDASHED 054
2111516Sralph #define LONGDASHED 074
2211516Sralph
23*14500Ssam char *Sid = "@(#)\t08/11/83";
2411517Sralph
2511516Sralph int linmod = SOLID;
2611516Sralph int done1;
2711516Sralph char chrtab[][16];
2811711Sralph char *obuf;
2911711Sralph int bufsize;
3011516Sralph int lastx;
3111516Sralph int lasty;
3211517Sralph int radius, startx, starty, endx, endy;
3311517Sralph double topx;
3411517Sralph double topy;
3511517Sralph double botx;
3611517Sralph double boty;
3711517Sralph int centx = 0;
3811517Sralph int centy = 0;
3911517Sralph double delx;
4011517Sralph double dely;
4111517Sralph double del;
4211516Sralph
4311517Sralph int warned = 0; /* Indicates whether the warning message about
4411517Sralph * unimplemented routines has been printed */
4511517Sralph
4611517Sralph FILE *infile;
4711711Sralph FILE *pfp; /* output file */
4811517Sralph char picture[] = "/usr/tmp/rastAXXXXXX";
4911517Sralph int run = 13; /* index of 'a' in picture[] */
5011517Sralph int DevRange = 1536; /* output array size (square) in pixels */
5111711Sralph int DevRange8 = 1536/8; /* output array size in bytes */
5211517Sralph int BytesPerLine = 264; /* Bytes per raster line (physical) */
5311517Sralph int lparg = 7; /* index into lpargs */
5411516Sralph
5511517Sralph char *lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" };
5611517Sralph
5711517Sralph /* variables for used to print from font file */
5811517Sralph int fontSet = 0; /* Has the font file been read */
5911517Sralph struct header header;
6011517Sralph struct dispatch dispatch[256];
6111517Sralph char *bits;
6211517Sralph char *fontFile = "/usr/lib/vfont/R.6";
6311517Sralph
main(argc,argv)6411516Sralph main(argc, argv)
6511517Sralph int argc;
6611516Sralph char **argv;
6711516Sralph {
6811517Sralph extern int cleanup();
6911711Sralph register char *cp1, *arg;
7011711Sralph register i;
7111517Sralph int again;
7211516Sralph
7311517Sralph infile = stdin;
7411517Sralph while (argc > 1 && argv[1][0] == '-') {
7511517Sralph argc--;
7611517Sralph arg = *++argv;
7711517Sralph switch (*++arg) {
7811517Sralph case 'W':
7911711Sralph DevRange = 2048;
8011711Sralph DevRange8 = 2048/8;
8111517Sralph BytesPerLine = 880;
8211517Sralph lpargs[1] = "-Pversatec";
8311517Sralph break;
8411517Sralph case 'V':
8511517Sralph DevRange = 1536;
8611711Sralph DevRange8 = 1536/8;
8711517Sralph BytesPerLine = 264;
8811517Sralph lpargs[1] = "-Pvarian";
8911517Sralph break;
9011517Sralph case 'b':
9111517Sralph if (argc-- > 1)
9211517Sralph lpargs[lparg-1] = *++argv;
9311517Sralph break;
9411517Sralph default:
9511517Sralph fprintf(stderr, "vplot: %s option unknown\n", *argv);
9611517Sralph break;
9711517Sralph }
9811516Sralph }
9911517Sralph if (argc > 1) {
10011517Sralph if ((infile = fopen(*++argv, "r")) == NULL) {
10111517Sralph perror(*argv);
10211517Sralph cleanup();
10311517Sralph }
10411517Sralph }
10511517Sralph
10611517Sralph /* init constants for scaling */
10711517Sralph topx = topy = DevRange;
10811517Sralph botx = boty = 0;
10911517Sralph delx = dely = del = DevRange;
11011517Sralph centx = (DevRange - mapx(topx))/2;
11111517Sralph centy = mapy(topy)/2;
11211517Sralph signal(SIGTERM, cleanup);
11311516Sralph if (signal(SIGINT, SIG_IGN) != SIG_IGN)
11411517Sralph signal(SIGINT, cleanup);
11511517Sralph mktemp(picture);
11611711Sralph if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) {
11711711Sralph fprintf(stderr, "vplot: ran out of memory\n");
11811711Sralph cleanup();
11911711Sralph }
12011517Sralph do {
12111711Sralph if ((pfp = fopen(picture, "w")) == NULL) {
12211711Sralph fprintf(stderr, "vplot: can't create %s\n", picture);
12311517Sralph cleanup();
12411516Sralph }
12511517Sralph i = strlen(picture) + 1;
12611711Sralph if ((arg = (char *) malloc(i)) == NULL) {
12711517Sralph fprintf(stderr, "ran out of memory\n");
12811517Sralph cleanup();
12911517Sralph }
13011517Sralph strcpy(arg, picture);
13111517Sralph lpargs[lparg++] = arg;
13211517Sralph picture[run]++;
13311711Sralph arg = &obuf[bufsize];
13411711Sralph for (cp1 = obuf; cp1 < arg; )
13511711Sralph *cp1++ = 0;
13611517Sralph
13711517Sralph again = getpict();
13811517Sralph
13911711Sralph for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) {
14011711Sralph fwrite(cp1, sizeof(char), DevRange8, pfp);
14111711Sralph fseek(pfp, (long) BytesPerLine - DevRange8, 1);
14211517Sralph }
14311711Sralph fclose(pfp);
14411517Sralph } while (again);
14511517Sralph lpargs[lparg] = 0;
14611517Sralph execv(LPR, lpargs);
14711517Sralph fprintf(stderr, "can't exec %s\n", LPR);
14811517Sralph cleanup();
14911516Sralph }
15011516Sralph
getpict()15111516Sralph getpict()
15211516Sralph {
15311516Sralph register x1, y1;
15411516Sralph
15511517Sralph for (;;) switch (x1 = getc(infile)) {
15611516Sralph
15711517Sralph case '\n':
15811517Sralph continue;
15911517Sralph
16011516Sralph case 's':
16111517Sralph botx = getinteger(infile);
16211517Sralph boty = getinteger(infile);
16311517Sralph topx = getinteger(infile);
16411517Sralph topy = getinteger(infile);
16511516Sralph delx = topx-botx;
16611516Sralph dely = topy-boty;
16711516Sralph if (dely/delx > 1536./2048.)
16811516Sralph del = dely;
16911516Sralph else
17011517Sralph del = delx;
17111516Sralph centx = 0;
17211517Sralph centx = (DevRange - mapx(topx))/2;
17311516Sralph centy = 0;
17411516Sralph centy = mapy(topy) / 2;
17511516Sralph continue;
17611516Sralph
17711517Sralph case 'b':
17811517Sralph x1 = getc(infile);
17911517Sralph continue;
18011517Sralph
18111516Sralph case 'l':
18211516Sralph done1 |= 01;
18311517Sralph x1 = mapx(getinteger(infile));
18411517Sralph y1 = mapy(getinteger(infile));
18511517Sralph lastx = mapx(getinteger(infile));
18611517Sralph lasty = mapy(getinteger(infile));
18711516Sralph line(x1, y1, lastx, lasty);
18811516Sralph continue;
18911516Sralph
19011517Sralph case 'c':
19111517Sralph x1 = mapx(getinteger(infile));
19211517Sralph y1 = mapy(getinteger(infile));
19311517Sralph radius = mapx(getinteger(infile));
19411517Sralph if (!warned) {
19511517Sralph fprintf(stderr,"Circles are Implemented\n");
19611517Sralph warned++;
19711517Sralph }
19811517Sralph circle(x1, y1, radius);
19911517Sralph continue;
20011517Sralph
20111517Sralph case 'a':
20211517Sralph x1 = mapx(getinteger(infile));
20311517Sralph y1 = mapy(getinteger(infile));
20411517Sralph startx = mapx(getinteger(infile));
20511517Sralph starty = mapy(getinteger(infile));
20611517Sralph endx = mapx(getinteger(infile));
20711517Sralph endy = mapy(getinteger(infile));
20811517Sralph if (!warned) {
20911517Sralph fprintf(stderr,"Circles and Arcs are unimplemented\n");
21011517Sralph warned++;
21111517Sralph }
21211517Sralph continue;
21311517Sralph
21411516Sralph case 'm':
21511517Sralph lastx = mapx(getinteger(infile));
21611517Sralph lasty = mapy(getinteger(infile));
21711516Sralph continue;
21811516Sralph
21911516Sralph case 't':
22011517Sralph lastx = lastx - 6;
22111517Sralph lasty = lasty + 6;
22211516Sralph done1 |= 01;
22311517Sralph while ((x1 = getc(infile)) != '\n')
22411516Sralph plotch(x1);
22511516Sralph continue;
22611516Sralph
22711516Sralph case 'e':
22811517Sralph if (done1)
22911517Sralph return(1);
23011516Sralph continue;
23111516Sralph
23211516Sralph case 'p':
23311516Sralph done1 |= 01;
23411517Sralph lastx = mapx(getinteger(infile));
23511517Sralph lasty = mapy(getinteger(infile));
23611516Sralph point(lastx, lasty);
23711516Sralph point(lastx+1, lasty);
23811516Sralph point(lastx, lasty+1);
23911516Sralph point(lastx+1, lasty+1);
24011516Sralph continue;
24111516Sralph
24211516Sralph case 'n':
24311516Sralph done1 |= 01;
24411517Sralph x1 = mapx(getinteger(infile));
24511517Sralph y1 = mapy(getinteger(infile));
24611516Sralph line(lastx, lasty, x1, y1);
24711516Sralph lastx = x1;
24811516Sralph lasty = y1;
24911516Sralph continue;
25011516Sralph
25111516Sralph case 'f':
25211517Sralph getinteger(infile);
25311517Sralph getc(infile);
25411517Sralph switch (getc(infile)) {
25511516Sralph case 't':
25611516Sralph linmod = DOTTED;
25711516Sralph break;
25811516Sralph default:
25911516Sralph case 'i':
26011516Sralph linmod = SOLID;
26111516Sralph break;
26211516Sralph case 'g':
26311516Sralph linmod = LONGDASHED;
26411516Sralph break;
26511516Sralph case 'r':
26611516Sralph linmod = SHORTDASHED;
26711516Sralph break;
26811516Sralph case 'd':
26911516Sralph linmod = DOTDASHED;
27011516Sralph break;
27111516Sralph }
27211517Sralph while ((x1 = getc(infile)) != '\n')
27311517Sralph if (x1 == EOF)
27411517Sralph return(0);
27511516Sralph continue;
27611516Sralph
27711516Sralph case 'd':
27811517Sralph getinteger(infile);
27911517Sralph getinteger(infile);
28011517Sralph getinteger(infile);
28111517Sralph x1 = getinteger(infile);
28211516Sralph while (--x1 >= 0)
28311517Sralph getinteger(infile);
28411516Sralph continue;
28511516Sralph
28611517Sralph case 0: /* ignore null characters */
28711517Sralph continue;
28811516Sralph
28911517Sralph case 255:
29011517Sralph case EOF:
29111517Sralph return(0);
29211517Sralph
29311516Sralph default:
29411517Sralph fprintf(stderr, "Input format error %c(%o)\n",x1,x1);
29511517Sralph cleanup();
29611516Sralph }
29711516Sralph }
29811516Sralph
plotch(ch)29911517Sralph plotch(ch)
30011517Sralph char ch;
30111516Sralph {
30211517Sralph register int i,j,k;
30311517Sralph register char *ptr,c;
30411517Sralph int nbytes;
30511516Sralph
30611517Sralph if (!fontSet)
30711517Sralph InitFont(); /* Read font if not already read */
30811517Sralph
30911517Sralph ptr = bits + dispatch[ch].addr;
31011517Sralph
31111517Sralph for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) {
31211517Sralph nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8;
31311517Sralph for (j = 0; j < nbytes; j++) {
31411517Sralph c = *ptr++;
31511517Sralph for (k = 7; k >= 0; k--)
31611517Sralph if ((c >> k) & 1)
31711517Sralph point(lastx+7-k+j*8-dispatch[ch].left, lasty-i);
31811517Sralph }
31911516Sralph }
32011517Sralph if (ch != ' ')
32111517Sralph lastx += dispatch[ch].width;
32211517Sralph else
32311517Sralph lastx += dispatch['a'].width;
32411516Sralph }
32511516Sralph
InitFont()32611517Sralph InitFont()
32711516Sralph {
32811517Sralph char *s;
32911517Sralph int fonts;
33011517Sralph int i;
33111516Sralph
33211517Sralph fontSet = 1;
33311517Sralph /* Get the font file */
33411517Sralph s = fontFile;
33511517Sralph if ((fonts = open(s, 0)) == -1) {
33611517Sralph perror(s);
33711517Sralph fprintf(stderr, "Can't get font file");
33811517Sralph cleanup();
33911516Sralph }
34011517Sralph /* Get the header and check magic number */
34111517Sralph if (read(fonts, &header, sizeof(header)) != sizeof(header)) {
34211517Sralph perror(s);
34311517Sralph fprintf(stderr, "Bad read in font file");
34411517Sralph cleanup();
34511516Sralph }
34611517Sralph if (header.magic != 0436) {
34711517Sralph fprintf(stderr,"Bad magic numer in font file");
34811517Sralph cleanup();
34911517Sralph }
35011517Sralph /* Get dispatches */
35111517Sralph if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) {
35211517Sralph perror(s);
35311517Sralph fprintf(stderr, "Bad read in font file");
35411517Sralph cleanup();
35511517Sralph }
35611517Sralph /* Allocate space for bit map and read in bits */
35711517Sralph bits = (char *) malloc(header.size);
35811517Sralph if (read(fonts, bits, header.size) != header.size) {
35911517Sralph perror(s);
36011517Sralph fprintf(stderr,"Can't read bit map in font file");
36111517Sralph cleanup();
36211517Sralph }
36311517Sralph /* Close font file */
36411517Sralph if (close(fonts) != 0) {
36511517Sralph perror(s);
36611517Sralph fprintf(stderr,"Can't close font file");
36711517Sralph cleanup();
36811517Sralph }
36911516Sralph }
37011516Sralph
line(x0,y0,x1,y1)37111516Sralph line(x0, y0, x1, y1)
37211516Sralph register x0, y0;
37311516Sralph {
37411516Sralph int dx, dy;
37511516Sralph int xinc, yinc;
37611516Sralph register res1;
37711516Sralph int res2;
37811516Sralph int slope;
37911516Sralph
38011516Sralph xinc = 1;
38111516Sralph yinc = 1;
38211516Sralph if ((dx = x1-x0) < 0) {
38311516Sralph xinc = -1;
38411516Sralph dx = -dx;
38511516Sralph }
38611516Sralph if ((dy = y1-y0) < 0) {
38711516Sralph yinc = -1;
38811516Sralph dy = -dy;
38911516Sralph }
39011516Sralph slope = xinc*yinc;
39111516Sralph res1 = 0;
39211516Sralph res2 = 0;
39311516Sralph if (dx >= dy) while (x0 != x1) {
39411517Sralph if ((x0+slope*y0) & linmod)
39511517Sralph point(x0, y0);
39611516Sralph if (res1 > res2) {
39711516Sralph res2 += dx - res1;
39811516Sralph res1 = 0;
39911516Sralph y0 += yinc;
40011516Sralph }
40111516Sralph res1 += dy;
40211516Sralph x0 += xinc;
40311516Sralph } else while (y0 != y1) {
40411517Sralph if ((x0+slope*y0) & linmod)
40511516Sralph point(x0, y0);
40611516Sralph if (res1 > res2) {
40711516Sralph res2 += dy - res1;
40811516Sralph res1 = 0;
40911516Sralph x0 += xinc;
41011516Sralph }
41111516Sralph res1 += dx;
41211516Sralph y0 += yinc;
41311516Sralph }
41411517Sralph if ((x1+slope*y1) & linmod)
41511516Sralph point(x1, y1);
41611516Sralph }
41711516Sralph
41811517Sralph #define labs(a) (a >= 0 ? a : -a)
41911517Sralph
circle(x,y,c)42011517Sralph circle(x,y,c)
42111517Sralph {
42211517Sralph register dx, dy;
42311517Sralph long ep;
42411517Sralph int de;
42511517Sralph
42611517Sralph dx = 0;
42711517Sralph ep = 0;
42811517Sralph for (dy=c; dy>=dx; dy--) {
42911517Sralph for (;;) {
43011517Sralph point(x+dx, y+dy);
43111517Sralph point(x-dx, y+dy);
43211517Sralph point(x+dx, y-dy);
43311517Sralph point(x-dx, y-dy);
43411517Sralph point(x+dy, y+dx);
43511517Sralph point(x-dy, y+dx);
43611517Sralph point(x+dy, y-dx);
43711517Sralph point(x-dy, y-dx);
43811517Sralph ep += 2*dx + 1;
43911517Sralph de = -2*dy + 1;
44011517Sralph dx++;
44111517Sralph if (labs(ep) >= labs(ep+de)) {
44211517Sralph ep += de;
44311517Sralph break;
44411517Sralph }
44511517Sralph }
44611517Sralph }
44711517Sralph }
44811517Sralph
44911517Sralph /*
45011517Sralph * Points should be in the range 0 <= x (or y) <= DevRange.
45111517Sralph * The origin is the top left-hand corner with increasing x towards the
45211517Sralph * right and increasing y going down.
45311517Sralph */
point(x,y)45411516Sralph point(x, y)
45511517Sralph register int x, y;
45611516Sralph {
45711711Sralph register unsigned byte;
45811516Sralph
45911711Sralph byte = y * DevRange8 + (x >> 3);
46011711Sralph if (byte < bufsize)
46111711Sralph obuf[byte] |= 1 << (7 - (x & 07));
46211516Sralph }
46311516Sralph
cleanup()46411517Sralph cleanup()
46511516Sralph {
46611517Sralph while (picture[run] != 'a') {
46711517Sralph unlink(picture);
46811517Sralph picture[run]--;
46911517Sralph }
47011516Sralph exit(1);
47111516Sralph }
47211516Sralph
getinteger(f)47311517Sralph getinteger(f)
47411517Sralph FILE *f;
47511517Sralph {
47611517Sralph register int low, high, result;
47711517Sralph
47811517Sralph low = getc(f);
47911517Sralph high = getc(f);
48011517Sralph result = ((high << 8) | low);
48111517Sralph if (high > 127)
48211517Sralph result |= ~0xffff;
48311517Sralph return(result);
48411517Sralph }
485