|
|
1.1 ! root 1: /* ! 2: * t6.c ! 3: * ! 4: * width functions, sizes and fonts ! 5: */ ! 6: ! 7: #include "tdef.h" ! 8: #include "dev.h" ! 9: #include <sgtty.h> ! 10: #include <ctype.h> ! 11: #include "ext.h" ! 12: ! 13: /* fitab[f][c] is 0 if c is not on font f ! 14: /* if it's non-zero, c is in fontab[f] at position ! 15: /* fitab[f][c]. ! 16: */ ! 17: extern struct Font *fontbase[NFONT+1]; ! 18: extern char *codetab[NFONT+1]; ! 19: extern int nchtab; ! 20: ! 21: int fontlab[NFONT+1]; ! 22: short *pstab; ! 23: int cstab[NFONT+1]; ! 24: int ccstab[NFONT+1]; ! 25: int bdtab[NFONT+1]; ! 26: int sbold = 0; ! 27: ! 28: width(j) ! 29: register tchar j; ! 30: { ! 31: register i, k; ! 32: ! 33: if (j & (ZBIT|MOT)) { ! 34: if (iszbit(j)) ! 35: return(0); ! 36: if (isvmot(j)) ! 37: return(0); ! 38: k = absmot(j); ! 39: if (isnmot(j)) ! 40: k = -k; ! 41: return(k); ! 42: } ! 43: i = cbits(j); ! 44: if (i < ' ') { ! 45: if (i == '\b') ! 46: return(-widthp); ! 47: if (i == PRESC) ! 48: i = eschar; ! 49: else if (iscontrol(i)) ! 50: return(0); ! 51: } ! 52: if (i==ohc) ! 53: return(0); ! 54: i = trtab[i]; ! 55: if (i < 32) ! 56: return(0); ! 57: if (sfbits(j) == oldbits) { ! 58: xfont = pfont; ! 59: xpts = ppts; ! 60: } else ! 61: xbits(j, 0); ! 62: if (widcache[i-32].fontpts == (xfont<<8) + xpts && !setwdf) ! 63: k = widcache[i-32].width; ! 64: else { ! 65: k = getcw(i-32); ! 66: if (bd) ! 67: k += (bd - 1) * HOR; ! 68: if (cs) ! 69: k = cs; ! 70: } ! 71: widthp = k; ! 72: return(k); ! 73: } ! 74: ! 75: /* ! 76: * clear width cache-- s means just space ! 77: */ ! 78: zapwcache(s) ! 79: { ! 80: register i; ! 81: ! 82: if (s) { ! 83: widcache[0].fontpts = 0; ! 84: return; ! 85: } ! 86: for (i=0; i<NWIDCACHE; i++) ! 87: widcache[i].fontpts = 0; ! 88: } ! 89: ! 90: getcw(i) ! 91: register int i; ! 92: { ! 93: register int k; ! 94: register char *p; ! 95: register int x, j; ! 96: int nocache = 0; ! 97: ! 98: bd = 0; ! 99: if (i >= nchtab + 128-32) { ! 100: j = abscw(i + 32 - (nchtab+128)); ! 101: goto g0; ! 102: } ! 103: if (i == 0) { /* a blank */ ! 104: k = (fontab[xfont][0] * spacesz + 6) / 12; ! 105: /* this nonsense because .ss cmd uses 1/36 em as its units */ ! 106: /* and default is 12 */ ! 107: goto g1; ! 108: } ! 109: if ((j = fitab[xfont][i] & BYTEMASK) == 0) { /* it's not on current font */ ! 110: /* search through search list of xfont ! 111: /* to see what font it ought to be on. ! 112: /* searches S, then remaining fonts in wraparound order. ! 113: */ ! 114: nocache = 1; ! 115: if (smnt) { ! 116: int ii, jj; ! 117: for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) { ! 118: j = fitab[ii][i] & BYTEMASK; ! 119: if (j != 0) { ! 120: p = fontab[ii]; ! 121: k = *(p + j); ! 122: if (xfont == sbold) ! 123: bd = bdtab[ii]; ! 124: if (setwdf) ! 125: numtab[CT].val |= kerntab[ii][j]; ! 126: goto g1; ! 127: } ! 128: } ! 129: } ! 130: k = fontab[xfont][0]; /* leave a space-size space */ ! 131: goto g1; ! 132: } ! 133: g0: ! 134: p = fontab[xfont]; ! 135: if (setwdf) ! 136: numtab[CT].val |= kerntab[xfont][j]; ! 137: k = *(p + j); ! 138: g1: ! 139: if (!bd) ! 140: bd = bdtab[xfont]; ! 141: if (cs = cstab[xfont]) { ! 142: nocache = 1; ! 143: if (ccs = ccstab[xfont]) ! 144: x = ccs; ! 145: else ! 146: x = xpts; ! 147: cs = (cs * EMPTS(x)) / 36; ! 148: } ! 149: k = ((k&BYTEMASK) * xpts + (Unitwidth / 2)) / Unitwidth; ! 150: if (nocache|bd) ! 151: widcache[i].fontpts = 0; ! 152: else { ! 153: widcache[i].fontpts = (xfont<<8) + xpts; ! 154: widcache[i].width = k; ! 155: } ! 156: return(k); ! 157: /* Unitwidth is Units/Point, where ! 158: /* Units is the fundamental digitization ! 159: /* of the character set widths, and ! 160: /* Point is the number of goobies in a point ! 161: /* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6 ! 162: /* In effect, it's the size at which the widths ! 163: /* translate directly into units. ! 164: */ ! 165: } ! 166: ! 167: abscw(n) /* return index of abs char n in fontab[], etc. */ ! 168: { register int i, ncf; ! 169: ! 170: ncf = fontbase[xfont]->nwfont & BYTEMASK; ! 171: for (i = 0; i < ncf; i++) ! 172: if (codetab[xfont][i] == n) ! 173: return i; ! 174: return 0; ! 175: } ! 176: ! 177: xbits(i, bitf) ! 178: register tchar i; ! 179: { ! 180: register k; ! 181: ! 182: xfont = fbits(i); ! 183: k = sbits(i); ! 184: if (k) { ! 185: xpts = pstab[--k]; ! 186: oldbits = sfbits(i); ! 187: pfont = xfont; ! 188: ppts = xpts; ! 189: return; ! 190: } ! 191: switch (bitf) { ! 192: case 0: ! 193: xfont = font; ! 194: xpts = pts; ! 195: break; ! 196: case 1: ! 197: xfont = pfont; ! 198: xpts = ppts; ! 199: break; ! 200: case 2: ! 201: xfont = mfont; ! 202: xpts = mpts; ! 203: } ! 204: } ! 205: ! 206: ! 207: tchar setch(c) ! 208: { ! 209: register j; ! 210: char temp[50]; ! 211: register char *s; ! 212: extern char *chname; ! 213: extern short *chtab; ! 214: extern int nchtab; ! 215: ! 216: s = temp; ! 217: if (c == '(') { /* \(xx */ ! 218: if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0) ! 219: return(0); ! 220: } else { /* \C'...' */ ! 221: c = getach(); ! 222: while ((*s = getach()) != c && *s != '\n') ! 223: s++; ! 224: } ! 225: *s = '\0'; ! 226: for (j = 0; j < nchtab; j++) ! 227: if (strcmp(&chname[chtab[j]], temp) == 0) ! 228: return(j + 128 | chbits); ! 229: return(0); ! 230: } ! 231: ! 232: tchar setabs() /* set absolute char from \N'...' */ ! 233: { ! 234: int i, n, nf; ! 235: extern int nchtab; ! 236: ! 237: getch(); ! 238: n = 0; ! 239: n = inumb(&n); ! 240: getch(); ! 241: if (nonumb) ! 242: return 0; ! 243: return n + nchtab + 128; ! 244: } ! 245: ! 246: ! 247: ! 248: findft(i) ! 249: register int i; ! 250: { ! 251: register k; ! 252: ! 253: if ((k = i - '0') >= 0 && k <= nfonts && k < smnt) ! 254: return(k); ! 255: for (k = 0; fontlab[k] != i; k++) ! 256: if (k > nfonts) ! 257: return(-1); ! 258: return(k); ! 259: } ! 260: ! 261: ! 262: caseps() ! 263: { ! 264: register i; ! 265: ! 266: if (skip()) ! 267: i = apts1; ! 268: else { ! 269: noscale++; ! 270: i = inumb(&apts); /* this is a disaster for fractional point sizes */ ! 271: noscale = 0; ! 272: if (nonumb) ! 273: return; ! 274: } ! 275: casps1(i); ! 276: } ! 277: ! 278: ! 279: casps1(i) ! 280: register int i; ! 281: { ! 282: ! 283: /* ! 284: * in olden times, it used to ignore changes to 0 or negative. ! 285: * this is meant to allow the requested size to be anything, ! 286: * in particular so eqn can generate lots of \s-3's and still ! 287: * get back by matching \s+3's. ! 288: ! 289: if (i <= 0) ! 290: return; ! 291: */ ! 292: apts1 = apts; ! 293: apts = i; ! 294: pts1 = pts; ! 295: pts = findps(i); ! 296: mchbits(); ! 297: } ! 298: ! 299: ! 300: findps(i) ! 301: register int i; ! 302: { ! 303: register j, k; ! 304: ! 305: for (j=k=0 ; pstab[j] != 0 ; j++) ! 306: if (abs(pstab[j]-i) < abs(pstab[k]-i)) ! 307: k = j; ! 308: ! 309: return(pstab[k]); ! 310: } ! 311: ! 312: ! 313: mchbits() ! 314: { ! 315: register i, j, k; ! 316: ! 317: i = pts; ! 318: for (j = 0; i > (k = pstab[j]); j++) ! 319: if (!k) { ! 320: k = pstab[--j]; ! 321: break; ! 322: } ! 323: chbits = 0; ! 324: setsbits(chbits, ++j); ! 325: setfbits(chbits, font); ! 326: sps = width(' ' | chbits); ! 327: zapwcache(1); ! 328: } ! 329: ! 330: setps() ! 331: { ! 332: register int i, j; ! 333: ! 334: i = cbits(getch()); ! 335: if (isdigit(i)) { /* \sd or \sdd */ ! 336: i -= '0'; ! 337: if (i == 0) /* \s0 */ ! 338: j = apts1; ! 339: else if (i <= 3 && isdigit(j = cbits(ch=getch()))) { /* \sdd */ ! 340: j = 10 * i + j - '0'; ! 341: ch = 0; ! 342: } else /* \sd */ ! 343: j = i; ! 344: } else if (i == '(') { /* \s(dd */ ! 345: j = cbits(getch()) - '0'; ! 346: j = 10 * j + cbits(getch()) - '0'; ! 347: if (j == 0) /* \s(00 */ ! 348: j = apts1; ! 349: } else if (i == '+' || i == '-') { /* \s+, \s- */ ! 350: j = cbits(getch()); ! 351: if (isdigit(j)) { /* \s+d, \s-d */ ! 352: j -= '0'; ! 353: } else if (j == '(') { /* \s+(dd, \s-(dd */ ! 354: j = cbits(getch()) - '0'; ! 355: j = 10 * j + cbits(getch()) - '0'; ! 356: } ! 357: if (i == '-') ! 358: j = -j; ! 359: j += apts; ! 360: } ! 361: casps1(j); ! 362: } ! 363: ! 364: ! 365: tchar setht() /* set character height from \H'...' */ ! 366: { ! 367: int n; ! 368: tchar c; ! 369: ! 370: getch(); ! 371: n = inumb(&apts); ! 372: getch(); ! 373: if (n == 0 || nonumb) ! 374: n = apts; /* does this work? */ ! 375: c = CHARHT; ! 376: c |= ZBIT; ! 377: setsbits(c, n); ! 378: return(c); ! 379: } ! 380: ! 381: tchar setslant() /* set slant from \S'...' */ ! 382: { ! 383: int n; ! 384: tchar c; ! 385: ! 386: getch(); ! 387: n = 0; ! 388: n = inumb(&n); ! 389: getch(); ! 390: if (nonumb) ! 391: n = 0; ! 392: c = SLANT; ! 393: c |= ZBIT; ! 394: setsfbits(c, n+180); ! 395: return(c); ! 396: } ! 397: ! 398: ! 399: caseft() ! 400: { ! 401: skip(); ! 402: setfont(1); ! 403: } ! 404: ! 405: ! 406: setfont(a) ! 407: int a; ! 408: { ! 409: register i, j; ! 410: ! 411: if (a) ! 412: i = getrq(); ! 413: else ! 414: i = getsn(); ! 415: if (!i || i == 'P') { ! 416: j = font1; ! 417: goto s0; ! 418: } ! 419: if (i == 'S' || i == '0') ! 420: return; ! 421: if ((j = findft(i)) == -1) ! 422: if ((j = setfp(0, i, 0)) == -1) /* try to put it in position 0 */ ! 423: return; ! 424: s0: ! 425: font1 = font; ! 426: font = j; ! 427: mchbits(); ! 428: } ! 429: ! 430: ! 431: setwd() ! 432: { ! 433: register base, wid; ! 434: register tchar i; ! 435: int delim, emsz, k; ! 436: int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1; ! 437: ! 438: base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0; ! 439: if (ismot(i = getch())) ! 440: return; ! 441: delim = cbits(i); ! 442: savhp = numtab[HP].val; ! 443: numtab[HP].val = 0; ! 444: savapts = apts; ! 445: savapts1 = apts1; ! 446: savfont = font; ! 447: savfont1 = font1; ! 448: savpts = pts; ! 449: savpts1 = pts1; ! 450: setwdf++; ! 451: while (cbits(i = getch()) != delim && !nlflg) { ! 452: k = width(i); ! 453: wid += k; ! 454: numtab[HP].val += k; ! 455: if (!ismot(i)) { ! 456: emsz = POINT * xpts; ! 457: } else if (isvmot(i)) { ! 458: k = absmot(i); ! 459: if (isnmot(i)) ! 460: k = -k; ! 461: base -= k; ! 462: emsz = 0; ! 463: } else ! 464: continue; ! 465: if (base < numtab[SB].val) ! 466: numtab[SB].val = base; ! 467: if ((k = base + emsz) > numtab[ST].val) ! 468: numtab[ST].val = k; ! 469: } ! 470: setn1(wid, 0, (tchar) 0); ! 471: numtab[HP].val = savhp; ! 472: apts = savapts; ! 473: apts1 = savapts1; ! 474: font = savfont; ! 475: font1 = savfont1; ! 476: pts = savpts; ! 477: pts1 = savpts1; ! 478: mchbits(); ! 479: setwdf = 0; ! 480: } ! 481: ! 482: ! 483: tchar vmot() ! 484: { ! 485: dfact = lss; ! 486: vflag++; ! 487: return(mot()); ! 488: } ! 489: ! 490: ! 491: tchar hmot() ! 492: { ! 493: dfact = EM; ! 494: return(mot()); ! 495: } ! 496: ! 497: ! 498: tchar mot() ! 499: { ! 500: register int j, n; ! 501: register tchar i; ! 502: ! 503: j = HOR; ! 504: getch(); /*eat delim*/ ! 505: if (n = atoi()) { ! 506: if (vflag) ! 507: j = VERT; ! 508: i = makem(quant(n, j)); ! 509: } else ! 510: i = 0; ! 511: getch(); ! 512: vflag = 0; ! 513: dfact = 1; ! 514: return(i); ! 515: } ! 516: ! 517: ! 518: tchar sethl(k) ! 519: int k; ! 520: { ! 521: register j; ! 522: tchar i; ! 523: ! 524: j = EM / 2; ! 525: if (k == 'u') ! 526: j = -j; ! 527: else if (k == 'r') ! 528: j = -2 * j; ! 529: vflag++; ! 530: i = makem(j); ! 531: vflag = 0; ! 532: return(i); ! 533: } ! 534: ! 535: ! 536: tchar makem(i) ! 537: register int i; ! 538: { ! 539: register tchar j; ! 540: ! 541: if ((j = i) < 0) ! 542: j = -j; ! 543: j |= MOT; ! 544: if (i < 0) ! 545: j |= NMOT; ! 546: if (vflag) ! 547: j |= VMOT; ! 548: return(j); ! 549: } ! 550: ! 551: ! 552: tchar getlg(i) ! 553: tchar i; ! 554: { ! 555: tchar j, k; ! 556: register int lf; ! 557: ! 558: if ((lf = fontbase[fbits(i)]->ligfont) == 0) /* font lacks ligatures */ ! 559: return(i); ! 560: j = getch0(); ! 561: if (cbits(j) == 'i' && (lf & LFI)) ! 562: j = LIG_FI; ! 563: else if (cbits(j) == 'l' && (lf & LFL)) ! 564: j = LIG_FL; ! 565: else if (cbits(j) == 'f' && (lf & LFF)) { ! 566: if ((lf & (LFFI|LFFL)) && lg != 2) { ! 567: k = getch0(); ! 568: if (cbits(k)=='i' && (lf&LFFI)) ! 569: j = LIG_FFI; ! 570: else if (cbits(k)=='l' && (lf&LFFL)) ! 571: j = LIG_FFL; ! 572: else { ! 573: *pbp++ = k; ! 574: j = LIG_FF; ! 575: } ! 576: } else ! 577: j = LIG_FF; ! 578: } else { ! 579: *pbp++ = j; ! 580: j = i; ! 581: } ! 582: return(i & SFMASK | j); ! 583: } ! 584: ! 585: ! 586: caselg() ! 587: { ! 588: ! 589: lg = 1; ! 590: if (skip()) ! 591: return; ! 592: lg = atoi(); ! 593: } ! 594: ! 595: ! 596: casefp() ! 597: { ! 598: register int i, j; ! 599: register char *s; ! 600: ! 601: skip(); ! 602: if ((i = cbits(getch()) - '0') <= 0 || i > nfonts) ! 603: errprint("fp: bad font position %d", i); ! 604: else if (skip() || !(j = getrq())) ! 605: errprint("fp: no font name"); ! 606: else if (skip() || !getname()) ! 607: setfp(i, j, 0); ! 608: else /* 3rd argument = filename */ ! 609: setfp(i, j, nextf); ! 610: } ! 611: ! 612: setfp(pos, f, truename) /* mount font f at position pos[0...nfonts] */ ! 613: int pos, f; ! 614: char *truename; ! 615: { ! 616: register k; ! 617: int n; ! 618: char longname[NS], shortname[20]; ! 619: extern int nchtab; ! 620: ! 621: zapwcache(0); ! 622: if (truename) ! 623: strcpy(shortname, truename); ! 624: else { ! 625: shortname[0] = f & BYTEMASK; ! 626: shortname[1] = f >> BYTE; ! 627: shortname[2] = '\0'; ! 628: } ! 629: sprintf(longname, "%s/dev%s/%s.out", fontfile, devname, shortname); ! 630: if ((k = open(longname, 0)) < 0) { ! 631: errprint("Can't open %s", longname); ! 632: return(-1); ! 633: } ! 634: n = fontbase[pos]->nwfont & BYTEMASK; ! 635: read(k, (char *) fontbase[pos], 3*n + nchtab + 128 - 32 + sizeof(struct Font)); ! 636: kerntab[pos] = (char *) fontab[pos] + (fontbase[pos]->nwfont & BYTEMASK); ! 637: /* have to reset the fitab pointer because the width may be different */ ! 638: fitab[pos] = (char *) fontab[pos] + 3 * (fontbase[pos]->nwfont & BYTEMASK); ! 639: if ((fontbase[pos]->nwfont & BYTEMASK) > n) { ! 640: errprint("Font %s too big for position %d", shortname, pos); ! 641: return(-1); ! 642: } ! 643: fontbase[pos]->nwfont = n; /* so can load a larger one again later */ ! 644: close(k); ! 645: if (pos == smnt) { ! 646: smnt = 0; ! 647: sbold = 0; ! 648: } ! 649: if ((fontlab[pos] = f) == 'S') ! 650: smnt = pos; ! 651: bdtab[pos] = cstab[pos] = ccstab[pos] = 0; ! 652: /* if there is a directory, no place to store its name. */ ! 653: /* if position isn't zero, no place to store its value. */ ! 654: /* only time a FONTPOS is pushed back is if it's a */ ! 655: /* standard font on position 0 (i.e., mounted implicitly. */ ! 656: /* there's a bug here: if there are several input lines */ ! 657: /* that look like .ft XX in short successtion, the output */ ! 658: /* will all be in the last one because the "x font ..." */ ! 659: /* comes out too soon. pushing back FONTPOS doesn't work */ ! 660: /* with .ft commands because input is flushed after .xx cmds */ ! 661: ptfpcmd(pos, shortname); ! 662: if (pos == 0) ! 663: ch = (tchar) FONTPOS | (tchar) f << 16; ! 664: return(pos); ! 665: } ! 666: ! 667: ! 668: casecs() ! 669: { ! 670: register i, j; ! 671: ! 672: noscale++; ! 673: skip(); ! 674: if (!(i = getrq()) || (i = findft(i)) < 0) ! 675: goto rtn; ! 676: skip(); ! 677: cstab[i] = atoi(); ! 678: skip(); ! 679: j = atoi(); ! 680: if (nonumb) ! 681: ccstab[i] = 0; ! 682: else ! 683: ccstab[i] = findps(j); ! 684: rtn: ! 685: zapwcache(0); ! 686: noscale = 0; ! 687: } ! 688: ! 689: ! 690: casebd() ! 691: { ! 692: register i, j, k; ! 693: ! 694: zapwcache(0); ! 695: k = 0; ! 696: bd0: ! 697: if (skip() || !(i = getrq()) || (j = findft(i)) == -1) { ! 698: if (k) ! 699: goto bd1; ! 700: else ! 701: return; ! 702: } ! 703: if (j == smnt) { ! 704: k = smnt; ! 705: goto bd0; ! 706: } ! 707: if (k) { ! 708: sbold = j; ! 709: j = k; ! 710: } ! 711: bd1: ! 712: skip(); ! 713: noscale++; ! 714: bdtab[j] = atoi(); ! 715: noscale = 0; ! 716: } ! 717: ! 718: ! 719: casevs() ! 720: { ! 721: register i; ! 722: ! 723: skip(); ! 724: vflag++; ! 725: dfact = INCH; /* default scaling is points! */ ! 726: dfactd = 72; ! 727: res = VERT; ! 728: i = inumb(&lss); ! 729: if (nonumb) ! 730: i = lss1; ! 731: if (i < VERT) ! 732: i = VERT; ! 733: lss1 = lss; ! 734: lss = i; ! 735: } ! 736: ! 737: ! 738: casess() ! 739: { ! 740: register i; ! 741: ! 742: noscale++; ! 743: skip(); ! 744: if (i = atoi()) { ! 745: spacesz = i & 0177; ! 746: zapwcache(0); ! 747: sps = width(' ' | chbits); ! 748: } ! 749: noscale = 0; ! 750: } ! 751: ! 752: ! 753: tchar xlss() ! 754: { ! 755: /* stores \x'...' into ! 756: /* two successive tchars. ! 757: /* the first contains HX, the second the value, ! 758: /* encoded as a vertical motion. ! 759: /* decoding is done in n2.c by pchar(). ! 760: */ ! 761: int i; ! 762: ! 763: getch(); ! 764: dfact = lss; ! 765: i = quant(atoi(), VERT); ! 766: dfact = 1; ! 767: getch(); ! 768: if (i >= 0) ! 769: *pbp++ = MOT | VMOT | i; ! 770: else ! 771: *pbp++ = MOT | VMOT | NMOT | -i; ! 772: return(HX); ! 773: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.