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