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