|
|
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 10 ! 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: break; ! 424: /* these don't belong here... */ ! 425: case 'H': /* char height */ ! 426: fscanf(fp, "%d", &n); ! 427: t_charht(n); ! 428: break; ! 429: case 'S': /* slant */ ! 430: fscanf(fp, "%d", &n); ! 431: t_slant(n); ! 432: break; ! 433: } ! 434: while ((c = getc(fp)) != '\n') /* skip rest of input line */ ! 435: if (c == EOF) ! 436: break; ! 437: } ! 438: ! 439: fileinit() /* read in font and code files, etc. */ ! 440: { ! 441: int i, fin, nw; ! 442: char *malloc(), *filebase, *p; ! 443: char temp[60]; ! 444: ! 445: /* open table for device, ! 446: /* read in resolution, size info, font info, etc. ! 447: /* and set params ! 448: */ ! 449: sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname); ! 450: if ((fin = open(temp, 0)) < 0) ! 451: error(FATAL, "can't open tables for %s\n", temp); ! 452: read(fin, &dev, sizeof(struct dev)); ! 453: nfonts = dev.nfonts; ! 454: nsizes = dev.nsizes; ! 455: nchtab = dev.nchtab; ! 456: filebase = malloc(dev.filesize); /* enough room for whole file */ ! 457: read(fin, filebase, dev.filesize); /* all at once */ ! 458: pstab = (short *) filebase; ! 459: chtab = pstab + nsizes + 1; ! 460: chname = (char *) (chtab + dev.nchtab); ! 461: p = chname + dev.lchname; ! 462: for (i = 1; i <= nfonts; i++) { ! 463: fontbase[i] = (struct Font *) p; ! 464: nw = *p & BYTEMASK; /* 1st thing is width count */ ! 465: if (smnt == 0 && fontbase[i]->specfont == 1) ! 466: smnt = i; /* first special font */ ! 467: p += sizeof(struct Font); /* that's what's on the beginning */ ! 468: widthtab[i] = p; ! 469: codetab[i] = p + 2 * nw; ! 470: fitab[i] = p + 3 * nw; ! 471: p += 3 * nw + dev.nchtab + 128 - 32; ! 472: t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); ! 473: if(dbg > 1) fontprint(i); ! 474: } ! 475: fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct Font)); ! 476: widthtab[0] = (char *) fontbase[0] + sizeof (struct Font); ! 477: fontbase[0]->nwfont = 255; ! 478: close(fin); ! 479: } ! 480: ! 481: fontprint(i) /* debugging print of font i (0,...) */ ! 482: { ! 483: int j, k, n; ! 484: char *p; ! 485: ! 486: printf("font %d:\n", i); ! 487: p = (char *) fontbase[i]; ! 488: n = fontbase[i]->nwfont & BYTEMASK; ! 489: printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n", ! 490: p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]); ! 491: printf("widths:\n"); ! 492: for (j=0; j <= n; j++) { ! 493: printf(" %2d", widthtab[i][j] & BYTEMASK); ! 494: if (j % 20 == 19) printf("\n"); ! 495: } ! 496: printf("\ncodetab:\n"); ! 497: for (j=0; j <= n; j++) { ! 498: printf(" %2d", codetab[i][j] & BYTEMASK); ! 499: if (j % 20 == 19) printf("\n"); ! 500: } ! 501: printf("\nfitab:\n"); ! 502: for (j=0; j <= dev.nchtab + 128-32; j++) { ! 503: printf(" %2d", fitab[i][j] & BYTEMASK); ! 504: if (j % 20 == 19) printf("\n"); ! 505: } ! 506: printf("\n"); ! 507: } ! 508: ! 509: loadfont(n, s, s1) /* load font info for font s on position n (0...) */ ! 510: int n; ! 511: char *s, *s1; ! 512: { ! 513: char temp[60]; ! 514: int fin, nw, norig; ! 515: ! 516: if (n < 0 || n > NFONT) ! 517: error(FATAL, "illegal fp command %d %s", n, s); ! 518: if (strcmp(s, fontbase[n]->namefont) == 0) ! 519: return; ! 520: if (s1 && s1[0]) ! 521: s = s1; ! 522: sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s); ! 523: if ((fin = open(temp, 0)) < 0) ! 524: error(FATAL, "can't open font table %s", temp); ! 525: norig = fontbase[n]->nwfont & BYTEMASK; ! 526: read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct Font)); ! 527: if ((fontbase[n]->nwfont & BYTEMASK) > norig) ! 528: error(FATAL, "Font %s too big for position %d\n", s, n); ! 529: close(fin); ! 530: nw = fontbase[n]->nwfont & BYTEMASK; ! 531: widthtab[n] = (char *) fontbase[n] + sizeof(struct Font); ! 532: codetab[n] = (char *) widthtab[n] + 2 * nw; ! 533: fitab[n] = (char *) widthtab[n] + 3 * nw; ! 534: t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); ! 535: fontbase[n]->nwfont = norig; /* so can later use full original size */ ! 536: if (dbg > 1) fontprint(n); ! 537: } ! 538: ! 539: done() ! 540: { ! 541: if (tf == NULL) ! 542: exit(1); ! 543: putint(0); /* some no-ops */ ! 544: putint(0); ! 545: t_reset('s'); ! 546: exit(0); ! 547: } ! 548: ! 549: error(f, s, a1, a2, a3, a4, a5, a6, a7) { ! 550: fprintf(stderr, "d202: "); ! 551: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); ! 552: fprintf(stderr, "\n"); ! 553: if (f) ! 554: done(); ! 555: } ! 556: ! 557: ! 558: /* ! 559: Here beginneth all the stuff that really depends ! 560: on the 202 (we hope). ! 561: */ ! 562: ! 563: ! 564: char devname[20] = "202"; ! 565: ! 566: #define RES 972 /* 202 is 288 goobies per inch vertically */ ! 567: /* but 972 horizontally! */ ! 568: /* can get 486 vertically by using electronic baseline jump */ ! 569: #define TRAILER (14 * res) ! 570: #define LMARGIN 0 /* left margin offset */ ! 571: #define HMAX (48 * (res/6)) /* maximum horizontal size = 48 picas */ ! 572: #define VMAX (15 * res) /* 15 inch page */ ! 573: ! 574: #define HOR 254 /* next int is horizontal motion */ ! 575: #define ESCAPE 255 /* general-purpose escape for all others */ ! 576: #define BASEINIT -162 /* initial baseline for 202 */ ! 577: ! 578: ! 579: ! 580: int lastc, lastw; /* last character and width (not used) */ ! 581: int lastfont = -2; /* last real font sent to 202 */ ! 582: ! 583: long paper; /* paper used */ ! 584: ! 585: int refscr = 0; ! 586: ! 587: t_init(reinit) /* initialize device */ ! 588: int reinit; ! 589: { ! 590: int i; ! 591: ! 592: hpos = vpos = oldv = oldh = 0; ! 593: refscr = 0; ! 594: /* the above are not true until the code below happens*/ ! 595: setsize(t_size(10)); /* start somewhere */ ! 596: setfont(font = 1); ! 597: sendfont(); ! 598: putesc("v"); ! 599: putint(72); /* 1/4 inch initial lead */ ! 600: putesc("j"); ! 601: putint(BASEINIT); ! 602: putesc("H"); ! 603: putint(0); /* make sure at left */ ! 604: ! 605: if (drawdot) { /* -. flag was given */ ! 606: drawsize = 2; ! 607: } else { ! 608: for (i = 0; i < nchtab; i++) ! 609: if (strcmp(&chname[chtab[i]], "l.") == 0) ! 610: break; ! 611: if (i < nchtab) { ! 612: drawdot = i + 128; ! 613: drawsize = 1; ! 614: } else { ! 615: drawdot = '.'; ! 616: drawsize = 2; /* half size */ ! 617: } ! 618: } ! 619: } ! 620: ! 621: #define MAXSTATE 5 ! 622: ! 623: struct state { ! 624: int ssize; ! 625: int sfont; ! 626: int shpos; ! 627: int svpos; ! 628: int shorig; ! 629: int svorig; ! 630: }; ! 631: struct state state[MAXSTATE]; ! 632: struct state *statep = state; ! 633: ! 634: t_push() /* begin a new block */ ! 635: { ! 636: hflush(); ! 637: statep->ssize = size; ! 638: statep->sfont = font; ! 639: statep->shorig = horig; ! 640: statep->svorig = vorig; ! 641: statep->shpos = hpos; ! 642: statep->svpos = vpos; ! 643: horig = hpos; ! 644: vorig = vpos; ! 645: hpos = vpos = 0; ! 646: if (statep++ >= state+MAXSTATE) ! 647: error(FATAL, "{ nested too deep"); ! 648: hpos = vpos = 0; ! 649: } ! 650: ! 651: t_pop() /* pop to previous state */ ! 652: { ! 653: if (--statep < state) ! 654: error(FATAL, "extra }"); ! 655: size = statep->ssize; ! 656: font = statep->sfont; ! 657: hpos = statep->shpos; ! 658: vpos = statep->svpos; ! 659: horig = statep->shorig; ! 660: vorig = statep->svorig; ! 661: } ! 662: ! 663: t_page(n) /* do whatever new page functions */ ! 664: { ! 665: int i; ! 666: ! 667: if (output) { ! 668: if (tf != stdout) ! 669: paper += vpos; ! 670: if (++scount >= spage) { ! 671: t_reset('p'); ! 672: scount = 0; ! 673: } ! 674: } ! 675: refscr -= vpos; ! 676: vpos = 0; ! 677: oldv = 0; ! 678: output = 1; ! 679: putesc("p"); ! 680: putint(n); ! 681: putesc("H"); ! 682: putint(0); ! 683: putflush(); ! 684: if (nolist == 0) ! 685: return; /* no -o specified */ ! 686: if (n > maxolist) /* we've gone past the end */ ! 687: done(); ! 688: output = 0; ! 689: for (i = 0; i < nolist; i += 2) ! 690: if (n >= olist[i] && n <= olist[i+1]) { ! 691: output = 1; ! 692: break; ! 693: } ! 694: } ! 695: ! 696: t_newline() /* do whatever for the end of a line */ ! 697: { ! 698: hpos = 0; /* because we're now back at the left margin */ ! 699: if (output) ! 700: putesc("n"); ! 701: } ! 702: ! 703: t_size(n) /* convert integer to internal size number*/ ! 704: int n; ! 705: { ! 706: int i; ! 707: ! 708: if (n <= pstab[0]) ! 709: return(1); ! 710: else if (n >= pstab[nsizes-1]) ! 711: return(nsizes); ! 712: for (i = 0; n > pstab[i]; i++) ! 713: ; ! 714: return(i+1); ! 715: } ! 716: ! 717: t_charht(n) /* set character height to n */ ! 718: int n; ! 719: { ! 720: putesc("xH"); ! 721: putint(n); ! 722: putc('\n', tf); ! 723: } ! 724: ! 725: t_slant(n) /* set slant to n */ ! 726: int n; ! 727: { ! 728: putesc("xS"); ! 729: putint(n); ! 730: putc('\n', tf); ! 731: } ! 732: ! 733: t_font(s) /* convert string to internal font number */ ! 734: char *s; ! 735: { ! 736: int n; ! 737: ! 738: n = atoi(s); ! 739: if (n < 0 || n > nfonts) ! 740: n = 1; ! 741: return(n); ! 742: } ! 743: ! 744: t_text(s) /* print string s as text. not used */ ! 745: char *s; ! 746: { ! 747: int c, w; ! 748: char str[100]; ! 749: ! 750: if (!output) ! 751: return; ! 752: while (c = *s++) { ! 753: if (c == '\\') { ! 754: switch (c = *s++) { ! 755: case '\\': ! 756: case 'e': ! 757: put1('\\'); ! 758: break; ! 759: case '(': ! 760: str[0] = *s++; ! 761: str[1] = *s++; ! 762: str[2] = '\0'; ! 763: put1s(str); ! 764: break; ! 765: } ! 766: } else { ! 767: put1(c); ! 768: } ! 769: hmot(lastw); ! 770: if (dbg) printf("width = %d\n", lastw); ! 771: } ! 772: } ! 773: ! 774: t_reset(c) ! 775: { ! 776: int n; ! 777: ! 778: if (output) ! 779: paper += vpos; ! 780: output = 1; /* by God */ ! 781: if (c == 'p') ! 782: putesc("xp\n"); ! 783: else ! 784: putesc("xs\n"); ! 785: fflush(tf); ! 786: } ! 787: ! 788: char *tracct = "/usr/adm/tracct"; ! 789: ! 790: account() /* record paper use */ ! 791: { ! 792: FILE *f = NULL; ! 793: char *name, *getlogin(); ! 794: ! 795: if (tf == stdout) ! 796: return; ! 797: f = fopen(tracct, "a"); ! 798: if(f != NULL) { ! 799: name = getlogin(); ! 800: if (name == NULL) ! 801: name = "???"; ! 802: fprintf(f, "%4d %s\n", (int)(paper/res + 20+6)/12, name); ! 803: } ! 804: } ! 805: ! 806: t_trailer() ! 807: { ! 808: /* vpos = oldv = 0; ! 809: /* vgoto(TRAILER); ! 810: /* vpos = oldv = 0; ! 811: */ ! 812: } ! 813: ! 814: hflush() /* actual horizontal output occurs here */ ! 815: { ! 816: register int dh; ! 817: int htrue; ! 818: ! 819: if (!output) ! 820: return; ! 821: htrue = hpos + horig; ! 822: dh = htrue - oldh; ! 823: if (dh > 0 && dh < 256) { ! 824: if (dbg) ! 825: printf(" h%d\n", dh & BYTEMASK); ! 826: else { ! 827: putc(HOR, tf); ! 828: putc(dh, tf); ! 829: } ! 830: } else if (dh != 0) { ! 831: if (dbg) ! 832: printf(" esc H %d\n", htrue+xoffset); ! 833: else { ! 834: putesc("H"); ! 835: putint(htrue+xoffset); ! 836: } ! 837: } ! 838: oldh = htrue + horig; ! 839: } ! 840: ! 841: vgoto(n) ! 842: { ! 843: int deltav, nelec, ps, vtrue, ntrue; ! 844: ! 845: /* To understand this function, you need to know the ! 846: /* following characteristics of the 202: ! 847: /* one unit of electronic baseline jump = 1/486 inch; ! 848: /* one unit of mechanical motion = 1/288 inch; ! 849: /* further, mechanical motion accumulates and persists, ! 850: /* while electronic baseline jump persists but doesn't accumulate. ! 851: /* The window is 1296 units high, and we leave a margin on top of ! 852: /* 14*(current point size) and on the bottom of 4*(curr pt sz). ! 853: /* Our inductive assertion on entering this function ! 854: /* is that the current vertical position is within the margins. ! 855: /* If we want to move to a point between the margins, we ! 856: /* perform this motion with a pure electronic baseline jump. ! 857: /* Otherwise, we move the paper mechanically so that the desired ! 858: /* point is close to the top of the screen, subject to the margin ! 859: /* constraints. ! 860: */ ! 861: ! 862: if (!output) ! 863: return; ! 864: if (dbg) printf(" vgoto %d to %d\n", vpos, n); ! 865: ps = (pstab[size]-1)>72?72:pstab[size-1]; ! 866: vtrue = vpos + vorig; ! 867: ntrue = n + vorig; ! 868: if (refscr < ntrue || refscr - windowht - 14*ps > ntrue) { ! 869: /* mechanical motion */ ! 870: deltav = ntrue - refscr; ! 871: if (deltav < 0 && deltav > -54) ! 872: deltav -= 54; ! 873: if (deltav > 0 && deltav < 54) ! 874: deltav += 54; ! 875: deltav = (deltav > 0) ? ((deltav/54)*54) : -((-(deltav-53)/54)*54); ! 876: if (deltav) { ! 877: putesc ("v"); ! 878: if (deltav > 0) ! 879: putint(deltav/54*16); ! 880: else ! 881: putint(-(-deltav/54)*16); ! 882: refscr += deltav; ! 883: vtrue += deltav; ! 884: } ! 885: } ! 886: if (ntrue - vtrue) { ! 887: nelec = -(324 - (refscr - ntrue)); ! 888: if (nelec > 0) ! 889: nelec /= 2; ! 890: else ! 891: nelec = -((-nelec) / 2); ! 892: putesc("j"); ! 893: putint(nelec); ! 894: } ! 895: vpos = n; ! 896: } ! 897: ! 898: ! 899: put1s(s) /* s is a funny char name */ ! 900: char *s; ! 901: { ! 902: int i; ! 903: static char lasti = 0; /* cache last hit */ ! 904: ! 905: if (!output) ! 906: return; ! 907: if (dbg) printf("%s ", s); ! 908: if (strcmp(&chname[chtab[lasti]], s) != 0) ! 909: for (i = 0; i < nchtab; i++) ! 910: if (strcmp(&chname[chtab[i]], s) == 0) ! 911: break; ! 912: if (i < nchtab) ! 913: put1(i + 128); ! 914: } ! 915: ! 916: put1(c) /* output char c */ ! 917: int c; ! 918: { ! 919: char *pw; ! 920: register char *p; ! 921: register int i, k; ! 922: int j, ofont, code, w; ! 923: ! 924: if (!output) ! 925: return; ! 926: c -= 32; ! 927: if (c <= 0) { ! 928: if (dbg) printf("non-exist 0%o\n", c+32); ! 929: return; ! 930: } ! 931: k = ofont = font; ! 932: i = fitab[font][c] & BYTEMASK; ! 933: if (i != 0) { /* it's on this font */ ! 934: p = codetab[font]; ! 935: pw = widthtab[font]; ! 936: } else if (smnt > 0) { /* on special (we hope) */ ! 937: for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)) ! 938: if ((i = fitab[k][c] & BYTEMASK) != 0) { ! 939: p = codetab[k]; ! 940: pw = widthtab[k]; ! 941: setfont(k); ! 942: break; ! 943: } ! 944: } ! 945: if (i == 0 || (code = p[i] & BYTEMASK) == 0 || k > nfonts) { ! 946: if (dbg) printf("not found 0%o\n", c+32); ! 947: return; ! 948: } ! 949: hflush(); ! 950: sendfont(); ! 951: if (dbg) { ! 952: if (isprint(c+32)) ! 953: printf("%c %d\n", c+32, code); ! 954: else ! 955: printf(" C%d\n", code); ! 956: } else ! 957: putc(code, tf); /* character is < 254 */ ! 958: font = ofont; ! 959: } ! 960: ! 961: put1a(n) /* put single char by absolute number */ ! 962: int n; ! 963: { ! 964: hflush(); ! 965: sendfont(); ! 966: if (dbg) { ! 967: if (isprint(n)) ! 968: printf("%c %d\n", n, n); ! 969: else ! 970: printf(" N%d\n", n); ! 971: } else ! 972: putc(n, tf); /* character is < 254 */ ! 973: } ! 974: ! 975: setsize(n) /* set point size to n (internal) */ ! 976: int n; ! 977: { ! 978: ! 979: if (!output) ! 980: return; ! 981: if (n == size) ! 982: return; /* already there */ ! 983: /* for now, only cope with integer sizes */ ! 984: putesc("s"); ! 985: putint(pstab[n-1]); ! 986: size = n; ! 987: } ! 988: ! 989: /* font position info: */ ! 990: ! 991: struct { ! 992: char *name; ! 993: int number; ! 994: } fontname[NFONT+1]; ! 995: ! 996: t_fp(n, s, si) /* font position n now contains font s, intname si */ ! 997: int n; ! 998: char *s, *si; ! 999: { ! 1000: fontname[n].name = s; ! 1001: fontname[n].number = atoi(si); ! 1002: } ! 1003: ! 1004: setfont(n) /* set font to n */ ! 1005: int n; ! 1006: { ! 1007: if (!output) ! 1008: return; ! 1009: if (n < 0 || n > NFONT) ! 1010: error(FATAL, "illegal font %d\n", n); ! 1011: font = n; ! 1012: } ! 1013: ! 1014: sendfont() /* actually send a font command if needed */ ! 1015: { ! 1016: if (font != lastfont) { ! 1017: putesc("f"); ! 1018: putint(fontname[font].number); ! 1019: lastfont = font; ! 1020: } ! 1021: } ! 1022: ! 1023: putint(n) ! 1024: { ! 1025: if (dbg) { ! 1026: printf("%02d\n", n); ! 1027: return; ! 1028: } ! 1029: putc(n>>8, tf); ! 1030: putc(n, tf); ! 1031: } ! 1032: ! 1033: putesc(s) ! 1034: register char *s; ! 1035: { ! 1036: if (dbg) { ! 1037: printf(" esc %s ", s); ! 1038: return; ! 1039: } ! 1040: putc(ESCAPE, tf); ! 1041: while (*s) ! 1042: putc(*s++, tf); ! 1043: } ! 1044: ! 1045: putflush() /* flush it out */ ! 1046: { ! 1047: fflush(tf); ! 1048: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.