1*11711Sralph /* VPLOT: version 4.2 updated 03/24/83 211516Sralph * 311517Sralph * Reads standard graphics input and produces a plot on the 411517Sralph * Varian or Versatec 511516Sralph */ 611517Sralph #include <stdio.h> 711516Sralph #include <signal.h> 811517Sralph #include <vfont.h> 911516Sralph 1011517Sralph #define LPR "/usr/ucb/lpr" 1111517Sralph 1211517Sralph #define mapx(x) ((DevRange*((x)-botx)/del)+centx) 1311517Sralph #define mapy(y) ((DevRange*(del-(y)+boty)/del)-centy) 1411516Sralph #define SOLID -1 1511516Sralph #define DOTTED 014 1611516Sralph #define SHORTDASHED 034 1711516Sralph #define DOTDASHED 054 1811516Sralph #define LONGDASHED 074 1911516Sralph 20*11711Sralph char *Sid = "@(#)\t03/24/83"; 2111517Sralph 2211516Sralph int linmod = SOLID; 2311516Sralph int done1; 2411516Sralph char chrtab[][16]; 25*11711Sralph char *obuf; 26*11711Sralph int bufsize; 2711516Sralph int lastx; 2811516Sralph int lasty; 2911517Sralph int radius, startx, starty, endx, endy; 3011517Sralph double topx; 3111517Sralph double topy; 3211517Sralph double botx; 3311517Sralph double boty; 3411517Sralph int centx = 0; 3511517Sralph int centy = 0; 3611517Sralph double delx; 3711517Sralph double dely; 3811517Sralph double del; 3911516Sralph 4011517Sralph int warned = 0; /* Indicates whether the warning message about 4111517Sralph * unimplemented routines has been printed */ 4211517Sralph 4311517Sralph FILE *infile; 44*11711Sralph FILE *pfp; /* output file */ 4511517Sralph char picture[] = "/usr/tmp/rastAXXXXXX"; 4611517Sralph int run = 13; /* index of 'a' in picture[] */ 4711517Sralph int DevRange = 1536; /* output array size (square) in pixels */ 48*11711Sralph int DevRange8 = 1536/8; /* output array size in bytes */ 4911517Sralph int BytesPerLine = 264; /* Bytes per raster line (physical) */ 5011517Sralph int lparg = 7; /* index into lpargs */ 5111516Sralph 5211517Sralph char *lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", "vplot" }; 5311517Sralph 5411517Sralph /* variables for used to print from font file */ 5511517Sralph int fontSet = 0; /* Has the font file been read */ 5611517Sralph struct header header; 5711517Sralph struct dispatch dispatch[256]; 5811517Sralph char *bits; 5911517Sralph char *fontFile = "/usr/lib/vfont/R.6"; 6011517Sralph 6111516Sralph main(argc, argv) 6211517Sralph int argc; 6311516Sralph char **argv; 6411516Sralph { 6511517Sralph extern int cleanup(); 66*11711Sralph register char *cp1, *arg; 67*11711Sralph register i; 6811517Sralph int again; 6911516Sralph 7011517Sralph infile = stdin; 7111517Sralph while (argc > 1 && argv[1][0] == '-') { 7211517Sralph argc--; 7311517Sralph arg = *++argv; 7411517Sralph switch (*++arg) { 7511517Sralph case 'W': 76*11711Sralph DevRange = 2048; 77*11711Sralph DevRange8 = 2048/8; 7811517Sralph BytesPerLine = 880; 7911517Sralph lpargs[1] = "-Pversatec"; 8011517Sralph break; 8111517Sralph case 'V': 8211517Sralph DevRange = 1536; 83*11711Sralph DevRange8 = 1536/8; 8411517Sralph BytesPerLine = 264; 8511517Sralph lpargs[1] = "-Pvarian"; 8611517Sralph break; 8711517Sralph case 'b': 8811517Sralph if (argc-- > 1) 8911517Sralph lpargs[lparg-1] = *++argv; 9011517Sralph break; 9111517Sralph default: 9211517Sralph fprintf(stderr, "vplot: %s option unknown\n", *argv); 9311517Sralph break; 9411517Sralph } 9511516Sralph } 9611517Sralph if (argc > 1) { 9711517Sralph if ((infile = fopen(*++argv, "r")) == NULL) { 9811517Sralph perror(*argv); 9911517Sralph cleanup(); 10011517Sralph } 10111517Sralph } 10211517Sralph 10311517Sralph /* init constants for scaling */ 10411517Sralph topx = topy = DevRange; 10511517Sralph botx = boty = 0; 10611517Sralph delx = dely = del = DevRange; 10711517Sralph centx = (DevRange - mapx(topx))/2; 10811517Sralph centy = mapy(topy)/2; 10911517Sralph signal(SIGTERM, cleanup); 11011516Sralph if (signal(SIGINT, SIG_IGN) != SIG_IGN) 11111517Sralph signal(SIGINT, cleanup); 11211517Sralph mktemp(picture); 113*11711Sralph if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) { 114*11711Sralph fprintf(stderr, "vplot: ran out of memory\n"); 115*11711Sralph cleanup(); 116*11711Sralph } 11711517Sralph do { 118*11711Sralph if ((pfp = fopen(picture, "w")) == NULL) { 119*11711Sralph fprintf(stderr, "vplot: can't create %s\n", picture); 12011517Sralph cleanup(); 12111516Sralph } 12211517Sralph i = strlen(picture) + 1; 123*11711Sralph if ((arg = (char *) malloc(i)) == NULL) { 12411517Sralph fprintf(stderr, "ran out of memory\n"); 12511517Sralph cleanup(); 12611517Sralph } 12711517Sralph strcpy(arg, picture); 12811517Sralph lpargs[lparg++] = arg; 12911517Sralph picture[run]++; 130*11711Sralph arg = &obuf[bufsize]; 131*11711Sralph for (cp1 = obuf; cp1 < arg; ) 132*11711Sralph *cp1++ = 0; 13311517Sralph 13411517Sralph again = getpict(); 13511517Sralph 136*11711Sralph for (cp1 = obuf; cp1 < arg; cp1 += DevRange8) { 137*11711Sralph fwrite(cp1, sizeof(char), DevRange8, pfp); 138*11711Sralph fseek(pfp, (long) BytesPerLine - DevRange8, 1); 13911517Sralph } 140*11711Sralph fclose(pfp); 14111517Sralph } while (again); 14211517Sralph lpargs[lparg] = 0; 14311517Sralph execv(LPR, lpargs); 14411517Sralph fprintf(stderr, "can't exec %s\n", LPR); 14511517Sralph cleanup(); 14611516Sralph } 14711516Sralph 14811516Sralph getpict() 14911516Sralph { 15011516Sralph register x1, y1; 15111516Sralph 15211517Sralph for (;;) switch (x1 = getc(infile)) { 15311516Sralph 15411517Sralph case '\n': 15511517Sralph continue; 15611517Sralph 15711516Sralph case 's': 15811517Sralph botx = getinteger(infile); 15911517Sralph boty = getinteger(infile); 16011517Sralph topx = getinteger(infile); 16111517Sralph topy = getinteger(infile); 16211516Sralph delx = topx-botx; 16311516Sralph dely = topy-boty; 16411516Sralph if (dely/delx > 1536./2048.) 16511516Sralph del = dely; 16611516Sralph else 16711517Sralph del = delx; 16811516Sralph centx = 0; 16911517Sralph centx = (DevRange - mapx(topx))/2; 17011516Sralph centy = 0; 17111516Sralph centy = mapy(topy) / 2; 17211516Sralph continue; 17311516Sralph 17411517Sralph case 'b': 17511517Sralph x1 = getc(infile); 17611517Sralph continue; 17711517Sralph 17811516Sralph case 'l': 17911516Sralph done1 |= 01; 18011517Sralph x1 = mapx(getinteger(infile)); 18111517Sralph y1 = mapy(getinteger(infile)); 18211517Sralph lastx = mapx(getinteger(infile)); 18311517Sralph lasty = mapy(getinteger(infile)); 18411516Sralph line(x1, y1, lastx, lasty); 18511516Sralph continue; 18611516Sralph 18711517Sralph case 'c': 18811517Sralph x1 = mapx(getinteger(infile)); 18911517Sralph y1 = mapy(getinteger(infile)); 19011517Sralph radius = mapx(getinteger(infile)); 19111517Sralph if (!warned) { 19211517Sralph fprintf(stderr,"Circles are Implemented\n"); 19311517Sralph warned++; 19411517Sralph } 19511517Sralph circle(x1, y1, radius); 19611517Sralph continue; 19711517Sralph 19811517Sralph case 'a': 19911517Sralph x1 = mapx(getinteger(infile)); 20011517Sralph y1 = mapy(getinteger(infile)); 20111517Sralph startx = mapx(getinteger(infile)); 20211517Sralph starty = mapy(getinteger(infile)); 20311517Sralph endx = mapx(getinteger(infile)); 20411517Sralph endy = mapy(getinteger(infile)); 20511517Sralph if (!warned) { 20611517Sralph fprintf(stderr,"Circles and Arcs are unimplemented\n"); 20711517Sralph warned++; 20811517Sralph } 20911517Sralph continue; 21011517Sralph 21111516Sralph case 'm': 21211517Sralph lastx = mapx(getinteger(infile)); 21311517Sralph lasty = mapy(getinteger(infile)); 21411516Sralph continue; 21511516Sralph 21611516Sralph case 't': 21711517Sralph lastx = lastx - 6; 21811517Sralph lasty = lasty + 6; 21911516Sralph done1 |= 01; 22011517Sralph while ((x1 = getc(infile)) != '\n') 22111516Sralph plotch(x1); 22211516Sralph continue; 22311516Sralph 22411516Sralph case 'e': 22511517Sralph if (done1) 22611517Sralph return(1); 22711516Sralph continue; 22811516Sralph 22911516Sralph case 'p': 23011516Sralph done1 |= 01; 23111517Sralph lastx = mapx(getinteger(infile)); 23211517Sralph lasty = mapy(getinteger(infile)); 23311516Sralph point(lastx, lasty); 23411516Sralph point(lastx+1, lasty); 23511516Sralph point(lastx, lasty+1); 23611516Sralph point(lastx+1, lasty+1); 23711516Sralph continue; 23811516Sralph 23911516Sralph case 'n': 24011516Sralph done1 |= 01; 24111517Sralph x1 = mapx(getinteger(infile)); 24211517Sralph y1 = mapy(getinteger(infile)); 24311516Sralph line(lastx, lasty, x1, y1); 24411516Sralph lastx = x1; 24511516Sralph lasty = y1; 24611516Sralph continue; 24711516Sralph 24811516Sralph case 'f': 24911517Sralph getinteger(infile); 25011517Sralph getc(infile); 25111517Sralph switch (getc(infile)) { 25211516Sralph case 't': 25311516Sralph linmod = DOTTED; 25411516Sralph break; 25511516Sralph default: 25611516Sralph case 'i': 25711516Sralph linmod = SOLID; 25811516Sralph break; 25911516Sralph case 'g': 26011516Sralph linmod = LONGDASHED; 26111516Sralph break; 26211516Sralph case 'r': 26311516Sralph linmod = SHORTDASHED; 26411516Sralph break; 26511516Sralph case 'd': 26611516Sralph linmod = DOTDASHED; 26711516Sralph break; 26811516Sralph } 26911517Sralph while ((x1 = getc(infile)) != '\n') 27011517Sralph if (x1 == EOF) 27111517Sralph return(0); 27211516Sralph continue; 27311516Sralph 27411516Sralph case 'd': 27511517Sralph getinteger(infile); 27611517Sralph getinteger(infile); 27711517Sralph getinteger(infile); 27811517Sralph x1 = getinteger(infile); 27911516Sralph while (--x1 >= 0) 28011517Sralph getinteger(infile); 28111516Sralph continue; 28211516Sralph 28311517Sralph case 0: /* ignore null characters */ 28411517Sralph continue; 28511516Sralph 28611517Sralph case 255: 28711517Sralph case EOF: 28811517Sralph return(0); 28911517Sralph 29011516Sralph default: 29111517Sralph fprintf(stderr, "Input format error %c(%o)\n",x1,x1); 29211517Sralph cleanup(); 29311516Sralph } 29411516Sralph } 29511516Sralph 29611517Sralph plotch(ch) 29711517Sralph char ch; 29811516Sralph { 29911517Sralph register int i,j,k; 30011517Sralph register char *ptr,c; 30111517Sralph int nbytes; 30211516Sralph 30311517Sralph if (!fontSet) 30411517Sralph InitFont(); /* Read font if not already read */ 30511517Sralph 30611517Sralph ptr = bits + dispatch[ch].addr; 30711517Sralph 30811517Sralph for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) { 30911517Sralph nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8; 31011517Sralph for (j = 0; j < nbytes; j++) { 31111517Sralph c = *ptr++; 31211517Sralph for (k = 7; k >= 0; k--) 31311517Sralph if ((c >> k) & 1) 31411517Sralph point(lastx+7-k+j*8-dispatch[ch].left, lasty-i); 31511517Sralph } 31611516Sralph } 31711517Sralph if (ch != ' ') 31811517Sralph lastx += dispatch[ch].width; 31911517Sralph else 32011517Sralph lastx += dispatch['a'].width; 32111516Sralph } 32211516Sralph 32311517Sralph InitFont() 32411516Sralph { 32511517Sralph char *s; 32611517Sralph int fonts; 32711517Sralph int i; 32811516Sralph 32911517Sralph fontSet = 1; 33011517Sralph /* Get the font file */ 33111517Sralph s = fontFile; 33211517Sralph if ((fonts = open(s, 0)) == -1) { 33311517Sralph perror(s); 33411517Sralph fprintf(stderr, "Can't get font file"); 33511517Sralph cleanup(); 33611516Sralph } 33711517Sralph /* Get the header and check magic number */ 33811517Sralph if (read(fonts, &header, sizeof(header)) != sizeof(header)) { 33911517Sralph perror(s); 34011517Sralph fprintf(stderr, "Bad read in font file"); 34111517Sralph cleanup(); 34211516Sralph } 34311517Sralph if (header.magic != 0436) { 34411517Sralph fprintf(stderr,"Bad magic numer in font file"); 34511517Sralph cleanup(); 34611517Sralph } 34711517Sralph /* Get dispatches */ 34811517Sralph if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) { 34911517Sralph perror(s); 35011517Sralph fprintf(stderr, "Bad read in font file"); 35111517Sralph cleanup(); 35211517Sralph } 35311517Sralph /* Allocate space for bit map and read in bits */ 35411517Sralph bits = (char *) malloc(header.size); 35511517Sralph if (read(fonts, bits, header.size) != header.size) { 35611517Sralph perror(s); 35711517Sralph fprintf(stderr,"Can't read bit map in font file"); 35811517Sralph cleanup(); 35911517Sralph } 36011517Sralph /* Close font file */ 36111517Sralph if (close(fonts) != 0) { 36211517Sralph perror(s); 36311517Sralph fprintf(stderr,"Can't close font file"); 36411517Sralph cleanup(); 36511517Sralph } 36611516Sralph } 36711516Sralph 36811516Sralph line(x0, y0, x1, y1) 36911516Sralph register x0, y0; 37011516Sralph { 37111516Sralph int dx, dy; 37211516Sralph int xinc, yinc; 37311516Sralph register res1; 37411516Sralph int res2; 37511516Sralph int slope; 37611516Sralph 37711516Sralph xinc = 1; 37811516Sralph yinc = 1; 37911516Sralph if ((dx = x1-x0) < 0) { 38011516Sralph xinc = -1; 38111516Sralph dx = -dx; 38211516Sralph } 38311516Sralph if ((dy = y1-y0) < 0) { 38411516Sralph yinc = -1; 38511516Sralph dy = -dy; 38611516Sralph } 38711516Sralph slope = xinc*yinc; 38811516Sralph res1 = 0; 38911516Sralph res2 = 0; 39011516Sralph if (dx >= dy) while (x0 != x1) { 39111517Sralph if ((x0+slope*y0) & linmod) 39211517Sralph point(x0, y0); 39311516Sralph if (res1 > res2) { 39411516Sralph res2 += dx - res1; 39511516Sralph res1 = 0; 39611516Sralph y0 += yinc; 39711516Sralph } 39811516Sralph res1 += dy; 39911516Sralph x0 += xinc; 40011516Sralph } else while (y0 != y1) { 40111517Sralph if ((x0+slope*y0) & linmod) 40211516Sralph point(x0, y0); 40311516Sralph if (res1 > res2) { 40411516Sralph res2 += dy - res1; 40511516Sralph res1 = 0; 40611516Sralph x0 += xinc; 40711516Sralph } 40811516Sralph res1 += dx; 40911516Sralph y0 += yinc; 41011516Sralph } 41111517Sralph if ((x1+slope*y1) & linmod) 41211516Sralph point(x1, y1); 41311516Sralph } 41411516Sralph 41511517Sralph #define labs(a) (a >= 0 ? a : -a) 41611517Sralph 41711517Sralph circle(x,y,c) 41811517Sralph { 41911517Sralph register dx, dy; 42011517Sralph long ep; 42111517Sralph int de; 42211517Sralph 42311517Sralph dx = 0; 42411517Sralph ep = 0; 42511517Sralph for (dy=c; dy>=dx; dy--) { 42611517Sralph for (;;) { 42711517Sralph point(x+dx, y+dy); 42811517Sralph point(x-dx, y+dy); 42911517Sralph point(x+dx, y-dy); 43011517Sralph point(x-dx, y-dy); 43111517Sralph point(x+dy, y+dx); 43211517Sralph point(x-dy, y+dx); 43311517Sralph point(x+dy, y-dx); 43411517Sralph point(x-dy, y-dx); 43511517Sralph ep += 2*dx + 1; 43611517Sralph de = -2*dy + 1; 43711517Sralph dx++; 43811517Sralph if (labs(ep) >= labs(ep+de)) { 43911517Sralph ep += de; 44011517Sralph break; 44111517Sralph } 44211517Sralph } 44311517Sralph } 44411517Sralph } 44511517Sralph 44611517Sralph /* 44711517Sralph * Points should be in the range 0 <= x (or y) <= DevRange. 44811517Sralph * The origin is the top left-hand corner with increasing x towards the 44911517Sralph * right and increasing y going down. 45011517Sralph */ 45111516Sralph point(x, y) 45211517Sralph register int x, y; 45311516Sralph { 454*11711Sralph register unsigned byte; 45511516Sralph 456*11711Sralph byte = y * DevRange8 + (x >> 3); 457*11711Sralph if (byte < bufsize) 458*11711Sralph obuf[byte] |= 1 << (7 - (x & 07)); 45911516Sralph } 46011516Sralph 46111517Sralph cleanup() 46211516Sralph { 46311517Sralph while (picture[run] != 'a') { 46411517Sralph unlink(picture); 46511517Sralph picture[run]--; 46611517Sralph } 46711516Sralph exit(1); 46811516Sralph } 46911516Sralph 47011517Sralph getinteger(f) 47111517Sralph FILE *f; 47211517Sralph { 47311517Sralph register int low, high, result; 47411517Sralph 47511517Sralph low = getc(f); 47611517Sralph high = getc(f); 47711517Sralph result = ((high << 8) | low); 47811517Sralph if (high > 127) 47911517Sralph result |= ~0xffff; 48011517Sralph return(result); 48111517Sralph } 482