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