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