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