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