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