|
|
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.