1: #include <errno.h>
   2: #include <signal.h>
   3: #include <stdio.h>
   4: #include <sgtty.h>
   5: #include <pwd.h>
   6: #include <sys/vcmd.h>
   7: #include <vfont.h>
   8: 
   9: /*
  10:  * Cat Simulator for Versatec and Varian
  11:  * Modified for Varian with rotated fonts: wnj 5/30/80.
  12:  *
  13:  * Takes two extra special codes defined by rvsort:
  14:  *	0115 - break for new page, goto (0,0)
  15:  *	0116 - lead 64* following byte
  16:  */
  17: 
  18: static char *sccsid ="@(#)rvcat.c	1.2 (Berkeley) 8/9/81";
  19: 
  20: int prtmode[] = {VPRINT, 0, 0};
  21: int pltmode[] = {VPLOT, 0, 0};
  22: 
  23: #define DISPATCHSIZE        256 /* must be a power of two */
  24: #define CHARMASK        (DISPATCHSIZE-1)
  25: #define NFONTS          25
  26: #define SPECIALFONT     3
  27: #define DSIZ            ((sizeof *dispatch)*DISPATCHSIZE)
  28: #define MAXF            4
  29: 
  30: #define LOCAL_RAILMAG       ".railmag"
  31: #define GLOBAL_RAILMAG      "/usr/lib/vfont/railmag"
  32: 
  33: /*
  34:  * Here we make up for the fact that we only have 2112
  35:  * bits vertically when we need 2200 (11''*200/in), by
  36:  * a 4% vertical size squashing.
  37:  */
  38: #define CONVERT(n)      ((n*(200./432.))*(2112./2200.))
  39: #define RECONVERT(n)        ((n*(432./200.))*(2200./2112.))
  40: 
  41: #define VA_RASTER_LENGTH    2112
  42: 
  43: #define VA_BYTES_PER_LINE   (VA_RASTER_LENGTH/8)
  44: 
  45: #define NLINES          110
  46: #define VA_BUFFER_SIZE      (NLINES*VA_BYTES_PER_LINE)
  47: 
  48: #define FF_LINES        1600    /* Scan lines to output before formfeeding. */
  49: #define PAGE_LINES      1700    /* 8.5 inches * 200 lines/inch. */
  50: 
  51: #define TOF_TO_BOF      (83-19+2)
  52: #define BAN_TO_BOF      (49-19+2)
  53: 
  54: #define min(a,b)        (a<b ? a : b)
  55: 
  56: char    buffer[VA_BUFFER_SIZE]; /* Big line buffers  */
  57: char    *buf0p = &buffer[0];    /* Zero origin in circular buffer  */
  58: 
  59: char    *calloc();
  60: char    *nalloc();
  61: char    *allpanic();
  62: char    chrtab[][16];
  63: 
  64: struct  header  header;
  65: struct dispatch *dispatch;
  66: 
  67: struct  fontdes {
  68:     int fnum;
  69:     int psize;
  70:     struct  dispatch *disp;
  71:     char    *bits;
  72: } fontdes[NFONTS] = {
  73:     -1,
  74:     -1
  75: };
  76: 
  77: struct point_sizes {
  78:     int stupid_code;
  79:     int real_code;
  80: } point_sizes[] = {
  81:     010, 6,
  82:     0, 7,
  83:     01, 8,
  84:     07, 9,
  85:     02, 10,
  86:     03, 11,
  87:     04, 12,
  88:     05, 14,
  89:     0211, 16,
  90:     06, 18,
  91:     0212, 20,
  92:     0213, 22,
  93:     0214, 24,
  94:     0215, 28,
  95:     0216, 36,
  96:     0, 0
  97: };
  98: 
  99: #define VA_FFLINES  2200
 100: #define VP_FFLINES  650
 101: #define VP_EOTLINES 1400
 102: #define VA_ACCTFILE "/usr/adm/vaacct"
 103: #define VP_ACCTFILE "/usr/adm/vpacct"
 104: 
 105: int lines;
 106: 
 107: int vc;     /* varian/versatec output file descriptor */
 108: int varian;     /* 0 for versatec, 1 for varian. */
 109: int BYTES_PER_LINE; /* VA_BYTES_PER_LINE or VP_BYTES_PER_LINE. */
 110: int BUFFER_SIZE;    /* VA_BUFFER_SIZE or VP_BUFFER_SIZE. */
 111: int cfnum = -1;
 112: int cpsize = 10;
 113: int cfont = 1;
 114: char    *bits;
 115: int nfontnum = -1;
 116: int fontwanted = 1;
 117: int npsize = 10;
 118: int last_ssize = 02;
 119: int xpos, ypos;
 120: int esc, lead, back, verd, mcase, railmag;
 121: double  row, col;
 122: char    *fontname[MAXF];
 123: char    fnbuf[120];
 124: char    *scanline;
 125: int linecount;
 126: 
 127: char    asctab[128] = {
 128:     '\0',   /*blank*/
 129:     'h',    /*h*/
 130:     't',    /*t*/
 131:     'n',    /*n*/
 132:     'm',    /*m*/
 133:     'l',    /*l*/
 134:     'i',    /*i*/
 135:     'z',    /*z*/
 136:     's',    /*s*/
 137:     'd',    /*d*/
 138:     'b',    /*b*/
 139:     'x',    /*x*/
 140:     'f',    /*f*/
 141:     'j',    /*j*/
 142:     'u',    /*u*/
 143:     'k',    /*k*/
 144:     '\0',   /*blank*/
 145:     'p',    /*p*/
 146:     '\06',  /*_ 3/4 em dash*/
 147:     ';',    /*;*/
 148:     '\0',   /*blank*/
 149:     'a',    /*a*/
 150:     '\05',  /*rule*/
 151:     'c',    /*c*/
 152:     '`',    /*` open*/
 153:     'e',    /*e*/
 154:     '\'',   /*' close*/
 155:     'o',    /*o*/
 156:     '\021', /*1/4*/
 157:     'r',    /*r*/
 158:     '\022', /*1/2*/
 159:     'v',    /*v*/
 160:     '-',    /*- hyphen*/
 161:     'w',    /*w*/
 162:     'q',    /*q*/
 163:     '/',    /*/*/
 164:     '.',    /*.*/
 165:     'g',    /*g*/
 166:     '\023', /*3/4*/
 167:     ',',    /*,*/
 168:     '&',    /*&*/
 169:     'y',    /*y*/
 170:     '\0',   /*blank*/
 171:     '%',    /*%*/
 172:     '\0',   /*blank*/
 173:     'Q',    /*Q*/
 174:     'T',    /*T*/
 175:     'O',    /*O*/
 176:     'H',    /*H*/
 177:     'N',    /*N*/
 178:     'M',    /*M*/
 179:     'L',    /*L*/
 180:     'R',    /*R*/
 181:     'G',    /*G*/
 182:     'I',    /*I*/
 183:     'P',    /*P*/
 184:     'C',    /*C*/
 185:     'V',    /*V*/
 186:     'E',    /*E*/
 187:     'Z',    /*Z*/
 188:     'D',    /*D*/
 189:     'B',    /*B*/
 190:     'S',    /*S*/
 191:     'Y',    /*Y*/
 192:     '\0',   /*blank*/
 193:     'F',    /*F*/
 194:     'X',    /*X*/
 195:     'A',    /*A*/
 196:     'W',    /*W*/
 197:     'J',    /*J*/
 198:     'U',    /*U*/
 199:     'K',    /*K*/
 200:     '0',    /*0*/
 201:     '1',    /*1*/
 202:     '2',    /*2*/
 203:     '3',    /*3*/
 204:     '4',    /*4*/
 205:     '5',    /*5*/
 206:     '6',    /*6*/
 207:     '7',    /*7*/
 208:     '8',    /*8*/
 209:     '9',    /*9*/
 210:     '*',    /***/
 211:     '\04',  /*minus*/
 212:     '\01',  /*fi*/
 213:     '\02',  /*fl*/
 214:     '\03',  /*ff*/
 215:     '\020', /* cent sign */
 216:     '\012', /*ffl*/
 217:     '\011', /*ffi*/
 218:     '(',    /*(*/
 219:     ')',    /*)*/
 220:     '[',    /*[*/
 221:     ']',    /*]*/
 222:     '\013', /* degree */
 223:     '\014', /* dagger */
 224:     '=',    /*=*/
 225:     '\017', /* registered */
 226:     ':',    /*:*/
 227:     '+',    /*+*/
 228:     '\0',   /*blank*/
 229:     '!',    /*!*/
 230:     '\07',  /* bullet */
 231:     '?',    /*?*/
 232:     '\015', /*foot mark*/
 233:     '|',    /*|*/
 234:     '\0',   /*blank*/
 235:     '\016', /* copyright */
 236:     '\010', /* square */
 237:     '$',    /*$*/
 238:     '\0',
 239:     '\0',
 240:     '"',    /*"*/
 241:     '#',    /*#*/
 242:     '<',    /*<*/
 243:     '>',    /*>*/
 244:     '@',    /*@*/
 245:     '\\',   /*\\*/
 246:     '^',    /*^*/
 247:     '{',    /*{*/
 248:     '}',    /*}*/
 249:     '~' /*~*/
 250: };
 251: 
 252: char spectab[128] = {
 253:     '\0',   /*blank*/
 254:     'w',    /*psi*/
 255:     'h',    /*theta*/
 256:     'm',    /*nu*/
 257:     'l',    /*mu*/
 258:     'k',    /*lambda*/
 259:     'i',    /*iota*/
 260:     'f',    /*zeta*/
 261:     'r',    /*sigma*/
 262:     'd',    /*delta*/
 263:     'b',    /*beta*/
 264:     'n',    /*xi*/
 265:     'g',    /*eta*/
 266:     'u',    /*phi*/
 267:     't',    /*upsilon*/
 268:     'j',    /*kappa*/
 269:     '\0',   /*blank*/
 270:     'p',    /*pi*/
 271:     '@',    /*at-sign*/
 272:     '7',    /*down arrow*/
 273:     '\0',   /*blank*/
 274:     'a',    /*alpha*/
 275:     '|',    /*or*/
 276:     'v',    /*chi*/
 277:     '"',    /*"*/
 278:     'e',    /*epsilon*/
 279:     '=',    /*=*/
 280:     'o',    /*omicron*/
 281:     '4',    /*left arrow*/
 282:     'q',    /*rho*/
 283:     '6',    /*up arrow*/
 284:     's',    /*tau*/
 285:     '_',    /*underrule*/
 286:     '\\',   /*\*/
 287:     'W',    /*Psi*/
 288:     '\07',  /*bell system sign*/
 289:     '\001', /*infinity*/
 290:     'c',    /*gamma*/
 291:     '\002', /*improper superset*/
 292:     '\003', /*proportional to*/
 293:     '\004', /*right hand*/
 294:     'x',    /*omega*/
 295:     '\0',   /*blank*/
 296:     '(',    /*gradient*/
 297:     '\0',   /*blank*/
 298:     'U',    /*Phi*/
 299:     'H',    /*Theta*/
 300:     'X',    /*Omega*/
 301:     '\005', /*cup (union)*/
 302:     '\006', /*root en*/
 303:     '\014', /*terminal sigma*/
 304:     'K',    /*Lambda*/
 305:     '-',    /*minus*/
 306:     'C',    /*Gamma*/
 307:     '\015', /*integral sign*/
 308:     'P',    /*Pi*/
 309:     '\032', /*subset of*/
 310:     '\033', /*superset of*/
 311:     '2',    /*approximates*/
 312:     'y',    /*partial derivative*/
 313:     'D',    /*Delta*/
 314:     '\013', /*square root*/
 315:     'R',    /*Sigma*/
 316:     '1',    /*approx =*/
 317:     '\0',   /*blank*/
 318:     '>',    /*>*/
 319:     'N',    /*Xi*/
 320:     '<',    /*<*/
 321:     '\016', /*slash (longer)*/
 322:     '\034', /*cap (intersection)*/
 323:     'T',    /*Upsilon*/
 324:     '\035', /*not*/
 325:     '\023', /*right ceiling (rt of ")*/
 326:     '\024', /*left top (of big curly)*/
 327:     '\017', /*bold vertical*/
 328:     '\030', /*left center of big curly bracket*/
 329:     '\025', /*left bottom*/
 330:     '\026', /*right top*/
 331:     '\031', /*right center of big curly bracket*/
 332:     '\027', /*right bot*/
 333:     '\021', /*right floor (rb of ")*/
 334:     '\020', /*left floor (left bot of big sq bract)*/
 335:     '\022', /*left ceiling (lt of ")*/
 336:     '*',    /*multiply*/
 337:     '/',    /*divide*/
 338:     '\010', /*plus-minus*/
 339:     '\011', /*<=*/
 340:     '\012', /*>=*/
 341:     '0',    /*identically equal*/
 342:     '3',    /*not equal*/
 343:     '{',    /*{*/
 344:     '}',    /*}*/
 345:     '\'',   /*' acute accent*/
 346:     '\`',   /*` grave accent*/
 347:     '^',    /*^*/
 348:     '#',    /*sharp*/
 349:     '\036', /*left hand*/
 350:     '\037', /*member of*/
 351:     '~',    /*~*/
 352:     'z',    /*empty set*/
 353:     '\0',   /*blank*/
 354:     'Y',    /*dbl dagger*/
 355:     'Z',    /*box rule*/
 356:     '9',    /*asterisk*/
 357:     '[',    /*improper subset*/
 358:     ']',    /*circle*/
 359:     '\0',   /*blank*/
 360:     '+',    /*eqn plus*/
 361:     '5',    /*right arrow*/
 362:     '8' /*section mark*/
 363: };
 364: 
 365: 
 366: onintr()
 367: {
 368:     signal(SIGINT, SIG_IGN);
 369:     signal(SIGHUP, SIG_IGN);
 370:     signal(SIGTERM, SIG_IGN);
 371:     exit(1);
 372: }
 373: 
 374: main(argc, argv)
 375:     int argc;
 376:     char *argv[];
 377: {
 378:     register int wait = 0;
 379:     char *banarg;
 380: 
 381:     if (geteuid() == 0) {
 382:         nice(-40); nice(20); nice(-4);
 383:         setuid(1);  /* daemon */
 384:     }
 385:     if (signal(SIGINT, SIG_IGN) == SIG_DFL) {
 386:         signal(SIGPIPE, SIG_IGN);
 387:         signal(SIGINT, onintr);
 388:         signal(SIGHUP, onintr);
 389:     } else
 390:         signal(SIGHUP, SIG_IGN);
 391:     if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
 392:         signal(SIGTERM, onintr);
 393:     argc--, argv++;
 394: 
 395:     varian = 1;     /* Assume varian unless -W. */
 396:     banarg = NULL;
 397:     BYTES_PER_LINE = VA_BYTES_PER_LINE;
 398:     BUFFER_SIZE = VA_BUFFER_SIZE;
 399: 
 400:     while (argc > 0 && argv[0][0] == '-') {
 401:         switch (argv[0][1]) {
 402: 
 403:         case 'W':       /* Wide: the versatec. */
 404: /*
 405: 			varian = 0;
 406: 			BYTES_PER_LINE = VP_BYTES_PER_LINE;
 407: 			BUFFER_SIZE = VP_BUFFER_SIZE;
 408: */
 409:             fprintf(stderr, "rvcat: -W not implemented\n");
 410:             break;
 411: 
 412:         case 't':
 413:             vc = 1;
 414:             break;
 415: 
 416:         case 'w':
 417:             wait = 1;
 418:             break;
 419: 
 420:         case '3':
 421:             vc = 3;     /* from vpd */
 422:             break;
 423: 
 424:         case 'b':
 425:             if (argc != 1) {
 426:                 banarg = argv[1];
 427:                 argc--, argv++;
 428:             }
 429:             break;
 430: 
 431:         default:
 432:             fprintf(stderr, "usage: rvcat [ -t ] [ -w ] [ -b banner ] [ file... ]\n");
 433:             exit(1);
 434:         }
 435:         argc--, argv++;
 436:     }
 437:     if (vc == 0) {
 438:         /* directly to plotter */
 439:         for (;;) {
 440:             extern int errno;
 441: 
 442:             if ((vc = open((varian ? "/dev/va0" : "/dev/vp0"), 1)) >= 0)
 443:                 break;
 444:             if (!wait)
 445:                 break;
 446:             if (errno != EIO && errno != ENXIO)
 447:                 break;
 448:             sleep(10);
 449:         }
 450:     }
 451:     ioctl(vc, VSETSTATE, prtmode);
 452:     banner(banarg);
 453:     ioctl(vc, VSETSTATE, pltmode);
 454:     readrm();
 455:     for (;;) {
 456:         if (argc > 0) {
 457:             if (freopen(argv[0], "r", stdin) == NULL) {
 458:                 perror(argv[0]);
 459:                 argc--, argv++;
 460:                 continue;
 461:             }
 462:             argc--, argv++;
 463:         }
 464:         ofile();
 465:         if (argc <= 0)
 466:             break;
 467:         ioctl(vc, VSETSTATE, prtmode);
 468:         if (varian) {
 469:             write(vc, "\014\0", 2);
 470:         } else
 471:             write (vc, "\n\n\n\n\n", 5);
 472:         ioctl(vc, VSETSTATE, pltmode);
 473:     }
 474:     ioctl(vc, VSETSTATE, prtmode);
 475:     account(banarg);
 476:     exit(0);
 477: }
 478: 
 479: readrm()
 480: {
 481:     register int i;
 482:     register char *cp;
 483:     register int rmfd;
 484:     char c;
 485: 
 486:     if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
 487:         if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
 488:             fprintf(stderr, "No railmag file\n");
 489:             exit(1);
 490:         }
 491:     cp = fnbuf;
 492:     for (i = 0; i < 4; i++) {
 493:         fontname[i] = cp;
 494:         while (read(rmfd, &c, 1) == 1 && c != '\n')
 495:             *cp++ = c;
 496:         *cp++ = '\0';
 497:     }
 498:     close(rmfd);
 499: }
 500: 
 501: ofile()
 502: {
 503:     register int c;
 504:     register int i;
 505:     double scol;
 506:     static int initialized;
 507: 
 508:     lines = 0;
 509:     while ((c = getchar()) != EOF) {
 510:         if (!c)
 511:             continue;
 512:         if (c & 0200) {
 513:             esc += (~c) & 0177;
 514:             continue;
 515:         }
 516:         if (esc) {
 517:             if (back)
 518:                 esc = -esc;
 519:             col += esc;
 520:             esc = 0;
 521:             i = CONVERT(col);
 522:             while (i >= NLINES) {
 523:                 slop_lines(15);
 524:                 i = CONVERT(col);
 525:             }
 526:             ypos = i;
 527:         }
 528:         if ((c & 0377) < 0100)  /*  Purely for efficiency  */
 529:             goto normal_char;
 530:         switch (c) {
 531: 
 532:         case 0100:
 533:             esc = 0;
 534:             lead = 0;
 535:             linecount = 0;
 536:             verd = 0;
 537:             back = 0;
 538:             mcase = 0;
 539:             railmag = 0;
 540:             if (loadfont(railmag, cpsize) < 0)
 541:                 fprintf(stderr, "Can't load initial font\n");
 542:             if (initialized)
 543:                 goto reset;
 544:             initialized = 1;
 545:             row = 0;
 546:             xpos = CONVERT(row);
 547:             for (c = 0; c < BUFFER_SIZE; c++)
 548:                 buffer[c] = 0;
 549:             col = 0;
 550:             ypos = 0;
 551:             break;
 552: 
 553:         case 0101:  /* lower rail */
 554:             crail(railmag &= ~01);
 555:             break;
 556: 
 557:         case 0102:  /* upper rail */
 558:             crail(railmag |= 01);
 559:             break;
 560: 
 561:         case 0103:  /* upper mag */
 562:             crail(railmag |= 02);
 563:             break;
 564: 
 565:         case 0104:  /* lower mag */
 566:             crail(railmag &= ~02);
 567:             break;
 568: 
 569:         case 0105:  /* lower case */
 570:             mcase = 0;
 571:             break;
 572: 
 573:         case 0106:  /* upper case */
 574:             mcase = 0100;
 575:             break;
 576: 
 577:         case 0107:  /* escape forward */
 578:             back = 0;
 579:             break;
 580: 
 581:         case 0110:  /* escape backwards */
 582:             back = 1;
 583:             break;
 584: 
 585:         case 0111:  /* stop */
 586:             break;
 587: 
 588:         case 0112:  /* lead forward */
 589:             verd = 0;
 590:             break;
 591: 
 592:         case 0113:  /* undefined */
 593:             break;
 594: 
 595:         case 0114:  /* lead backward */
 596:             verd = 1;
 597:             break;
 598: 
 599:         case 0115:  /* undefined */
 600: reset:
 601:             c = lines % PAGE_LINES;
 602:             while (c < FF_LINES) {
 603:                 slop_lines(min(FF_LINES - c, NLINES));
 604:                 c = lines % PAGE_LINES;
 605:             }
 606:             new_page(PAGE_LINES - c);
 607:             break;
 608: 
 609:         case 0116:
 610:             lead = (getchar() & 0377) * 64;
 611:             goto leadin;
 612: 
 613:         case 0117:
 614:             break;
 615: 
 616:         default:
 617:             if ((c & 0340) == 0140) /* leading */ {
 618:                 lead = (~c) & 037;
 619: leadin:
 620:                 if (verd)
 621:                     lead = -lead;
 622:                 row += lead*3;  /*  Lead is 3 units  */
 623:                 xpos = CONVERT(row);
 624:                 continue;
 625:             }
 626:             if ((c & 0360) == 0120) /* size change */ {
 627:                 loadfont(railmag, findsize(c & 017));
 628:                 continue;
 629:             }
 630:             if (c & 0300)
 631:                 continue;
 632: 
 633: normal_char:
 634:             if (row < 0 || CONVERT(row) >= VA_RASTER_LENGTH)
 635:                 continue;
 636:             c = (c & 077) | mcase;
 637:             outc(c);
 638:         }
 639:     }
 640: out:
 641:     slop_lines(NLINES);
 642: }
 643: 
 644: findsize(code)
 645:     register int code;
 646: {
 647:     register struct point_sizes *psp;
 648: 
 649:     psp = point_sizes;
 650:     while (psp->real_code != 0) {
 651:         if ((psp->stupid_code & 017) == code)
 652:             break;
 653:         psp++;
 654:     }
 655:     code = 0;
 656:     if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
 657:         code = -55;
 658:     else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
 659:         code = 55;
 660:     if (back)
 661:         code = -code;
 662:     esc += code;
 663:     last_ssize = psp->stupid_code;
 664:     return (psp->real_code);
 665: }
 666: 
 667: account(who)
 668: char *who;
 669: {
 670:     register FILE *a;
 671: 
 672:     if (who == NULL)
 673:         return;
 674:     a = fopen(varian ? VA_ACCTFILE : VP_ACCTFILE, "a");
 675:     if (a == NULL)
 676:         return;
 677:     /*
 678: 	 * Varian accounting is done by 8.5 inch pages;
 679: 	 * Versatec accounting is by the (12 inch) foot.
 680: 	 */
 681:     fprintf(a, "t%6.2f\t%s\n",
 682:            (lines / 200.0) / (varian ? 8.5 : 12.0), who);
 683:     fclose(a);
 684: }
 685: 
 686: crail(nrail)
 687:     register int nrail;
 688: {
 689:     register int psize;
 690: 
 691:     psize = cpsize;
 692:     if (fontwanted && psize != npsize)
 693:         psize = npsize;
 694:     loadfont(nrail, psize);
 695: }
 696: 
 697: 
 698: loadfont(fnum, size)
 699:     register int fnum;
 700:     register int size;
 701:     {
 702:     register int i;
 703:     char cbuf[80];
 704: 
 705:     fontwanted = 0;
 706:     if (fnum == cfnum && size == cpsize)
 707:         return(0);
 708:     for (i = 0; i < NFONTS; i++)
 709:         if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
 710:             cfnum = fontdes[i].fnum;
 711:             cpsize = fontdes[i].psize;
 712:             dispatch = &fontdes[i].disp[0];
 713:             bits = fontdes[i].bits;
 714:             cfont = i;
 715:             return (0);
 716:         }
 717:     if (fnum < 0 || fnum >= MAXF) {
 718:         fprintf(stderr, "Internal error: illegal font\n");
 719:         return(-1);
 720:     }
 721:     nfontnum = fnum;
 722:     npsize = size;
 723:     fontwanted++;
 724:     return (0);
 725: }
 726: 
 727: 
 728: getfont()
 729: {
 730:     register int fnum, size, font;
 731:     int d;
 732:     char cbuf[BUFSIZ];
 733:     char *cp = cbuf;
 734:     char *dp;
 735: 
 736:     if (!fontwanted)
 737:         return(0);
 738:     fnum = nfontnum;
 739:     size = npsize;
 740:     sprintf(cbuf, "%s.%dr", fontname[fnum], size);
 741:     font = open(cbuf, 0);
 742:     if (font == -1) {
 743:         perror(cbuf);
 744:         fontwanted = 0;
 745:         return (-1);
 746:     }
 747:     if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
 748:         fprintf(stderr, "%s: Bad font file", cbuf);
 749:     else {
 750:         cfont = relfont();
 751:         if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
 752:             && ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
 753:                 fprintf(stderr, "%s: ran out of memory\n", cbuf);
 754:                 exit(1);
 755:         } else {
 756:             /*
 757: 			 * have allocated one chunk of mem for font, dispatch.
 758: 			 * get the dispatch addr, align to word boundary.
 759: 			 */
 760:             d = (int) bits+header.size;
 761:             d += 1;
 762:             d &= ~1;
 763:             if (read(font, d, DSIZ)!=DSIZ
 764:               || read(font, bits, header.size)!=header.size)
 765:                 fprintf(stderr, "bad font header");
 766:             else {
 767:                 close(font);
 768:                 cfnum = fontdes[cfont].fnum = fnum;
 769:                 cpsize = fontdes[cfont].psize = size;
 770:                 fontdes[cfont].bits = bits;
 771:                 fontdes[cfont].disp = (struct dispatch *) d;
 772:                 dispatch = &fontdes[cfont].disp[0];
 773:                 fontwanted = 0;
 774:                 return (0);
 775:             }
 776:         }
 777:     }
 778:     close(font);
 779:     fontwanted = 0;
 780:     return(-1);
 781: }
 782: 
 783: int lastloaded  = -1;
 784: 
 785: relfont()
 786: {
 787:     register int newfont;
 788: 
 789:     newfont = lastloaded;
 790:     /*
 791: 	 * optimization for special font.  since we think that usually
 792: 	 * there is only one character at a time from any special math
 793: 	 * font, make it the candidate for removal.
 794: 	 */
 795:     if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
 796:         if (++newfont>=NFONTS)
 797:             newfont = 0;
 798:     lastloaded = newfont;
 799:     if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0) {
 800:         /* fprintf(stderr, "freeing position %d\n", newfont); */
 801:         nfree(fontdes[newfont].bits);
 802:     } else
 803:         /* fprintf(stderr, "taking without freeing position %d\n", newfont); */
 804:         ;
 805:     fontdes[newfont].bits = 0;
 806:     return (newfont);
 807: }
 808: 
 809: char *
 810: allpanic(nbytes)
 811:     int nbytes;
 812: {
 813:     register int i;
 814: 
 815:     for (i = 0; i <= NFONTS; i++)
 816:         if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
 817:             nfree(fontdes[i].bits);
 818:     lastloaded = cfont;
 819:     for (i = 0; i <= NFONTS; i++) {
 820:         fontdes[i].fnum = fontdes[i].psize = -1;
 821:         fontdes[i].bits = 0;
 822:         cfnum = cpsize = -1;
 823:     }
 824:     return(nalloc(nbytes,1));
 825: }
 826: 
 827: int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
 828:         0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
 829: int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
 830:         0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
 831: int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
 832: 
 833: outc(code)
 834:     int code;
 835: {
 836:     char c;             /* character to print */
 837:     register struct dispatch *d;    /* ptr to character font record */
 838:     register char *addr;        /* addr of font data */
 839:     int llen;           /* length of each font line */
 840:     int nlines;         /* number of font lines */
 841:     register char *scanp;       /* ptr to output buffer */
 842:     int scanp_inc;          /* increment to start of next buffer */
 843:     int offset;         /* bit offset to start of font data */
 844:     int i;              /* loop counter */
 845:     register int count;     /* font data ptr */
 846:     register unsigned fontdata; /* font data temporary */
 847:     register int off8;      /* offset + 8 */
 848:     int b0poff;         /* bit offset back towards buf0p */
 849: 
 850:     if (fontwanted)
 851:         getfont();
 852:     if (railmag == SPECIALFONT) {
 853:         if ((c = spectab[code]) < 0)
 854:             return(0);
 855:     } else if ((c = asctab[code]) < 0)
 856:         return(0);
 857:     d = dispatch+c;
 858:     if (d->nbytes) {
 859:         addr = bits+d->addr;
 860:         llen = (d->down+d->up+7)/8;
 861:         nlines = d->left+d->right;
 862:         if (ypos+d->right >= NLINES)
 863:             slop_lines(ypos+d->right-NLINES+6);
 864:         b0poff = BYTES_PER_LINE*8 - 1 - (xpos+d->down);
 865:         scanp = ((ypos-d->left-1)*BYTES_PER_LINE+b0poff/8)+buf0p;
 866:         if (scanp < &buffer[0])
 867:             scanp += BUFFER_SIZE;
 868:         scanp_inc = BYTES_PER_LINE-llen;
 869:         offset = -(b0poff&07);
 870:         off8 = offset+8;
 871:         for (i = 0; i < nlines; i++) {
 872:             if (scanp >= &buffer[BUFFER_SIZE])
 873:                 scanp -= BUFFER_SIZE;
 874:             count = llen;
 875:             if (scanp + count <= &buffer[BUFFER_SIZE])
 876:                 do {
 877:                     fontdata = *(unsigned *)addr;
 878:                     addr += 4;
 879:                     if (count < 4)
 880:                         fontdata &= ~strim[count];
 881:                     *(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
 882:                     scanp++;
 883:                     *(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
 884:                     scanp += 3;
 885:                     count -= 4;
 886:                 } while (count > 0);
 887:             scanp += scanp_inc+count;
 888:             addr += count;
 889:         }
 890:         return (1);
 891:     }
 892:     return (0);
 893: }
 894: 
 895: slop_lines(ncols)
 896:     int ncols;
 897: {
 898:     register int i, rcols;
 899: 
 900:     lines += ncols;
 901:     rcols = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
 902:     if (rcols < ncols) {
 903:         if (write(vc, buf0p, BYTES_PER_LINE * rcols) < 0)
 904:             exit(1);
 905:         clear(buf0p, rcols * BYTES_PER_LINE);
 906:         buf0p = buffer;
 907:         ncols -= rcols;
 908:         ypos -= rcols;
 909:         col -= RECONVERT(rcols);
 910:     }
 911:     if (write(vc, buf0p, BYTES_PER_LINE * ncols) < 0)
 912:         exit(1);
 913:     clear(buf0p, BYTES_PER_LINE * ncols);
 914:     buf0p += BYTES_PER_LINE * ncols;
 915:     if (buf0p >= &buffer[BUFFER_SIZE])
 916:         buf0p -= BUFFER_SIZE;
 917:     ypos -= ncols;
 918:     col -= RECONVERT(ncols);
 919: }
 920: 
 921: /*ARGSUSED*/
 922: clear(lp, nbytes)
 923:     int *lp;
 924:     int nbytes;
 925: {
 926: 
 927:     asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
 928: 
 929: }
 930: 
 931: /* Start a new page by formfeeding, resetting buffer and column counters. */
 932: new_page(lines_left)
 933:     int lines_left;     /* ... on page. */
 934: {
 935:     lines += lines_left;
 936:     buf0p = buffer;     /* Clear out buffer and reset pointers. */
 937:     clear(buf0p, BYTES_PER_LINE * NLINES);
 938:     row = 0;
 939:     col = 0;
 940:     xpos = CONVERT(row);
 941:     ypos = 0;
 942:     ioctl(vc, VSETSTATE, prtmode);
 943:     write (vc, "\014\0", 2);
 944:     ioctl(vc, VSETSTATE, pltmode);
 945: }
 946: 
 947: 
 948: char *
 949: nalloc(i, j)
 950:     int i, j;
 951: {
 952:     register char *cp;
 953: 
 954:     cp = calloc(i, j);
 955:     /* fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); */
 956:     return(cp);
 957: }
 958: 
 959: nfree(cp)
 960:     char *cp;
 961: {
 962: 
 963:     /* fprintf(stderr, "freeing at %x\n", cp); */
 964:     free(cp);
 965: }
 966: 
 967: banner(s)
 968: char *s;
 969: {
 970:     long timeb;
 971:     register char *sp;
 972:     int i, j, t;
 973: 
 974:     if (!varian) {      /* Versatec uses just a small banner. */
 975:         if (s == NULL)  /* No banner, just return. */
 976:             return;
 977:         write(vc, s, strlen(s));
 978:         write(vc, " ", 1);
 979:         time(&timeb);
 980:         write(vc, ctime(&timeb), 26);
 981:         return;
 982:     }
 983: 
 984:     if (s == NULL) {
 985:         write(vc, "\014\0", 2);
 986:         return;
 987:     }
 988:     newlines(8);
 989:     for (i=0; i<16; i++)
 990:     {
 991:         write(vc, "               ", 16);
 992:         for (sp=s; *sp; sp++)
 993:         {
 994:             char obuf[10];
 995:             char *cp = obuf;
 996: 
 997:             if (*sp<=' '|| *sp >'}')
 998:                 continue;
 999:             *cp++ = ' ', *cp++ = ' ';
1000:             t = chrtab[*sp - ' '][i];
1001:             for (j=7; j>=0; j--)
1002:                 if ((t>>j) & 01)
1003:                     *cp++ = 'X';
1004:                 else
1005:                     *cp++ = ' ';
1006:             write(vc, obuf, 10);
1007:         }
1008:         write (vc, " \n", 2);
1009:     }
1010:     newlines(8);
1011:     write(vc, "                ", 16);
1012:     time(&timeb);
1013:     write(vc, ctime(&timeb), 26);
1014:     write(vc, "\014\0", 2);
1015: }
1016: 
1017: newlines(count)
1018: int count;
1019: {
1020:     char buf[100];
1021:     register int i;
1022: 
1023:     for (i = 0; i < count; i++)
1024:         buf[i] = '\n';
1025:     buf[i] = '\0';
1026:     write(vc, buf, i+1);
1027: }

Defined functions

account defined in line 667; used 1 times
allpanic defined in line 809; used 2 times
banner defined in line 967; used 1 times
clear defined in line 922; used 3 times
crail defined in line 686; used 4 times
findsize defined in line 644; used 1 times
getfont defined in line 728; used 1 times
loadfont defined in line 698; used 3 times
main defined in line 374; never used
nalloc defined in line 948; used 3 times
new_page defined in line 932; used 1 times
newlines defined in line 1017; used 2 times
nfree defined in line 959; used 2 times
ofile defined in line 501; used 1 times
onintr defined in line 366; used 4 times
outc defined in line 833; used 1 times
readrm defined in line 479; used 1 times
relfont defined in line 785; used 1 times
slop_lines defined in line 895; used 4 times

Defined variables

BUFFER_SIZE defined in line 110; used 9 times
BYTES_PER_LINE defined in line 109; used 11 times
M defined in line 827; used 1 times
N defined in line 829; used 1 times
asctab defined in line 127; used 1 times
back defined in line 120; used 5 times
bits defined in line 114; used 19 times
buf0p defined in line 57; used 12 times
buffer defined in line 56; used 9 times
cfnum defined in line 111; used 4 times
cfont defined in line 113; used 10 times
chrtab defined in line 62; used 1 times
col defined in line 121; used 7 times
cpsize defined in line 112; used 6 times
dispatch defined in line 65; used 4 times
esc defined in line 120; used 8 times
fnbuf defined in line 123; used 1 times
fontdes defined in line 72; used 23 times
fontname defined in line 122; used 2 times
fontwanted defined in line 116; used 8 times
header defined in line 64; used 9 times
last_ssize defined in line 118; used 3 times
lastloaded defined in line 783; used 3 times
lead defined in line 120; used 6 times
linecount defined in line 125; used 1 times
lines defined in line 105; used 6 times
mcase defined in line 120; used 4 times
nfontnum defined in line 115; used 2 times
npsize defined in line 117; used 4 times
pltmode defined in line 21; used 3 times
point_sizes defined in line 80; used 1 times
prtmode defined in line 20; used 4 times
railmag defined in line 120; used 8 times
row defined in line 121; used 8 times
scanline defined in line 124; never used
sccsid defined in line 18; never used
spectab defined in line 252; used 1 times
strim defined in line 831; used 1 times
varian defined in line 108; used 6 times
vc defined in line 107; used 27 times
verd defined in line 120; used 4 times
xpos defined in line 119; used 4 times
ypos defined in line 119; used 8 times

Defined struct's

fontdes defined in line 67; never used
point_sizes defined in line 77; used 2 times
  • in line 647(2)

Defined macros

BAN_TO_BOF defined in line 52; never used
CHARMASK defined in line 24; never used
CONVERT defined in line 38; used 6 times
DISPATCHSIZE defined in line 23; used 2 times
DSIZ defined in line 27; used 4 times
FF_LINES defined in line 48; used 2 times
GLOBAL_RAILMAG defined in line 31; used 1 times
LOCAL_RAILMAG defined in line 30; used 1 times
MAXF defined in line 28; used 2 times
NFONTS defined in line 25; used 5 times
NLINES defined in line 45; used 7 times
PAGE_LINES defined in line 49; used 3 times
RECONVERT defined in line 39; used 2 times
SPECIALFONT defined in line 26; used 2 times
TOF_TO_BOF defined in line 51; never used
VA_ACCTFILE defined in line 102; used 1 times
VA_BUFFER_SIZE defined in line 46; used 2 times
VA_BYTES_PER_LINE defined in line 43; used 2 times
VA_FFLINES defined in line 99; never used
VA_RASTER_LENGTH defined in line 41; used 2 times
VP_ACCTFILE defined in line 103; used 1 times
VP_EOTLINES defined in line 101; never used
VP_FFLINES defined in line 100; never used
min defined in line 54; used 1 times
Last modified: 1982-08-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2802
Valid CSS Valid XHTML 1.0 Strict