151157Scael #ifndef lint
251157Scael static char sccsid[] = "@(#)t6.c 2.2 (CWI) 87/07/10";
351157Scael #endif lint
451157Scael /*
551157Scael * t6.c
651157Scael *
751157Scael * width functions, sizes and fonts
851157Scael */
951157Scael
1051157Scael #include "tdef.h"
1151157Scael #include "dev.h"
1251157Scael #include <sgtty.h>
1351157Scael #include <ctype.h>
1451157Scael #include "ext.h"
1551157Scael
1651157Scael /* fitab[f][c] is 0 if c is not on font f
1751157Scael /* if it's non-zero, c is in fontab[f] at position
1851157Scael /* fitab[f][c].
1951157Scael */
2051157Scael extern struct Font *fontbase[NFONT+1];
2151157Scael extern char *codetab[NFONT+1];
2251157Scael extern int nchtab;
2351157Scael
2451157Scael int fontlab[MAXFONTS+1];
2551157Scael short *pstab;
2651157Scael int cstab[MAXFONTS+1];
2751157Scael int ccstab[MAXFONTS+1];
2851157Scael int bdtab[MAXFONTS+1];
2951157Scael int sbold = 0;
3051157Scael
width(j)3151157Scael width(j)
3251157Scael register tchar j;
3351157Scael {
3451157Scael register i, k;
3551157Scael
3651157Scael if (j & (ZBIT|MOT)) {
3751157Scael if (iszbit(j))
3851157Scael return(0);
3951157Scael if (isvmot(j))
4051157Scael return(0);
4151157Scael k = absmot(j);
4251157Scael if (isnmot(j))
4351157Scael k = -k;
4451157Scael return(k);
4551157Scael }
4651157Scael i = cbits(j);
4751157Scael if (i < ' ') {
4851157Scael if (i == '\b')
4951157Scael return(-widthp);
5051157Scael if (i == PRESC)
5151157Scael i = eschar;
5251157Scael else if (iscontrol(i))
5351157Scael return(0);
5451157Scael }
5551157Scael if (i==ohc)
5651157Scael return(0);
5751157Scael i = trtab[i];
5851157Scael if (i < 32)
5951157Scael return(0);
6051157Scael if (sfbits(j) == oldbits) {
6151157Scael xfont = pfont;
6251157Scael xpts = ppts;
6351157Scael } else
6451157Scael xbits(j, 0);
6551157Scael if (widcache[i-32].fontpts == (xfont<<8) + xpts && !setwdf)
6651157Scael k = widcache[i-32].width;
6751157Scael else {
6851157Scael k = getcw(i-32);
6951157Scael if (bd)
7051157Scael k += (bd - 1) * HOR;
7151157Scael if (cs)
7251157Scael k = cs;
7351157Scael }
7451157Scael widthp = k;
7551157Scael return(k);
7651157Scael }
7751157Scael
7851157Scael /*
7951157Scael * clear width cache-- s means just space
8051157Scael */
zapwcache(s)8151157Scael zapwcache(s)
8251157Scael {
8351157Scael register i;
8451157Scael
8551157Scael if (s) {
8651157Scael widcache[0].fontpts = 0;
8751157Scael return;
8851157Scael }
8951157Scael for (i=0; i<NWIDCACHE; i++)
9051157Scael widcache[i].fontpts = 0;
9151157Scael }
9251157Scael
getcw(i)9351157Scael getcw(i)
9451157Scael register int i;
9551157Scael {
9651157Scael register int k;
9751157Scael register char *p;
9851157Scael register int x, j;
9951157Scael int nocache = 0;
10051157Scael int savxfont = 0, savsbold = 0, savulfont = 0;
10151157Scael
10251157Scael /*
10351157Scael * Here comes first part of bug fix
10451157Scael */
10551157Scael
10651157Scael if( xfont > nfonts) { /* font is not mounted */
10751157Scael savxfont = xfont;
10851157Scael if( xfont == sbold) {
10951157Scael savsbold = sbold;
11051157Scael sbold = 0;
11151157Scael }
11251157Scael if( xfont == ulfont) {
11351157Scael savulfont = ulfont;
11451157Scael ulfont = 0;
11551157Scael }
11651157Scael xfont = 0;
11751157Scael setfp(0, fontlab[savxfont], 0);
11851157Scael bdtab[0] = bdtab[savxfont]; /* Save */
11951157Scael cstab[0] = cstab[savxfont]; /* as */
12051157Scael ccstab[0] = ccstab[savxfont]; /* well */
12151157Scael }
12251157Scael /* End */
12351157Scael
12451157Scael
12551157Scael bd = 0;
12651157Scael if (i >= nchtab + 128-32) {
12751157Scael j = abscw(i + 32 - (nchtab+128));
12851157Scael goto g0;
12951157Scael }
13051157Scael if (i == 0) { /* a blank */
13151157Scael k = (fontab[xfont][0] * spacesz + 6) / 12;
13251157Scael /* this nonsense because .ss cmd uses 1/36 em as its units */
13351157Scael /* and default is 12 */
13451157Scael goto g1;
13551157Scael }
13651157Scael if ((j = fitab[xfont][i] & BYTEMASK) == 0) { /* it's not on current font */
13751157Scael /* search through search list of xfont
13851157Scael /* to see what font it ought to be on.
13951157Scael /* searches S, then remaining fonts in wraparound order.
14051157Scael */
14151157Scael nocache = 1;
14251157Scael if (smnt) {
14351157Scael int ii, jj;
14451157Scael for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
14551157Scael j = fitab[ii][i] & BYTEMASK;
14651157Scael if (j != 0) {
14751157Scael p = fontab[ii];
14851157Scael k = *(p + j);
14951157Scael if (xfont == sbold)
15051157Scael bd = bdtab[ii];
15151157Scael if (setwdf)
15251157Scael numtab[CT].val |= kerntab[ii][j];
15351157Scael goto g1;
15451157Scael }
15551157Scael }
15651157Scael }
15751157Scael k = fontab[xfont][0]; /* leave a space-size space */
15851157Scael goto g1;
15951157Scael }
16051157Scael g0:
16151157Scael p = fontab[xfont];
16251157Scael if (setwdf)
16351157Scael numtab[CT].val |= kerntab[xfont][j];
16451157Scael k = *(p + j);
16551157Scael g1:
16651157Scael if (!bd)
16751157Scael bd = bdtab[xfont];
16851157Scael if (cs = cstab[xfont]) {
16951157Scael nocache = 1;
17051157Scael if (ccs = ccstab[xfont])
17151157Scael x = ccs;
17251157Scael else
17351157Scael x = xpts;
17451157Scael cs = (cs * EMPTS(x)) / 36;
17551157Scael }
17651157Scael k = ((k&BYTEMASK) * xpts + (Unitwidth / 2)) / Unitwidth;
17751157Scael /*
17851157Scael * undo the fontswap
17951157Scael */
18051157Scael if(savxfont) {
18151157Scael xfont = savxfont;
18251157Scael if(savsbold)
18351157Scael sbold = savsbold;
18451157Scael if(savulfont)
18551157Scael ulfont = savulfont;
18651157Scael /*
18751157Scael * H'm, I guess we should not put
18851157Scael * this width in the cache
18951157Scael */
19051157Scael nocache = 1;
19151157Scael }
19251157Scael if (nocache|bd)
19351157Scael widcache[i].fontpts = 0;
19451157Scael else {
19551157Scael widcache[i].fontpts = (xfont<<8) + xpts;
19651157Scael widcache[i].width = k;
19751157Scael }
19851157Scael return(k);
19951157Scael /* Unitwidth is Units/Point, where
20051157Scael /* Units is the fundamental digitization
20151157Scael /* of the character set widths, and
20251157Scael /* Point is the number of goobies in a point
20351157Scael /* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
20451157Scael /* In effect, it's the size at which the widths
20551157Scael /* translate directly into units.
20651157Scael */
20751157Scael }
20851157Scael
abscw(n)20951157Scael abscw(n) /* return index of abs char n in fontab[], etc. */
21051157Scael { register int i, ncf;
21151157Scael
21251157Scael ncf = fontbase[xfont]->nwfont & BYTEMASK;
21351157Scael for (i = 0; i < ncf; i++)
21451157Scael if (codetab[xfont][i] == n)
21551157Scael return i;
21651157Scael return 0;
21751157Scael }
21851157Scael
xbits(i,bitf)21951157Scael xbits(i, bitf)
22051157Scael register tchar i;
22151157Scael {
22251157Scael register k;
22351157Scael
22451157Scael xfont = fbits(i);
22551157Scael k = sbits(i);
22651157Scael if (k) {
22751157Scael xpts = pstab[--k];
22851157Scael oldbits = sfbits(i);
22951157Scael pfont = xfont;
23051157Scael ppts = xpts;
23151157Scael return;
23251157Scael }
23351157Scael switch (bitf) {
23451157Scael case 0:
23551157Scael xfont = font;
23651157Scael xpts = pts;
23751157Scael break;
23851157Scael case 1:
23951157Scael xfont = pfont;
24051157Scael xpts = ppts;
24151157Scael break;
24251157Scael case 2:
24351157Scael xfont = mfont;
24451157Scael xpts = mpts;
24551157Scael }
24651157Scael }
24751157Scael
24851157Scael
setch()24951157Scael tchar setch()
25051157Scael {
25151157Scael register j;
25251157Scael char temp[10];
25351157Scael register char *s;
25451157Scael extern char *chname;
25551157Scael extern short *chtab;
25651157Scael extern int nchtab;
25751157Scael
25851157Scael s = temp;
25951157Scael if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
26051157Scael return(0);
26151157Scael *s = '\0';
26251157Scael for (j = 0; j < nchtab; j++)
26351157Scael if (strcmp(&chname[chtab[j]], temp) == 0)
26451157Scael return(j + 128 | chbits);
26551157Scael return(0);
26651157Scael }
26751157Scael
setabs()26851157Scael tchar setabs() /* set absolute char from \C'...' */
26951157Scael {
27051157Scael int i, n, nf;
27151157Scael extern int nchtab;
27251157Scael
27351157Scael getch();
27451157Scael n = 0;
27551157Scael n = inumb(&n);
27651157Scael getch();
27751157Scael if (nonumb)
27851157Scael return 0;
27951157Scael return n + nchtab + 128;
28051157Scael }
28151157Scael /*
28251157Scael * I (jaap) expand fontlab to the maximum of fonts troff can
28351157Scael * handle. The maximum number i, due to the two chars
28451157Scael * fontname limit, is 99.
28551157Scael * If we don't use the (named) font in one of the
28651157Scael * standard position, we install the name in the next
28751157Scael * free slot. Whenever we need info about the font, we
28851157Scael * read in the data at position zero, and secretly use
28951157Scael * the data (actually only necessary for the width
29051157Scael * and ligature info). The ptfont() (t10.c) routine will tell
29151157Scael * the device filter to put the font always at position
29251157Scael * zero if xfont > physfonts, so no need to change these filters.
29351157Scael * Yes, this is a bit kludgy.
29451157Scael *
29551157Scael * This gives the new specs of findft:
29651157Scael *
29751157Scael * find the font name i, where i also can be a number.
29851157Scael *
29951157Scael * Installs the font(name) i when not present
30051157Scael *
30151157Scael * returns -1 on error
30251157Scael */
30351157Scael
findft(i)30451157Scael findft(i)
30551157Scael register int i;
30651157Scael {
30751157Scael register k;
30851157Scael register char *p;
30951157Scael extern char * unpair();
31051157Scael
31151157Scael p = unpair(i);
31251157Scael
31351157Scael /* first look for numbers */
31451157Scael if( isdigit(p[0]) && (p[1] == 0 || isdigit(p[1]))) {
31551157Scael k = p[0] - '0';
31651157Scael if( p[1] > 0 && isdigit(p[1]))
31751157Scael k = 10 * k + ( p[1] - '0');
31851157Scael
31951157Scael /*
32051157Scael fprintf(ptid, "x xxx it's a number: %d\n", k);
32151157Scael */
32251157Scael if( k > 0 && k <= nfonts && fontbase[k]->specfont == 0 ) {
32351157Scael /*
32451157Scael fprintf(ptid, "x xxx it's a mounted font\n");
32551157Scael */
32651157Scael return(k); /* mounted font */
32751157Scael }
32851157Scael if( fontlab[k] && k <= MAXFONTS) { /* translate */
32951157Scael /*
33051157Scael fprintf(ptid, "x xxx font exists\n");
33151157Scael */
33251157Scael return(k); /*number to a name */
33351157Scael }
33451157Scael else {
33551157Scael fprintf(stderr, "troff: no font at position %d\n", k);
33651157Scael return(-1); /* wild number */
33751157Scael }
33851157Scael }
33951157Scael
34051157Scael /*
34151157Scael * Now we look for font names
34251157Scael */
34351157Scael for (k = 1; fontlab[k] != i; k++) {
34451157Scael if (k > MAXFONTS +1) /* the +1 is for the ``font cache'' */
34551157Scael return(-1); /* running out of fontlab space */
34651157Scael if ( !fontlab[k] ) { /* passed all existing names */
34751157Scael if (k <= NFONT) {
34851157Scael if(setfp(k, i, 0) < 0)
34951157Scael return(-1);
35051157Scael nfonts = k;
35151157Scael } else
35251157Scael if(setfp(0, i, 0) < 0)
35351157Scael return(-1);
35451157Scael /*
35551157Scael fprintf(ptid, "x xxx installed %s on %d\n", name ,k);
35651157Scael */
35751157Scael /* now install the name */
35851157Scael fontlab[k] = i;
35951157Scael /*
36051157Scael * and remember accociated with
36151157Scael * this font, ligature info etc.
36251157Scael */
36351157Scael return(k);
36451157Scael }
36551157Scael }
36651157Scael return(k); /* was one of the existing names */
36751157Scael }
36851157Scael
36951157Scael
caseps()37051157Scael caseps()
37151157Scael {
37251157Scael register i;
37351157Scael
37451157Scael if (skip())
37551157Scael i = apts1;
37651157Scael else {
37751157Scael noscale++;
37851157Scael i = inumb(&apts); /* this is a disaster for fractional point sizes */
37951157Scael noscale = 0;
38051157Scael if (nonumb)
38151157Scael return;
38251157Scael }
38351157Scael casps1(i);
38451157Scael }
38551157Scael
38651157Scael
casps1(i)38751157Scael casps1(i)
38851157Scael register int i;
38951157Scael {
39051157Scael
39151157Scael /*
39251157Scael * in olden times, it used to ignore changes to 0 or negative.
39351157Scael * this is meant to allow the requested size to be anything,
39451157Scael * in particular so eqn can generate lots of \s-3's and still
39551157Scael * get back by matching \s+3's.
39651157Scael
39751157Scael if (i <= 0)
39851157Scael return;
39951157Scael */
40051157Scael apts1 = apts;
40151157Scael apts = i;
40251157Scael pts1 = pts;
40351157Scael pts = findps(i);
40451157Scael mchbits();
40551157Scael }
40651157Scael
40751157Scael
findps(i)40851157Scael findps(i)
40951157Scael register int i;
41051157Scael {
41151157Scael register j, k;
41251157Scael
41351157Scael for (j=k=0 ; pstab[j] != 0 ; j++)
41451157Scael if (abs(pstab[j]-i) < abs(pstab[k]-i))
41551157Scael k = j;
41651157Scael
41751157Scael return(pstab[k]);
41851157Scael }
41951157Scael
42051157Scael
mchbits()42151157Scael mchbits()
42251157Scael {
42351157Scael register i, j, k;
42451157Scael
42551157Scael i = pts;
42651157Scael for (j = 0; i > (k = pstab[j]); j++)
42751157Scael if (!k) {
42851157Scael k = pstab[--j];
42951157Scael break;
43051157Scael }
43151157Scael chbits = 0;
43251157Scael setsbits(chbits, ++j);
43351157Scael setfbits(chbits, font);
43451157Scael sps = width(' ' | chbits);
43551157Scael zapwcache(1);
43651157Scael }
43751157Scael
setps()43851157Scael setps()
43951157Scael {
44051157Scael register int i, j;
44151157Scael
44251157Scael i = cbits(getch());
44351157Scael if (isdigit(i)) { /* \sd or \sdd */
44451157Scael i -= '0';
44551157Scael if (i == 0) /* \s0 */
44651157Scael j = apts1;
44751157Scael else if (i <= 3 && isdigit(j = cbits(ch=getch()))) { /* \sdd */
44851157Scael j = 10 * i + j - '0';
44951157Scael ch = 0;
45051157Scael } else /* \sd */
45151157Scael j = i;
45251157Scael } else if (i == '(') { /* \s(dd */
45351157Scael j = cbits(getch()) - '0';
45451157Scael j = 10 * j + cbits(getch()) - '0';
45551157Scael if (j == 0) /* \s(00 */
45651157Scael j = apts1;
45751157Scael } else if (i == '+' || i == '-') { /* \s+, \s- */
45851157Scael j = cbits(getch());
45951157Scael if (isdigit(j)) { /* \s+d, \s-d */
46051157Scael j -= '0';
46151157Scael } else if (j == '(') { /* \s+(dd, \s-(dd */
46251157Scael j = cbits(getch()) - '0';
46351157Scael j = 10 * j + cbits(getch()) - '0';
46451157Scael }
46551157Scael if (i == '-')
46651157Scael j = -j;
46751157Scael j += apts;
46851157Scael }
46951157Scael casps1(j);
47051157Scael }
47151157Scael
47251157Scael
setht()47351157Scael tchar setht() /* set character height from \H'...' */
47451157Scael {
47551157Scael int n;
47651157Scael tchar c;
47751157Scael
47851157Scael getch();
47951157Scael n = inumb(&apts);
48051157Scael getch();
48151157Scael if (n == 0 || nonumb)
48251157Scael n = apts; /* does this work? */
48351157Scael c = CHARHT;
48451157Scael c |= ZBIT;
48551157Scael setsbits(c, n);
48651157Scael return(c);
48751157Scael }
48851157Scael
setslant()48951157Scael tchar setslant() /* set slant from \S'...' */
49051157Scael {
49151157Scael int n;
49251157Scael tchar c;
49351157Scael
49451157Scael getch();
49551157Scael n = 0;
49651157Scael n = inumb(&n);
49751157Scael getch();
49851157Scael if (nonumb)
49951157Scael n = 0;
50051157Scael c = SLANT;
50151157Scael c |= ZBIT;
50251157Scael setsfbits(c, n+180);
50351157Scael return(c);
50451157Scael }
50551157Scael
50651157Scael
caseft()50751157Scael caseft()
50851157Scael {
50951157Scael skip();
51051157Scael setfont(1);
51151157Scael }
51251157Scael
51351157Scael
setfont(a)51451157Scael setfont(a)
51551157Scael int a;
51651157Scael {
51751157Scael register i, j;
51851157Scael
51951157Scael if (a)
52051157Scael i = getrq();
52151157Scael else
52251157Scael i = getsn();
52351157Scael if (!i || i == 'P') {
52451157Scael j = font1;
52551157Scael goto s0;
52651157Scael }
52751157Scael if (i == 'S' || i == '0')
52851157Scael return;
52951157Scael if ((j = findft(i)) == -1)
53051157Scael #ifdef notdef
53151157Scael /* findft does the setfp if possible */
53251157Scael if ((j = setfp(0, i, 0)) == -1) /* try to put it in position 0 */
53351157Scael #endif
53451157Scael return;
53551157Scael s0:
53651157Scael font1 = font;
53751157Scael font = j;
53851157Scael mchbits();
53951157Scael }
54051157Scael
54151157Scael
setwd()54251157Scael setwd()
54351157Scael {
54451157Scael register base, wid;
54551157Scael register tchar i;
54651157Scael int delim, emsz, k;
54751157Scael int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
54851157Scael
54951157Scael base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0;
55051157Scael if (ismot(i = getch()))
55151157Scael return;
55251157Scael delim = cbits(i);
55351157Scael savhp = numtab[HP].val;
55451157Scael numtab[HP].val = 0;
55551157Scael savapts = apts;
55651157Scael savapts1 = apts1;
55751157Scael savfont = font;
55851157Scael savfont1 = font1;
55951157Scael savpts = pts;
56051157Scael savpts1 = pts1;
56151157Scael setwdf++;
56251157Scael while (cbits(i = getch()) != delim && !nlflg) {
56351157Scael k = width(i);
56451157Scael wid += k;
56551157Scael numtab[HP].val += k;
56651157Scael if (!ismot(i)) {
56751157Scael emsz = POINT * xpts;
56851157Scael } else if (isvmot(i)) {
56951157Scael k = absmot(i);
57051157Scael if (isnmot(i))
57151157Scael k = -k;
57251157Scael base -= k;
57351157Scael emsz = 0;
57451157Scael } else
57551157Scael continue;
57651157Scael if (base < numtab[SB].val)
57751157Scael numtab[SB].val = base;
57851157Scael if ((k = base + emsz) > numtab[ST].val)
57951157Scael numtab[ST].val = k;
58051157Scael }
58151157Scael setn1(wid, 0, (tchar) 0);
58251157Scael numtab[HP].val = savhp;
58351157Scael apts = savapts;
58451157Scael apts1 = savapts1;
58551157Scael font = savfont;
58651157Scael font1 = savfont1;
58751157Scael pts = savpts;
58851157Scael pts1 = savpts1;
58951157Scael mchbits();
59051157Scael setwdf = 0;
59151157Scael }
59251157Scael
59351157Scael
vmot()59451157Scael tchar vmot()
59551157Scael {
59651157Scael dfact = lss;
59751157Scael vflag++;
59851157Scael return(mot());
59951157Scael }
60051157Scael
60151157Scael
hmot()60251157Scael tchar hmot()
60351157Scael {
60451157Scael dfact = EM;
60551157Scael return(mot());
60651157Scael }
60751157Scael
60851157Scael
mot()60951157Scael tchar mot()
61051157Scael {
61151157Scael register int j, n;
61251157Scael register tchar i;
61351157Scael
61451157Scael j = HOR;
61551157Scael getch(); /*eat delim*/
616*54111Scael if (n = (int)atoi0()) {
61751157Scael if (vflag)
61851157Scael j = VERT;
61951157Scael i = makem(quant(n, j));
62051157Scael } else
62151157Scael i = 0;
62251157Scael getch();
62351157Scael vflag = 0;
62451157Scael dfact = 1;
62551157Scael return(i);
62651157Scael }
62751157Scael
62851157Scael
sethl(k)62951157Scael tchar sethl(k)
63051157Scael int k;
63151157Scael {
63251157Scael register j;
63351157Scael tchar i;
63451157Scael
63551157Scael j = EM / 2;
63651157Scael if (k == 'u')
63751157Scael j = -j;
63851157Scael else if (k == 'r')
63951157Scael j = -2 * j;
64051157Scael vflag++;
64151157Scael i = makem(j);
64251157Scael vflag = 0;
64351157Scael return(i);
64451157Scael }
64551157Scael
64651157Scael
makem(i)64751157Scael tchar makem(i)
64851157Scael register int i;
64951157Scael {
65051157Scael register tchar j;
65151157Scael
65251157Scael if ((j = i) < 0)
65351157Scael j = -j;
65451157Scael j |= MOT;
65551157Scael if (i < 0)
65651157Scael j |= NMOT;
65751157Scael if (vflag)
65851157Scael j |= VMOT;
65951157Scael return(j);
66051157Scael }
66151157Scael
66251157Scael
getlg(i)66351157Scael tchar getlg(i)
66451157Scael tchar i;
66551157Scael {
66651157Scael tchar j, k;
66751157Scael register int lf;
66851157Scael
66951157Scael /* remember to map the font */
67051157Scael if ((lf = fontbase[fbits(i) > nfonts ? 0 : fbits(i)]->ligfont) == 0) {
67151157Scael /* font lacks ligatures */
67251157Scael return(i);
67351157Scael }
67451157Scael j = getch0();
67551157Scael if (cbits(j) == 'i' && (lf & LFI))
67651157Scael j = LIG_FI;
67751157Scael else if (cbits(j) == 'l' && (lf & LFL))
67851157Scael j = LIG_FL;
67951157Scael else if (cbits(j) == 'f' && (lf & LFF)) {
68051157Scael if ((lf & (LFFI|LFFL)) && lg != 2) {
68151157Scael k = getch0();
68251157Scael if (cbits(k)=='i' && (lf&LFFI))
68351157Scael j = LIG_FFI;
68451157Scael else if (cbits(k)=='l' && (lf&LFFL))
68551157Scael j = LIG_FFL;
68651157Scael else {
68751157Scael *pbp++ = k;
68851157Scael j = LIG_FF;
68951157Scael }
69051157Scael } else
69151157Scael j = LIG_FF;
69251157Scael } else {
69351157Scael *pbp++ = j;
69451157Scael j = i;
69551157Scael }
69651157Scael return(i & SFMASK | j);
69751157Scael }
69851157Scael
69951157Scael
caselg()70051157Scael caselg()
70151157Scael {
70251157Scael
70351157Scael lg = 1;
70451157Scael if (skip())
70551157Scael return;
706*54111Scael lg = (int)atoi0();
70751157Scael }
70851157Scael
70951157Scael
casefp()71051157Scael casefp()
71151157Scael {
71251157Scael register int i, j;
71351157Scael register char *s;
71451157Scael
71551157Scael skip();
71651157Scael /* allow .fp for fonts >nfonts, <NFONTS? */
71751157Scael if ((i = cbits(getch()) - '0') <= 0 || i > nfonts)
71851157Scael errprint("fp: bad font position %d", i);
71951157Scael else if (skip() || !(j = getrq()))
72051157Scael errprint("fp: no font name");
72151157Scael else if (skip() || !getname())
72251157Scael setfp(i, j, 0);
72351157Scael else /* 3rd argument = filename */
72451157Scael setfp(i, j, nextf);
72551157Scael }
72651157Scael
setfp(pos,f,truename)72751157Scael setfp(pos, f, truename) /* mount font f at position pos[0...NFONTS] */
72851157Scael register pos;
72951157Scael int f;
73051157Scael char *truename;
73151157Scael {
73251157Scael register k;
73351157Scael register struct Font *ft;
73451157Scael int n;
73551157Scael char longname[NS], shortname[20];
73651157Scael extern int nchtab;
73751157Scael extern struct dev dev;
73851157Scael
73951157Scael if (fontlab[pos] == f) /* if f already mounted at pos, */
74051157Scael return(pos); /* don't remount it */
74151157Scael zapwcache(0);
74251157Scael if (truename)
74351157Scael strcpy(shortname, truename);
74451157Scael else {
74551157Scael shortname[0] = f & BYTEMASK;
74651157Scael shortname[1] = f >> BYTE;
74751157Scael shortname[2] = '\0';
74851157Scael }
74951157Scael sprintf(longname, "%s/dev%s/%s.out", fontfile, devname, shortname);
75051157Scael if ((k = open(longname, 0)) < 0) {
75151157Scael errprint("Can't open %s", longname);
75251157Scael return(-1);
75351157Scael }
75451157Scael if ((ft = fontbase[pos]) == 0) {
75551157Scael ft = fontbase[pos] = (struct Font *) malloc(EXTRAFONT);
75651157Scael ft->nwfont = MAXCHARS;
75751157Scael fontab[pos] = (char *)(ft + 1);
75851157Scael }
75951157Scael n = ft->nwfont;
76051157Scael read(k, (char *) ft, 3*n + nchtab + 128 - 32 + sizeof(struct Font));
76151157Scael close(k);
76251157Scael
76351157Scael k = ft->nwfont;
76451157Scael kerntab[pos] = (char *) fontab[pos] + k;
76551157Scael codetab[pos] = (char *) fontab[pos] + 2 * k;
76651157Scael /* have to reset the fitab pointer because the width may be different */
76751157Scael fitab[pos] = (char *) fontab[pos] + 3 * k;
76851157Scael ft->nwfont = n; /* so can load a larger one again later */
76951157Scael if (k > n) {
77051157Scael errprint("Font %s too big for position %d", shortname, pos);
77151157Scael return(-1);
77251157Scael }
77351157Scael if (pos == smnt) {
77451157Scael smnt = 0;
77551157Scael sbold = 0;
77651157Scael }
77751157Scael if ((fontlab[pos] = f) == 'S')
77851157Scael smnt = pos;
77951157Scael bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
78051157Scael /* if there is a directory, no place to store its name. */
78151157Scael /* if position isn't zero, no place to store its value. */
78251157Scael /* only time a FONTPOS is pushed back is if it's a */
78351157Scael /* standard font on position 0 (i.e., mounted implicitly. */
78451157Scael /* there's a bug here: if there are several input lines */
78551157Scael /* that look like .ft XX in short successtion, the output */
78651157Scael /* will all be in the last one because the "x font ..." */
78751157Scael /* comes out too soon. pushing back FONTPOS doesn't work */
78851157Scael /* with .ft commands because input is flushed after .xx cmds */
78951157Scael
79051157Scael /*
79151157Scael * Trying to fix this FONTPOS problem: See findft()
79251157Scael */
79351157Scael if ( pos > 0 && pos <= physfonts)
79451157Scael ptfpcmd(pos, shortname);
79551157Scael return(pos);
79651157Scael }
79751157Scael
79851157Scael
casecs()79951157Scael casecs()
80051157Scael {
80151157Scael register i, j;
80251157Scael
80351157Scael noscale++;
80451157Scael skip();
80551157Scael if (!(i = getrq()) || (i = findft(i)) < 0)
80651157Scael goto rtn;
80751157Scael skip();
808*54111Scael cstab[i] = (int)atoi0();
80951157Scael skip();
810*54111Scael j = (int)atoi0();
81151157Scael if (nonumb)
81251157Scael ccstab[i] = 0;
81351157Scael else
81451157Scael ccstab[i] = findps(j);
81551157Scael rtn:
81651157Scael zapwcache(0);
81751157Scael noscale = 0;
81851157Scael }
81951157Scael
82051157Scael
casebd()82151157Scael casebd()
82251157Scael {
82351157Scael register i, j, k;
82451157Scael
82551157Scael zapwcache(0);
82651157Scael k = 0;
82751157Scael bd0:
82851157Scael if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
82951157Scael if (k)
83051157Scael goto bd1;
83151157Scael else
83251157Scael return;
83351157Scael }
83451157Scael if (j == smnt) {
83551157Scael k = smnt;
83651157Scael goto bd0;
83751157Scael }
83851157Scael if (k) {
83951157Scael sbold = j;
84051157Scael j = k;
84151157Scael }
84251157Scael bd1:
84351157Scael skip();
84451157Scael noscale++;
845*54111Scael bdtab[j] = (int)atoi0();
84651157Scael noscale = 0;
84751157Scael }
84851157Scael
84951157Scael
casevs()85051157Scael casevs()
85151157Scael {
85251157Scael register i;
85351157Scael
85451157Scael skip();
85551157Scael vflag++;
85651157Scael dfact = INCH; /* default scaling is points! */
85751157Scael dfactd = 72;
85851157Scael res = VERT;
85951157Scael i = inumb(&lss);
86051157Scael if (nonumb)
86151157Scael i = lss1;
86251157Scael /* if(i < VERT)i = VERT; */
86351157Scael if (i < VERT)
86451157Scael i = 0;
86551157Scael lss1 = lss;
86651157Scael lss = i;
86751157Scael }
86851157Scael
86951157Scael
casess()87051157Scael casess()
87151157Scael {
87251157Scael register i;
87351157Scael
87451157Scael noscale++;
87551157Scael skip();
876*54111Scael if (i = (int)atoi0()) {
87751157Scael spacesz = i & 0177;
87851157Scael zapwcache(0);
87951157Scael sps = width(' ' | chbits);
88051157Scael }
88151157Scael noscale = 0;
88251157Scael }
88351157Scael
88451157Scael
xlss()88551157Scael tchar xlss()
88651157Scael {
88751157Scael /* stores \x'...' into
88851157Scael /* two successive tchars.
88951157Scael /* the first contains HX, the second the value,
89051157Scael /* encoded as a vertical motion.
89151157Scael /* decoding is done in n2.c by pchar().
89251157Scael */
89351157Scael int i;
89451157Scael
89551157Scael getch();
89651157Scael dfact = lss;
897*54111Scael i = quant((int)atoi0(), VERT);
89851157Scael dfact = 1;
89951157Scael getch();
90051157Scael if (i >= 0)
90151157Scael *pbp++ = MOT | VMOT | i;
90251157Scael else
90351157Scael *pbp++ = MOT | VMOT | NMOT | -i;
90451157Scael return(HX);
90551157Scael }
90651157Scael
90751157Scael char *
unpair(i)90851157Scael unpair(i)
90951157Scael register int i;
91051157Scael { static char name[3];
91151157Scael
91251157Scael name[0] = i & BYTEMASK;
91351157Scael name[1] = i >> BYTE;
91451157Scael name[2] = 0;
91551157Scael return (name);
91651157Scael }
917