|
|
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.