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