|
|
1.1 ! root 1: THIS VERSION IS NOT UP TO DATE; ! 2: INCLUDED FOR HISTORICAL REASONS. ! 3: /* ! 4: * drive C/A/T typesetter ! 5: * currently stdout only ! 6: */ ! 7: ! 8: /* ! 9: output language from troff: ! 10: all numbers are character strings ! 11: ! 12: sn size in points ! 13: fn font as number from 1-n ! 14: cx ascii character x ! 15: Cxyz funny char xyz. terminated by white space ! 16: Hn go to absolute horizontal position n ! 17: Vn go to absolute vertical position n (down is positive) ! 18: hn go n units horizontally (relative) ! 19: vn ditto vertically ! 20: nnc move right nn, then print c (exactly 2 digits!) ! 21: (this wart is an optimization that shrinks output file size ! 22: about 35% and run-time about 15% while preserving ascii-ness) ! 23: Dt ...\n draw operation 't': ! 24: Dl x y line from here by x,y ! 25: Dc d circle of diameter d with left side here ! 26: De x y ellipse of axes x,y with left side here ! 27: Da x y r arc counter-clockwise by x,y of radius r ! 28: D~ x y x y ... wiggly line by x,y then x,y ... ! 29: nb a end of line (information only -- no action needed) ! 30: b = space before line, a = after ! 31: p new page begins -- set v to 0 ! 32: #...\n comment ! 33: x ...\n device control functions: ! 34: x i init ! 35: x T s name of device is s ! 36: x r n h v resolution is n/inch ! 37: h = min horizontal motion, v = min vert ! 38: x p pause (can restart) ! 39: x s stop -- done for ever ! 40: x t generate trailer ! 41: x f n s font position n contains font s ! 42: x H n set character height to n ! 43: x S n set slant to N ! 44: ! 45: Subcommands like "i" are often spelled out like "init". ! 46: */ ! 47: ! 48: #include <stdio.h> ! 49: #include <ctype.h> ! 50: #include <signal.h> ! 51: ! 52: #include "dev.h" ! 53: #define NFONT 8 ! 54: ! 55: int output = 0; /* do we do output at all? */ ! 56: int nolist = 0; /* output page list if > 0 */ ! 57: int olist[20]; /* pairs of page numbers */ ! 58: int spage = 9999; /* stop every spage pages */ ! 59: int scount = 0; ! 60: ! 61: struct dev dev; ! 62: struct font *fontbase[NFONT+1]; ! 63: int *pstab; ! 64: int nsizes; ! 65: int nfonts; ! 66: int smnt; /* index of first special font */ ! 67: int nchtab; ! 68: char *chname; ! 69: int *chtab; ! 70: char *fitab[NFONT+1]; ! 71: char *widthtab[NFONT+1]; /* widtab would be a better name */ ! 72: char *codetab[NFONT+1]; /* device codes */ ! 73: ! 74: #define FATAL 1 ! 75: #define BMASK 0377 ! 76: int dbg = 0; ! 77: int res; /* input assumed computed according to this resolution */ ! 78: ! 79: #define HERE 0 ! 80: #define THERE 1 ! 81: #define HOST "r70\n" ! 82: char *typesetter[] = { ! 83: "/dev/cat", /* typesetter device */ ! 84: "r70!/dev/202" ! 85: }; ! 86: FILE *tf = NULL; /* output file */ ! 87: char *fontdir = "/usr/bwk/troff/devcat"; ! 88: extern char devname[]; ! 89: ! 90: #define hmot(n) hpos += n ! 91: #define hgoto(n) hpos = n ! 92: ! 93: int size = -1; /* this is invalid */ ! 94: int font = -1; /* current font */ ! 95: int hpos; /* horizontal position where we are supposed to be next (left = 0) */ ! 96: int oldh; /* previous H position */ ! 97: int vpos; /* current vertical position (down positive) */ ! 98: int oldv; /* current pos in 1/4 point units */ ! 99: int horig; /* h origin of current block; hpos rel to this */ ! 100: int vorig; ! 101: int DX = 1; /* step size in x for drawing */ ! 102: int DY = 3; /* step size in y for drawing */ ! 103: int drawdot = '.'; /* draw with this character */ ! 104: int drawsize = 1; /* shrink by this factor when drawing */ ! 105: ! 106: main(argc, argv) ! 107: char *argv[]; ! 108: { ! 109: FILE *fp; ! 110: int i; ! 111: int busyflag = 0; ! 112: int waitflag = 0; ! 113: int where = HERE; ! 114: char wherebuf[100]; ! 115: int done(); ! 116: ! 117: while (argc > 1 && argv[1][0] == '-') { ! 118: switch (argv[1][1]) { ! 119: case 't': ! 120: tf = stdout; ! 121: break; ! 122: case 'o': ! 123: outlist(&argv[1][2]); ! 124: break; ! 125: case 'd': ! 126: dbg = atoi(&argv[1][2]); ! 127: if (dbg == 0) dbg = 1; ! 128: break; ! 129: case 'b': ! 130: busyflag = 1; ! 131: break; ! 132: case 'w': ! 133: waitflag = 1; ! 134: break; ! 135: case 's': ! 136: spage = atoi(&argv[1][2]); ! 137: if (spage <= 0) ! 138: spage = 9999; ! 139: break; ! 140: } ! 141: argc--; ! 142: argv++; ! 143: } ! 144: tryagain: ! 145: if ((fp = fopen("/etc/where", "r")) != NULL) ! 146: if(fgets(wherebuf, sizeof(wherebuf), fp) != NULL) ! 147: if(strcmp(wherebuf, HOST) != 0) ! 148: where = THERE; ! 149: fclose(fp); ! 150: if (tf != stdout) ! 151: tf = fopen(typesetter[where], "w"); ! 152: if (busyflag) { ! 153: printf(tf==NULL? "Busy.\n": "Available.\n"); ! 154: exit(0); ! 155: } ! 156: if (tf == NULL) { ! 157: if (waitflag == 0) { ! 158: error(!FATAL, "can't open typesetter\n"); ! 159: exit(1); ! 160: } else { ! 161: sleep(60); ! 162: goto tryagain; ! 163: } ! 164: } ! 165: ! 166: if (signal(SIGINT, done) == SIG_IGN) { ! 167: signal(SIGINT, SIG_IGN); ! 168: signal(SIGQUIT, SIG_IGN); ! 169: signal(SIGHUP, SIG_IGN); ! 170: } else { ! 171: signal(SIGQUIT, done); ! 172: signal(SIGHUP, done); ! 173: } ! 174: signal(SIGTERM, done); ! 175: ! 176: if (argc <= 1) ! 177: conv(stdin); ! 178: else ! 179: while (--argc > 0) { ! 180: if (strcmp(*++argv, "-") == 0) ! 181: fp = stdin; ! 182: else if ((fp = fopen(*argv, "r")) == NULL) ! 183: error(FATAL, "can't open %s", *argv); ! 184: conv(fp); ! 185: fclose(fp); ! 186: } ! 187: account(); ! 188: done(); ! 189: } ! 190: ! 191: outlist(s) /* process list of page numbers to be printed */ ! 192: char *s; ! 193: { ! 194: int n1, n2, i; ! 195: ! 196: nolist = 0; ! 197: while (*s) { ! 198: n1 = 0; ! 199: if (isdigit(*s)) ! 200: do ! 201: n1 = 10 * n1 + *s++ - '0'; ! 202: while (isdigit(*s)); ! 203: else ! 204: n1 = -9999; ! 205: n2 = n1; ! 206: if (*s == '-') { ! 207: s++; ! 208: n2 = 0; ! 209: if (isdigit(*s)) ! 210: do ! 211: n2 = 10 * n2 + *s++ - '0'; ! 212: while (isdigit(*s)); ! 213: else ! 214: n2 = 9999; ! 215: } ! 216: olist[nolist++] = n1; ! 217: olist[nolist++] = n2; ! 218: if (*s != '\0') ! 219: s++; ! 220: } ! 221: olist[nolist] = 0; ! 222: if (dbg) ! 223: for (i=0; i<nolist; i += 2) ! 224: printf("%3d %3d\n", olist[i], olist[i+1]); ! 225: } ! 226: ! 227: conv(fp) ! 228: register FILE *fp; ! 229: { ! 230: register int c, k; ! 231: int m, n, i, n1, m1; ! 232: char str[100], buf[300]; ! 233: ! 234: while ((c = getc(fp)) != EOF) { ! 235: switch (c) { ! 236: case '\n': /* when input is text */ ! 237: case ' ': ! 238: case 0: /* occasional noise creeps in */ ! 239: break; ! 240: case '{': /* push down current environment */ ! 241: t_push(); ! 242: break; ! 243: case '}': ! 244: t_pop(); ! 245: break; ! 246: case '0': case '1': case '2': case '3': case '4': ! 247: case '5': case '6': case '7': case '8': case '9': ! 248: /* two motion digits plus a character */ ! 249: hmot((c-'0')*10 + getc(fp)-'0'); ! 250: put1(getc(fp)); ! 251: break; ! 252: case 'c': /* single ascii character */ ! 253: put1(getc(fp)); ! 254: break; ! 255: case 'C': ! 256: fscanf(fp, "%s", str); ! 257: put1s(str); ! 258: break; ! 259: case 't': /* straight text */ ! 260: fgets(buf, sizeof(buf), fp); ! 261: t_text(buf); ! 262: break; ! 263: case 'D': /* draw function */ ! 264: fgets(buf, sizeof(buf), fp); ! 265: switch (buf[0]) { ! 266: case 'l': /* draw a line */ ! 267: sscanf(buf+1, "%d %d", &n, &m); ! 268: drawline(n, m, "."); ! 269: break; ! 270: case 'c': /* circle */ ! 271: sscanf(buf+1, "%d", &n); ! 272: drawcirc(n); ! 273: break; ! 274: case 'e': /* ellipse */ ! 275: sscanf(buf+1, "%d %d", &m, &n); ! 276: drawellip(m, n); ! 277: break; ! 278: case 'a': /* arc */ ! 279: sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); ! 280: drawarc(n, m, n1, m1); ! 281: break; ! 282: case '~': /* wiggly line */ ! 283: drawwig(buf+1); ! 284: break; ! 285: default: ! 286: error(FATAL, "unknown drawing function %s\n", buf); ! 287: break; ! 288: } ! 289: break; ! 290: case 's': ! 291: fscanf(fp, "%d", &n); /* ignore fractional sizes */ ! 292: setsize(t_size(n)); ! 293: break; ! 294: case 'f': ! 295: fscanf(fp, "%s", str); ! 296: setfont(t_font(str)); ! 297: break; ! 298: case 'H': /* absolute horizontal motion */ ! 299: /* fscanf(fp, "%d", &n); */ ! 300: while ((c = getc(fp)) == ' ') ! 301: ; ! 302: k = 0; ! 303: do { ! 304: k = 10 * k + c - '0'; ! 305: } while (isdigit(c = getc(fp))); ! 306: ungetc(c, fp); ! 307: hgoto(k); ! 308: break; ! 309: case 'h': /* relative horizontal motion */ ! 310: /* fscanf(fp, "%d", &n); */ ! 311: while ((c = getc(fp)) == ' ') ! 312: ; ! 313: k = 0; ! 314: do { ! 315: k = 10 * k + c - '0'; ! 316: } while (isdigit(c = getc(fp))); ! 317: ungetc(c, fp); ! 318: hmot(k); ! 319: break; ! 320: case 'w': /* word space */ ! 321: break; ! 322: case 'V': ! 323: fscanf(fp, "%d", &n); ! 324: vgoto(n); ! 325: break; ! 326: case 'v': ! 327: fscanf(fp, "%d", &n); ! 328: vmot(n); ! 329: break; ! 330: case 'p': /* new page */ ! 331: fscanf(fp, "%d", &n); ! 332: t_page(n); ! 333: break; ! 334: case 'n': /* end of line */ ! 335: while (getc(fp) != '\n') ! 336: ; ! 337: t_newline(); ! 338: break; ! 339: case '#': /* comment */ ! 340: while (getc(fp) != '\n') ! 341: ; ! 342: break; ! 343: case 'x': /* device control */ ! 344: devcntrl(fp); ! 345: break; ! 346: default: ! 347: error(!FATAL, "unknown input character %o %c\n", c, c); ! 348: done(); ! 349: } ! 350: } ! 351: } ! 352: ! 353: devcntrl(fp) /* interpret device control functions */ ! 354: FILE *fp; ! 355: { ! 356: char str[20], str1[50], buf[50]; ! 357: int c, n; ! 358: ! 359: fscanf(fp, "%s", str); ! 360: switch (str[0]) { /* crude for now */ ! 361: case 'i': /* initialize */ ! 362: fileinit(); ! 363: t_init(0); ! 364: break; ! 365: case 'T': /* device name */ ! 366: fscanf(fp, "%s", devname); ! 367: break; ! 368: case 't': /* trailer */ ! 369: t_trailer(); ! 370: break; ! 371: case 'p': /* pause -- can restart */ ! 372: t_reset('p'); ! 373: break; ! 374: case 's': /* stop */ ! 375: t_reset('s'); ! 376: break; ! 377: case 'r': /* resolution assumed when prepared */ ! 378: fscanf(fp, "%d", &res); ! 379: break; ! 380: case 'f': /* font used */ ! 381: fscanf(fp, "%d %s", &n, str); ! 382: fgets(buf, sizeof buf, fp); /* in case there's a filename */ ! 383: ungetc('\n', fp); /* fgets goes too far */ ! 384: str1[0] = 0; /* in case there's nothing to come in */ ! 385: sscanf(buf, "%s", str1); ! 386: loadfont(n, str, str1); ! 387: break; ! 388: /* these don't belong here... */ ! 389: case 'H': /* char height */ ! 390: fscanf(fp, "%d", &n); ! 391: t_charht(n); ! 392: break; ! 393: case 'S': /* slant */ ! 394: fscanf(fp, "%d", &n); ! 395: t_slant(n); ! 396: break; ! 397: } ! 398: while ((c = getc(fp)) != '\n') /* skip rest of input line */ ! 399: if (c == EOF) ! 400: break; ! 401: } ! 402: ! 403: fileinit() /* read in font and code files, etc. */ ! 404: { ! 405: int i, fin, nw; ! 406: char *malloc(), *filebase, *p; ! 407: char temp[60]; ! 408: ! 409: /* open table for device, ! 410: /* read in resolution, size info, font info, etc. ! 411: /* and set params ! 412: */ ! 413: sprintf(temp, "%s/dev%s/desc.out", fontdir, devname); ! 414: if ((fin = open(temp, 0)) < 0) { ! 415: error(FATAL, "can't open tables for %s\n", temp); ! 416: } ! 417: read(fin, &dev, sizeof(struct dev)); ! 418: nfonts = dev.nfonts; ! 419: nsizes = dev.nsizes; ! 420: nchtab = dev.nchtab; ! 421: filebase = malloc(dev.filesize); /* enough room for whole file */ ! 422: read(fin, filebase, dev.filesize); /* all at once */ ! 423: pstab = (int *) filebase; ! 424: chtab = pstab + nsizes + 1; ! 425: chname = (char *) (chtab + dev.nchtab); ! 426: p = chname + dev.lchname; ! 427: for (i = 1; i <= nfonts; i++) { ! 428: fontbase[i] = (struct font *) p; ! 429: nw = *p & BMASK; /* 1st thing is width count */ ! 430: if (smnt == 0 && fontbase[i]->specfont == 1) ! 431: smnt = i; /* first special font */ ! 432: p += sizeof(struct font); /* that's what's on the beginning */ ! 433: widthtab[i] = p; ! 434: fitab[i] = p + nw; ! 435: p += nw + dev.nchtab + 128 - 32; ! 436: loadcode(i, nw, NULL); ! 437: t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); ! 438: if(dbg > 1) fontprint(i); ! 439: } ! 440: fontbase[0] = (struct font *) malloc(255 + dev.nchtab + (128-32) + sizeof (struct font)); ! 441: widthtab[0] = (char *) fontbase[0] + sizeof (struct font); ! 442: fontbase[0]->nwfont = 255; ! 443: close(fin); ! 444: } ! 445: ! 446: fontprint(i) /* debugging print of font i (0,...) */ ! 447: { ! 448: int j, k, n; ! 449: char *p; ! 450: ! 451: printf("font %d:\n", i); ! 452: p = (char *) fontbase[i]; ! 453: n = fontbase[i]->nwfont & BMASK; ! 454: printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n", ! 455: p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]); ! 456: printf("widths:\n"); ! 457: for (j=0; j <= n; j++) { ! 458: printf(" %2d", widthtab[i][j] & BMASK); ! 459: if (j % 20 == 19) printf("\n"); ! 460: } ! 461: printf("\ncodetab:\n"); ! 462: for (j=0; j <= n; j++) { ! 463: printf(" %2d", codetab[i][j] & BMASK); ! 464: if (j % 20 == 19) printf("\n"); ! 465: } ! 466: printf("\nfitab:\n"); ! 467: for (j=0; j <= dev.nchtab + 128-32; j++) { ! 468: printf(" %2d", fitab[i][j] & BMASK); ! 469: if (j % 20 == 19) printf("\n"); ! 470: } ! 471: printf("\n"); ! 472: } ! 473: ! 474: loadcode(n, nw, s1) /* load codetab on position n (0...); #chars is nw */ ! 475: int n, nw; ! 476: char *s1; ! 477: { ! 478: int cin; ! 479: char temp[60]; ! 480: char *malloc(); ! 481: ! 482: if (codetab[n] != NULL) ! 483: free(codetab[n]); ! 484: codetab[n] = malloc(nw); /* read in device codes */ ! 485: if (s1 == NULL || *s1 == 0) ! 486: sprintf(temp, "%s/dev%s/%s.code", fontdir, devname, fontbase[n]->namefont); ! 487: else ! 488: sprintf(temp, "%s/%s.code", s1, fontbase[n]->namefont); ! 489: if ((cin = open(temp, 0)) < 0) ! 490: error(FATAL, "can't open code tables %s", temp); ! 491: read(cin, codetab[n], nw); ! 492: close(cin); ! 493: } ! 494: ! 495: loadfont(n, s, s1) /* load font info for font s on position n (0...) */ ! 496: int n; ! 497: char *s, *s1; ! 498: { ! 499: char temp[60]; ! 500: int fin, nw, norig; ! 501: ! 502: if (n < 0 || n > NFONT) ! 503: error(FATAL, "illegal fp command %d %s", n, s); ! 504: if (strcmp(s, fontbase[n]->namefont) == 0) ! 505: return; ! 506: if (s1 == NULL || s1[0] == '\0') ! 507: sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s); ! 508: else ! 509: sprintf(temp, "%s/%s.out", s1, s); ! 510: if ((fin = open(temp, 0)) < 0) ! 511: error(FATAL, "can't open font table %s", temp); ! 512: norig = fontbase[n]->nwfont & BMASK; ! 513: read(fin, fontbase[n], norig + nchtab+128-32 + sizeof(struct font)); ! 514: if ((fontbase[n]->nwfont & BMASK) > norig) ! 515: error(FATAL, "Font %s too big for position %d\n", s, n); ! 516: close(fin); ! 517: nw = fontbase[n]->nwfont & BMASK; ! 518: widthtab[n] = (char *) fontbase[n] + sizeof(struct font); ! 519: fitab[n] = (char *) widthtab[n] + nw; ! 520: loadcode(n, nw, s1); ! 521: t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); ! 522: fontbase[n]->nwfont = norig; /* so can later use full original size */ ! 523: if (dbg > 1) fontprint(n); ! 524: } ! 525: ! 526: done() ! 527: { ! 528: if (tf == NULL) ! 529: exit(1); ! 530: t_reset('s'); ! 531: exit(0); ! 532: } ! 533: ! 534: error(f, s, a1, a2, a3, a4, a5, a6, a7) { ! 535: fprintf(stderr, "dcat: "); ! 536: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); ! 537: fprintf(stderr, "\n"); ! 538: if (f) ! 539: done(); ! 540: } ! 541: ! 542: ! 543: /* ! 544: Here beginneth all the stuff that really depends ! 545: on the Graphic Systems CAT. ! 546: */ ! 547: ! 548: ! 549: char devname[20] = "cat"; ! 550: ! 551: #define RES 432 /* CAT is 432 goobies per inch */ ! 552: /* this is the way the cat actually works. ! 553: /* the input resolution might be different, ! 554: /* but this version of the program doesn't use it yet. ! 555: */ ! 556: #define TRAILER (14 * res) /* trailer for last page */ ! 557: #define ROUND3(n) (((n+1)/3)*3) ! 558: #define IMOT 16 /* mandatory initial motion for typesetter */ ! 559: #define LMARGIN 0 /* left margin offset */ ! 560: #define HMAX (46 * (res/6)) /* maximum horizontal size = 46 picas */ ! 561: #define VMAX (15 * res) /* 15 inch page */ ! 562: ! 563: #define DOUBLE 0200 /* double lens indicated by this */ ! 564: ! 565: #define INIT 0100 /* initialize typesetter */ ! 566: /* supposedly the same as */ ! 567: /* DOWN, FWD, LRAIL, LMAG, LCASE */ ! 568: #define STOP 0111 /* all done */ ! 569: #define PAD 0101 /* lower rail padding */ ! 570: #define FWD 0107 /* horizontal forward (right) */ ! 571: #define BACK 0110 /* horizontal backward */ ! 572: #define UP 0114 /* vertical up (back up page) */ ! 573: #define DOWN 0112 /* down page */ ! 574: #define HMOT 0200 /* horizontal motion bit */ ! 575: #define VMOT 0140 /* vertical motion bits */ ! 576: #define SIZE 0120 /* size change */ ! 577: ! 578: /* font 1 = lower rail, lower mag */ ! 579: /* font 2 = upper rail, lower mag */ ! 580: /* font 3 = lower rail, upper mag */ ! 581: /* font 4 = upper rail, upper mag */ ! 582: /* god only knows how tilt factors into this */ ! 583: #define URAIL 0102 ! 584: #define LRAIL 0101 ! 585: #define UMAG 0103 ! 586: #define LMAG 0104 ! 587: #define LTILT 0117 /* for CAT 8 */ ! 588: #define UTILT 0116 /* copied from Scribe data base, not tested */ ! 589: #define UCASE 0106 /* upper case mode */ ! 590: #define LCASE 0105 ! 591: ! 592: #define MAXFWD 127 /* max number of horizontal units */ ! 593: #define MAXDOWN 31 /* max vertical units */ ! 594: ! 595: long paper; /* paper used */ ! 596: ! 597: static int hdir = FWD; /* current horizontal dir */ ! 598: static int vdir = DOWN; /* current vertical dir */ ! 599: ! 600: static int lastw = 0; /* last width, used by t_text */ ! 601: static int rail = -1; /* LRAIL or URAIL */ ! 602: static int mag = -1; /* LMAG or UMAG */ ! 603: static int tilt = -1; ! 604: static int curcase = -1; /* either LCASE or UCASE */ ! 605: static int hpos; /* current horizontal position (left = 0) */ ! 606: static int vpos; /* current vertical position (down positive) */ ! 607: ! 608: t_init(reinit) /* initialize device */ ! 609: int reinit; ! 610: { ! 611: int i; ! 612: ! 613: hpos = vpos = oldv = oldh = 0; ! 614: drawdot = '.'; ! 615: drawsize = 2; /* half size */ ! 616: setsize(t_size(10)); /* start somewhere */ ! 617: setfont(1); ! 618: if (!reinit) { ! 619: putc(INIT, tf); ! 620: hmot(IMOT); ! 621: vmot(3 * MAXDOWN); ! 622: hpos = vpos = 0; ! 623: movep(LMARGIN, 0); ! 624: } else { ! 625: putc(DOWN, tf); ! 626: putc(FWD, tf); ! 627: putc(LRAIL, tf); ! 628: putc(LMAG, tf); ! 629: putc(LCASE, tf); ! 630: } ! 631: } ! 632: ! 633: #define MAXSTATE 5 ! 634: ! 635: struct state { ! 636: int ssize; ! 637: int sfont; ! 638: int shpos; ! 639: int svpos; ! 640: int shorig; ! 641: int svorig; ! 642: }; ! 643: struct state state[MAXSTATE]; ! 644: struct state *statep = state; ! 645: ! 646: t_push() /* begin a new block */ ! 647: { ! 648: hflush(); ! 649: statep->ssize = size; ! 650: statep->sfont = font; ! 651: statep->shorig = horig; ! 652: statep->svorig = vorig; ! 653: statep->shpos = hpos; ! 654: statep->svpos = vpos; ! 655: horig = hpos; ! 656: vorig = vpos; ! 657: hpos = vpos = 0; ! 658: if (statep++ >= state+MAXSTATE) ! 659: error(FATAL, "{ nested too deep"); ! 660: hpos = vpos = 0; ! 661: } ! 662: ! 663: t_pop() /* pop to previous state */ ! 664: { ! 665: if (--statep < state) ! 666: error(FATAL, "extra }"); ! 667: size = statep->ssize; ! 668: font = statep->sfont; ! 669: hpos = statep->shpos; ! 670: vpos = statep->svpos; ! 671: horig = statep->shorig; ! 672: vorig = statep->svorig; ! 673: } ! 674: ! 675: t_page(n) /* do whatever new page functions */ ! 676: { ! 677: int i; ! 678: ! 679: if (output) { ! 680: if (tf != stdout) ! 681: paper += vpos; ! 682: if (++scount >= spage) { ! 683: t_reset('p'); ! 684: scount = 0; ! 685: } ! 686: } ! 687: vpos = 0; ! 688: oldv = 0; ! 689: output = 1; ! 690: /* somehow get to left margin? */ ! 691: if (nolist == 0) ! 692: return; /* no -o specified */ ! 693: output = 0; ! 694: for (i = 0; i < nolist; i += 2) ! 695: if (n >= olist[i] && n <= olist[i+1]) { ! 696: output = 1; ! 697: break; ! 698: } ! 699: } ! 700: ! 701: t_newline() /* do whatever for the end of a line */ ! 702: { ! 703: hpos = 0; /* because we want to be back at the left margin */ ! 704: } ! 705: ! 706: t_size(n) /* convert integer to internal size number*/ ! 707: int n; ! 708: { ! 709: int i; ! 710: ! 711: if (n <= pstab[0]) ! 712: return(1); ! 713: else if (n >= pstab[nsizes-1]) ! 714: return(nsizes); ! 715: for (i = 0; n > pstab[i]; i++) ! 716: ; ! 717: return(i+1); ! 718: } ! 719: ! 720: t_charht(n) /* set character height to n */ ! 721: int n; ! 722: { ! 723: } ! 724: ! 725: t_slant(n) /* set slant to n */ ! 726: int n; ! 727: { ! 728: } ! 729: ! 730: t_font(s) /* convert string to internal font number */ ! 731: char *s; ! 732: { ! 733: int n; ! 734: ! 735: n = atoi(s); ! 736: if (n < 0 || n > nfonts) ! 737: n = 1; ! 738: return(n); ! 739: } ! 740: ! 741: t_text(s) /* print string s as text */ ! 742: char *s; ! 743: { ! 744: int c, w; ! 745: char str[100]; ! 746: ! 747: if (!output) ! 748: return; ! 749: while (c = *s++) { ! 750: if (c == '\\') { ! 751: switch (c = *s++) { ! 752: case '\\': ! 753: case 'e': ! 754: put1('\\'); ! 755: break; ! 756: case '(': ! 757: str[0] = *s++; ! 758: str[1] = *s++; ! 759: str[2] = '\0'; ! 760: put1s(str); ! 761: break; ! 762: } ! 763: } else { ! 764: put1(c); ! 765: } ! 766: hmot(lastw); ! 767: if (dbg) printf("width = %d\n", lastw); ! 768: } ! 769: } ! 770: ! 771: t_reset(c) ! 772: { ! 773: int n; ! 774: ! 775: if (output) ! 776: paper += vpos; ! 777: output = 1; /* by God */ ! 778: putc(INIT, tf); ! 779: putc(STOP, tf); ! 780: for (n = 0; n < 8; n++) /* flush out CAT internal buffer */ ! 781: putc(PAD, tf); ! 782: fflush(tf); ! 783: } ! 784: ! 785: char *tracct[] = { /* accounting file */ ! 786: "/usr/adm/tracct", ! 787: "r70!/usr/adm/tracct" ! 788: }; ! 789: ! 790: account() /* record paper use */ ! 791: { ! 792: FILE *f = NULL; ! 793: char *name, *getlogin(); ! 794: int i; ! 795: ! 796: return; /* for now */ ! 797: if (tf == stdout) ! 798: return; ! 799: for(i=0; i<sizeof(tracct)/sizeof(*tracct) && f== NULL; i++) ! 800: f = fopen(tracct[i], "a"); ! 801: if(f != NULL) { ! 802: name = getlogin(); ! 803: if (name == NULL) ! 804: name = "???"; ! 805: fprintf(f, "%4d %s\n", (int)(paper/res + 20+6)/12, name); ! 806: } ! 807: } ! 808: ! 809: t_trailer() ! 810: { ! 811: return; ! 812: vpos = oldv = 0; ! 813: vgoto(TRAILER); ! 814: vpos = oldv = 0; ! 815: } ! 816: ! 817: movep(x, y) /* go to internal position x, y */ ! 818: int x, y; ! 819: { ! 820: hmot(x - hpos); ! 821: vmot(ROUND3(y) - vpos); ! 822: } ! 823: ! 824: hflush() /* actual horizontal output occurs here */ ! 825: { ! 826: int htrue; ! 827: int k, dir, n; ! 828: ! 829: if (!output) ! 830: return; ! 831: htrue = hpos + horig; ! 832: n = htrue - oldh; ! 833: if (htrue+n > HMAX) ! 834: n = HMAX - htrue; ! 835: if (htrue+n < 0) ! 836: n = -htrue; ! 837: htrue += n; ! 838: dir = (n >= 0) ? FWD : BACK; ! 839: if (dir != hdir) ! 840: putc(hdir = dir, tf); ! 841: if (n < 0) ! 842: n = -n; ! 843: while (n > 0) { ! 844: k = (n > MAXFWD) ? MAXFWD : n; ! 845: putc(HMOT | ~k, tf); ! 846: n -= k; ! 847: } ! 848: oldh = htrue + horig; ! 849: } ! 850: ! 851: vgoto(n) ! 852: { ! 853: vmot(n - vpos); ! 854: } ! 855: ! 856: vmot(n) /* generate n units of vertical motion */ ! 857: int n; ! 858: { ! 859: int dir, k; ! 860: if (vpos+n > VMAX) ! 861: n = VMAX - vpos; ! 862: if (vpos+n < 0) ! 863: n = -vpos; ! 864: vpos += n; ! 865: vpos = ROUND3(vpos); ! 866: dir = (n >= 0) ? DOWN : UP; ! 867: if (dir != vdir) ! 868: putc(vdir = dir, tf); ! 869: if (n < 0) ! 870: n = -n; ! 871: n = ((n+1) / 3); /* round to multiple of 3 */ ! 872: while (n > 0) { ! 873: k = (n > MAXDOWN) ? MAXDOWN : n; ! 874: putc(VMOT | (~k & MAXDOWN), tf); ! 875: n -= k; ! 876: } ! 877: if (vpos % 3 != 0) ! 878: fprintf(stderr, "vpos = %d\n", vpos); ! 879: } ! 880: ! 881: ! 882: put1s(s) /* s is a funny char name */ ! 883: char *s; ! 884: { ! 885: int i; ! 886: ! 887: if (!output) ! 888: return; ! 889: if (dbg) printf("%s ", s); ! 890: for (i = 0; i < nchtab; i++) ! 891: if (strcmp(&chname[chtab[i]], s) == 0) ! 892: break; ! 893: if (i < nchtab) ! 894: put1(i + 128); ! 895: } ! 896: ! 897: put1(c) /* output char c */ ! 898: int c; ! 899: { ! 900: char *pw; ! 901: register char *p; ! 902: register int i, k; ! 903: int j, ofont, code, w; ! 904: ! 905: if (!output) ! 906: return; ! 907: c -= 32; ! 908: if (c <= 0) { ! 909: if (dbg) printf("non-exist 0%o\n", c+32); ! 910: lastw = widthtab[font][0] * pstab[size-1] / dev.unitwidth; ! 911: return; ! 912: } ! 913: k = ofont = font; ! 914: i = fitab[font][c] & BMASK; ! 915: if (i != 0) { /* it's on this font */ ! 916: p = codetab[font]; ! 917: pw = widthtab[font]; ! 918: } else if (smnt > 0) { /* on special (we hope) */ ! 919: for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)) ! 920: if ((i = fitab[k][c] & BMASK) != 0) { ! 921: p = codetab[k]; ! 922: pw = widthtab[k]; ! 923: setfont(k); ! 924: break; ! 925: } ! 926: } ! 927: if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) { ! 928: if (dbg) printf("not found 0%o\n", c+32); ! 929: return; ! 930: } ! 931: if (code < 64) { /* it's lower case */ ! 932: if (curcase != LCASE) ! 933: putc(curcase = LCASE, tf); ! 934: } else { ! 935: if (curcase != UCASE) ! 936: putc(curcase = UCASE, tf); ! 937: code -= 64; ! 938: } ! 939: hflush(); ! 940: if (dbg) { ! 941: if (isprint(c+32)) ! 942: printf("%c %d\n", c+32, code); ! 943: else ! 944: printf("%03o %d\n", c+32, code); ! 945: } else ! 946: putc(code, tf); /* character is < 254 */ ! 947: if (font != ofont) ! 948: setfont(ofont); ! 949: lastw = pw[i] & 077; ! 950: lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth; ! 951: } ! 952: ! 953: setsize(n) /* set point size to n (internal) */ ! 954: int n; ! 955: { ! 956: static int stab[] ={ 0,010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217 }; ! 957: int spos; ! 958: ! 959: if (!output) ! 960: return; ! 961: if (n == size) ! 962: return; /* already there */ ! 963: putc(stab[n] & ~DOUBLE | SIZE, tf); ! 964: if (!(stab[size] & DOUBLE) && stab[n] & DOUBLE) { ! 965: spos = hpos; ! 966: hmot(55); /* single-double transition */ ! 967: hpos = spos; /* lens-compensation motion doesn't affect absolute position */ ! 968: } else if (stab[size] & DOUBLE && !(stab[n] & DOUBLE)) { ! 969: spos = hpos; ! 970: hmot(-55); /* double-single transition */ ! 971: hpos = spos; ! 972: } ! 973: size = n; ! 974: } ! 975: ! 976: /* font position info: */ ! 977: ! 978: struct { ! 979: char *name; ! 980: int number; ! 981: } fontname[NFONT+1]; ! 982: ! 983: t_fp(n, s, si) /* font position n now contains font s, intname si */ ! 984: int n; ! 985: char *s, *si; ! 986: { ! 987: fontname[n].name = s; ! 988: fontname[n].number = atoi(si); ! 989: } ! 990: ! 991: setfont(n) /* set font to n */ ! 992: int n; ! 993: { ! 994: if (!output) ! 995: return; ! 996: /* needs stuff added for 8 font version */ ! 997: /* easiest to loop over 3 font bits */ ! 998: /* masking them off */ ! 999: switch (n) { ! 1000: case 1: ! 1001: if (rail != LRAIL) ! 1002: putc(rail = LRAIL, tf); ! 1003: if (mag != LMAG) ! 1004: putc(mag = LMAG, tf); ! 1005: break; ! 1006: case 2: ! 1007: if (rail != URAIL) ! 1008: putc(rail = URAIL, tf); ! 1009: if (mag != LMAG) ! 1010: putc(mag = LMAG, tf); ! 1011: break; ! 1012: case 3: ! 1013: if (rail != LRAIL) ! 1014: putc(rail = LRAIL, tf); ! 1015: if (mag != UMAG) ! 1016: putc(mag = UMAG, tf); ! 1017: break; ! 1018: case 4: ! 1019: if (rail != URAIL) ! 1020: putc(rail = URAIL, tf); ! 1021: if (mag != UMAG) ! 1022: putc(mag = UMAG, tf); ! 1023: break; ! 1024: default: ! 1025: error(FATAL, "illegal font %d\n", n); ! 1026: } ! 1027: font = n; ! 1028: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.