123891Sjaap #ifndef lint
2*31823Sjaap static char sccsid[] = "@(#)t6.c	2.2 (CWI) 87/07/10";
323891Sjaap #endif lint
423912Sjaap /*
523912Sjaap  * t6.c
623912Sjaap  *
723912Sjaap  * width functions, sizes and fonts
823912Sjaap  */
923891Sjaap 
1023891Sjaap #include "tdef.h"
1123891Sjaap #include "dev.h"
1223912Sjaap #include <sgtty.h>
1323891Sjaap #include <ctype.h>
1423912Sjaap #include "ext.h"
1523891Sjaap 
1623891Sjaap /* fitab[f][c] is 0 if c is not on font f
1723891Sjaap 	/* if it's non-zero, c is in fontab[f] at position
1823891Sjaap 	/* fitab[f][c].
1923891Sjaap 	*/
2023912Sjaap extern	struct Font *fontbase[NFONT+1];
2123912Sjaap extern	char *codetab[NFONT+1];
2223912Sjaap extern int nchtab;
2323912Sjaap 
2423912Sjaap int	fontlab[MAXFONTS+1];
2523891Sjaap short	*pstab;
2623912Sjaap int	cstab[MAXFONTS+1];
2723912Sjaap int	ccstab[MAXFONTS+1];
2823891Sjaap int	bdtab[MAXFONTS+1];
2923891Sjaap int	sbold = 0;
3023891Sjaap 
width(j)3123891Sjaap width(j)
3223912Sjaap register tchar j;
3323891Sjaap {
3423891Sjaap 	register i, k;
3523891Sjaap 
3623912Sjaap 	if (j & (ZBIT|MOT)) {
3723912Sjaap 		if (iszbit(j))
3823912Sjaap 			return(0);
3923891Sjaap 		if (isvmot(j))
4023912Sjaap 			return(0);
4123891Sjaap 		k = absmot(j);
4223891Sjaap 		if (isnmot(j))
4323891Sjaap 			k = -k;
4423912Sjaap 		return(k);
4523891Sjaap 	}
4623912Sjaap 	i = cbits(j);
4723912Sjaap 	if (i < ' ') {
4823912Sjaap 		if (i == '\b')
4923912Sjaap 			return(-widthp);
5023912Sjaap 		if (i == PRESC)
5123912Sjaap 			i = eschar;
5223912Sjaap 		else if (iscontrol(i))
5323912Sjaap 			return(0);
5423891Sjaap 	}
5523912Sjaap 	if (i==ohc)
5623912Sjaap 		return(0);
5723912Sjaap 	i = trtab[i];
5823912Sjaap 	if (i < 32)
5923912Sjaap 		return(0);
6023891Sjaap 	if (sfbits(j) == oldbits) {
6123891Sjaap 		xfont = pfont;
6223891Sjaap 		xpts = ppts;
6323891Sjaap 	} else
6423912Sjaap 		xbits(j, 0);
6523912Sjaap 	if (widcache[i-32].fontpts == (xfont<<8) + xpts && !setwdf)
6623912Sjaap 		k = widcache[i-32].width;
6723912Sjaap 	else {
6823912Sjaap 		k = getcw(i-32);
6923912Sjaap 		if (bd)
7023912Sjaap 			k += (bd - 1) * HOR;
7123912Sjaap 		if (cs)
7223912Sjaap 			k = cs;
7323912Sjaap 	}
7423891Sjaap 	widthp = k;
7523891Sjaap 	return(k);
7623891Sjaap }
7723891Sjaap 
7823912Sjaap /*
7923912Sjaap  * clear width cache-- s means just space
8023912Sjaap  */
zapwcache(s)8123912Sjaap zapwcache(s)
8223912Sjaap {
8323912Sjaap 	register i;
8423891Sjaap 
8523912Sjaap 	if (s) {
8623912Sjaap 		widcache[0].fontpts = 0;
8723912Sjaap 		return;
8823912Sjaap 	}
8923912Sjaap 	for (i=0; i<NWIDCACHE; i++)
9023912Sjaap 		widcache[i].fontpts = 0;
9123912Sjaap }
9223912Sjaap 
getcw(i)9323891Sjaap getcw(i)
9423891Sjaap register int	i;
9523891Sjaap {
9623891Sjaap 	register int	k;
9723891Sjaap 	register char	*p;
9823912Sjaap 	register int	x, j;
9923912Sjaap 	int nocache = 0;
10023891Sjaap 	int	savxfont = 0, savsbold = 0, savulfont = 0;
10123891Sjaap 
10223891Sjaap 	/*
10323912Sjaap 	 * Here comes first part of bug fix
10423891Sjaap 	 */
10523891Sjaap 
10623912Sjaap 	if( xfont > nfonts) {		/* font is not mounted */
10723891Sjaap 		savxfont = xfont;
10823891Sjaap 		if( xfont == sbold) {
10923891Sjaap 			savsbold = sbold;
11023891Sjaap 			sbold = 0;
11123891Sjaap 		}
11223891Sjaap 		if( xfont == ulfont) {
11323891Sjaap 			savulfont = ulfont;
11423891Sjaap 			ulfont = 0;
11523891Sjaap 		}
11623891Sjaap 		xfont = 0;
11723912Sjaap 		setfp(0, fontlab[savxfont], 0);
11823912Sjaap 		bdtab[0] = bdtab[savxfont];	/* Save */
11923912Sjaap 		cstab[0] = cstab[savxfont];	/*  as  */
12023912Sjaap 		ccstab[0] = ccstab[savxfont];	/* well */
12123891Sjaap 	}
12223912Sjaap 	/* End */
12323891Sjaap 
12423912Sjaap 
12523891Sjaap 	bd = 0;
12623912Sjaap 	if (i >= nchtab + 128-32) {
12723912Sjaap 		j = abscw(i + 32 - (nchtab+128));
12823912Sjaap 		goto g0;
12923912Sjaap 	}
13023891Sjaap 	if (i == 0) {	/* a blank */
13123891Sjaap 		k = (fontab[xfont][0] * spacesz + 6) / 12;
13223891Sjaap 		/* this nonsense because .ss cmd uses 1/36 em as its units */
13323891Sjaap 		/* and default is 12 */
13423891Sjaap 		goto g1;
13523891Sjaap 	}
13623912Sjaap 	if ((j = fitab[xfont][i] & BYTEMASK) == 0) {	/* it's not on current font */
13723891Sjaap 		/* search through search list of xfont
13823891Sjaap 		/* to see what font it ought to be on.
13923912Sjaap 		/* searches S, then remaining fonts in wraparound order.
14023891Sjaap 		*/
14123912Sjaap 		nocache = 1;
14223891Sjaap 		if (smnt) {
14323912Sjaap 			int ii, jj;
14423891Sjaap 			for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
14523912Sjaap 				j = fitab[ii][i] & BYTEMASK;
14623891Sjaap 				if (j != 0) {
14723891Sjaap 					p = fontab[ii];
14823891Sjaap 					k = *(p + j);
14923912Sjaap 					if (xfont == sbold)
15023891Sjaap 						bd = bdtab[ii];
15123891Sjaap 					if (setwdf)
15223912Sjaap 						numtab[CT].val |= kerntab[ii][j];
15323891Sjaap 					goto g1;
15423891Sjaap 				}
15523891Sjaap 			}
15623891Sjaap 		}
15723891Sjaap 		k = fontab[xfont][0];	/* leave a space-size space */
15823891Sjaap 		goto g1;
15923891Sjaap 	}
16023912Sjaap  g0:
16123891Sjaap 	p = fontab[xfont];
16223891Sjaap 	if (setwdf)
16323912Sjaap 		numtab[CT].val |= kerntab[xfont][j];
16423891Sjaap 	k = *(p + j);
16523912Sjaap  g1:
16623891Sjaap 	if (!bd)
16723891Sjaap 		bd = bdtab[xfont];
16823891Sjaap 	if (cs = cstab[xfont]) {
16923912Sjaap 		nocache = 1;
17023891Sjaap 		if (ccs = ccstab[xfont])
17123891Sjaap 			x = ccs;
17223891Sjaap 		else
17323891Sjaap 			x = xpts;
17423891Sjaap 		cs = (cs * EMPTS(x)) / 36;
17523891Sjaap 	}
17623912Sjaap 	k = ((k&BYTEMASK) * xpts + (Unitwidth / 2)) / Unitwidth;
17723891Sjaap 	/*
17823912Sjaap 	 * undo the fontswap
17923891Sjaap 	 */
18023891Sjaap 	if(savxfont) {
18123891Sjaap 		xfont = savxfont;
18223891Sjaap 		if(savsbold)
18323891Sjaap 			sbold = savsbold;
18423891Sjaap 		if(savulfont)
18523891Sjaap 			ulfont = savulfont;
18623912Sjaap 		/*
18723912Sjaap 		 * H'm, I guess we should not put
18823912Sjaap 		 * this width in the cache
18923912Sjaap 		 */
19023912Sjaap 		nocache = 1;
19123891Sjaap 	}
19223912Sjaap 	if (nocache|bd)
19323912Sjaap 		widcache[i].fontpts = 0;
19423912Sjaap 	else {
19523912Sjaap 		widcache[i].fontpts = (xfont<<8) + xpts;
19623912Sjaap 		widcache[i].width = k;
19723912Sjaap 	}
19823912Sjaap 	return(k);
19923891Sjaap 	/* Unitwidth is Units/Point, where
20023891Sjaap 	/* Units is the fundamental digitization
20123891Sjaap 	/* of the character set widths, and
20223891Sjaap 	/* Point is the number of goobies in a point
20323891Sjaap 	/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
20423891Sjaap 	/* In effect, it's the size at which the widths
20523891Sjaap 	/* translate directly into units.
20623891Sjaap 	*/
20723891Sjaap }
20823891Sjaap 
abscw(n)20923912Sjaap abscw(n)	/* return index of abs char n in fontab[], etc. */
21023912Sjaap {	register int i, ncf;
21123891Sjaap 
21223912Sjaap 	ncf = fontbase[xfont]->nwfont & BYTEMASK;
21323912Sjaap 	for (i = 0; i < ncf; i++)
21423912Sjaap 		if (codetab[xfont][i] == n)
21523912Sjaap 			return i;
21623912Sjaap 	return 0;
21723912Sjaap }
21823912Sjaap 
xbits(i,bitf)21923912Sjaap xbits(i, bitf)
22023912Sjaap register tchar i;
22123891Sjaap {
22223912Sjaap 	register k;
22323891Sjaap 
22423891Sjaap 	xfont = fbits(i);
22523891Sjaap 	k = sbits(i);
22623891Sjaap 	if (k) {
22723891Sjaap 		xpts = pstab[--k];
22823891Sjaap 		oldbits = sfbits(i);
22923891Sjaap 		pfont = xfont;
23023891Sjaap 		ppts = xpts;
23123912Sjaap 		return;
23223891Sjaap 	}
23323912Sjaap 	switch (bitf) {
23423891Sjaap 	case 0:
23523891Sjaap 		xfont = font;
23623891Sjaap 		xpts = pts;
23723891Sjaap 		break;
23823891Sjaap 	case 1:
23923891Sjaap 		xfont = pfont;
24023891Sjaap 		xpts = ppts;
24123891Sjaap 		break;
24223891Sjaap 	case 2:
24323891Sjaap 		xfont = mfont;
24423891Sjaap 		xpts = mpts;
24523891Sjaap 	}
24623891Sjaap }
24723891Sjaap 
24823891Sjaap 
setch()24923891Sjaap tchar setch()
25023891Sjaap {
25123891Sjaap 	register j;
25223891Sjaap 	char	temp[10];
25323891Sjaap 	register char	*s;
25423891Sjaap 	extern char	*chname;
25523891Sjaap 	extern short	*chtab;
25623891Sjaap 	extern int	nchtab;
25723891Sjaap 
25823891Sjaap 	s = temp;
25923891Sjaap 	if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
26023891Sjaap 		return(0);
26123891Sjaap 	*s = '\0';
26223891Sjaap 	for (j = 0; j < nchtab; j++)
26323891Sjaap 		if (strcmp(&chname[chtab[j]], temp) == 0)
26423891Sjaap 			return(j + 128 | chbits);
26523891Sjaap 	return(0);
26623891Sjaap }
26723891Sjaap 
setabs()26823912Sjaap tchar setabs()		/* set absolute char from \C'...' */
26923912Sjaap {
27023912Sjaap 	int i, n, nf;
27123912Sjaap 	extern int	nchtab;
27223891Sjaap 
27323912Sjaap 	getch();
27423912Sjaap 	n = 0;
27523912Sjaap 	n = inumb(&n);
27623912Sjaap 	getch();
27723912Sjaap 	if (nonumb)
27823912Sjaap 		return 0;
27923912Sjaap 	return n + nchtab + 128;
28023891Sjaap }
28123912Sjaap /*
28223912Sjaap  * I (jaap) expand fontlab to the maximum of fonts troff can
28323912Sjaap  * handle. The maximum number i, due to the two chars
28423912Sjaap  * fontname limit, is 99.
28523912Sjaap  * If we don't use the (named) font in one of the
28623912Sjaap  * standard position, we install the name in the next
28723912Sjaap  * free slot. Whenever we need info about the font, we
28823912Sjaap  * read in the data at position zero, and secretly use
28923912Sjaap  * the data (actually only necessary for the width
29023912Sjaap  * and ligature info). The ptfont() (t10.c) routine will tell
29123912Sjaap  * the device filter to put the font always at position
29223912Sjaap  * zero if xfont > nfonts, so no need to change these filters.
29323912Sjaap  * Yes, this is a bit kludgy.
29423912Sjaap  *
29523912Sjaap  * This gives the new specs of findft:
29623912Sjaap  *
29723891Sjaap  * find the font name i, where i also can be a number.
29823891Sjaap  *
29923912Sjaap  * Installs the font(name) i when not present
30023891Sjaap  *
30123891Sjaap  * returns -1 on error
30223891Sjaap  */
30323891Sjaap 
findft(i)30423891Sjaap findft(i)
30523891Sjaap register int	i;
30623891Sjaap {
30723891Sjaap 	register k;
30823912Sjaap 	register char *p;
30923912Sjaap 	extern char * unpair();
31023891Sjaap 
31123912Sjaap 	p = unpair(i);
31223891Sjaap 
31323912Sjaap 	if( isdigit(p[0])) {		/* first look for numbers */
31423912Sjaap 		k = p[0] - '0';
31523912Sjaap 		if( p[1] > 0 && isdigit(p[1]))
31623912Sjaap 			k = 10 * k + ( p[1] - '0');
31723891Sjaap 
31823891Sjaap 		/*
31923891Sjaap 		fprintf(ptid, "x xxx it's a number: %d\n", k);
32023891Sjaap 		*/
32123891Sjaap 		if( k > 0 && k <= nfonts && k < smnt ) {
32223891Sjaap 			/*
32323891Sjaap 			fprintf(ptid, "x xxx it's a mounted font\n");
32423891Sjaap 			*/
32523891Sjaap 			return(k);	/* mounted font */
32623891Sjaap 		}
32723891Sjaap 		if( fontlab[k] && k <= MAXFONTS) {	/* translate */
32823891Sjaap 			/*
32923891Sjaap 			fprintf(ptid, "x xxx font exists\n");
33023891Sjaap 			*/
33123891Sjaap 			return(k);			/*number to a name */
33223891Sjaap 		}
33323891Sjaap 		else {
33423891Sjaap 			fprintf(stderr, "troff: no font at position %d\n", k);
33523891Sjaap 			return(-1);	/* wild number */
33623891Sjaap 		}
33723891Sjaap 	}
33823891Sjaap 
33923891Sjaap 	/*
34023891Sjaap 	 * Now we look for font names
34123891Sjaap 	 */
34223891Sjaap 	for (k = 1; fontlab[k] != i; k++) {
34323891Sjaap 		if (k > MAXFONTS +1)	/* the +1 is for the ``font cache'' */
34423891Sjaap 			return(-1);	/* running out of fontlab space */
34523891Sjaap 		if ( !fontlab[k] ) {	/* passed all existing names */
34623912Sjaap 			if(setfp(0, i, 0) < 0)
34723891Sjaap 				return(-1);
34823891Sjaap 			else {
34923891Sjaap 				/*
35023891Sjaap 				fprintf(ptid, "x xxx installed %s on %d\n", name ,k);
35123891Sjaap 				*/
352*31823Sjaap 					/* now install the name */
353*31823Sjaap 				fontlab[k] = i;
354*31823Sjaap 					/*
355*31823Sjaap 					 * and remember accociated with
356*31823Sjaap 					 * this font, ligature info etc.
357*31823Sjaap 					*/
35823891Sjaap 				return(k);
35923891Sjaap 			}
36023891Sjaap 		}
36123891Sjaap 	}
36223891Sjaap 	return(k);			/* was one of the existing names */
36323891Sjaap }
36423891Sjaap 
36523891Sjaap 
caseps()36623891Sjaap caseps()
36723891Sjaap {
36823891Sjaap 	register i;
36923891Sjaap 
37023891Sjaap 	if (skip())
37123891Sjaap 		i = apts1;
37223891Sjaap 	else {
37323891Sjaap 		noscale++;
37423891Sjaap 		i = inumb(&apts);	/* this is a disaster for fractional point sizes */
37523891Sjaap 		noscale = 0;
37623891Sjaap 		if (nonumb)
37723891Sjaap 			return;
37823891Sjaap 	}
37923891Sjaap 	casps1(i);
38023891Sjaap }
38123891Sjaap 
38223891Sjaap 
casps1(i)38323891Sjaap casps1(i)
38423891Sjaap register int	i;
38523891Sjaap {
38623912Sjaap 
38723912Sjaap /*
38823912Sjaap  * in olden times, it used to ignore changes to 0 or negative.
38923912Sjaap  * this is meant to allow the requested size to be anything,
39023912Sjaap  * in particular so eqn can generate lots of \s-3's and still
39123912Sjaap  * get back by matching \s+3's.
39223912Sjaap 
39323891Sjaap 	if (i <= 0)
39423891Sjaap 		return;
39523912Sjaap */
39623891Sjaap 	apts1 = apts;
39723891Sjaap 	apts = i;
39823891Sjaap 	pts1 = pts;
39923891Sjaap 	pts = findps(i);
40023891Sjaap 	mchbits();
40123891Sjaap }
40223891Sjaap 
40323891Sjaap 
findps(i)40423891Sjaap findps(i)
40523891Sjaap register int	i;
40623891Sjaap {
40723891Sjaap 	register j, k;
40823891Sjaap 
40923912Sjaap 	for (j=k=0 ; pstab[j] != 0 ; j++)
41023912Sjaap 		if (abs(pstab[j]-i) < abs(pstab[k]-i))
41123912Sjaap 			k = j;
41223912Sjaap 
41323912Sjaap 	return(pstab[k]);
41423891Sjaap }
41523891Sjaap 
41623891Sjaap 
mchbits()41723891Sjaap mchbits()
41823891Sjaap {
41923891Sjaap 	register i, j, k;
42023891Sjaap 
42123891Sjaap 	i = pts;
42223891Sjaap 	for (j = 0; i > (k = pstab[j]); j++)
42323891Sjaap 		if (!k) {
42423891Sjaap 			k = pstab[--j];
42523891Sjaap 			break;
42623891Sjaap 		}
42723891Sjaap 	chbits = 0;
42823891Sjaap 	setsbits(chbits, ++j);
42923891Sjaap 	setfbits(chbits, font);
43023891Sjaap 	sps = width(' ' | chbits);
43123912Sjaap 	zapwcache(1);
43223891Sjaap }
43323891Sjaap 
setps()43423891Sjaap setps()
43523891Sjaap {
43623912Sjaap 	register int i, j;
43723891Sjaap 
43823912Sjaap 	i = cbits(getch());
43923912Sjaap 	if (isdigit(i)) {		/* \sd or \sdd */
44023912Sjaap 		i -= '0';
44123912Sjaap 		if (i == 0)		/* \s0 */
44223912Sjaap 			j = apts1;
44323912Sjaap 		else if (i <= 3 && isdigit(j = cbits(ch=getch()))) {	/* \sdd */
44423912Sjaap 			j = 10 * i + j - '0';
44523912Sjaap 			ch = 0;
44623912Sjaap 		} else		/* \sd */
44723912Sjaap 			j = i;
44823912Sjaap 	} else if (i == '(') {		/* \s(dd */
44923912Sjaap 		j = cbits(getch()) - '0';
45023912Sjaap 		j = 10 * j + cbits(getch()) - '0';
45123912Sjaap 		if (j == 0)		/* \s(00 */
45223912Sjaap 			j = apts1;
45323912Sjaap 	} else if (i == '+' || i == '-') {	/* \s+, \s- */
45423912Sjaap 		j = cbits(getch());
45523912Sjaap 		if (isdigit(j)) {		/* \s+d, \s-d */
45623912Sjaap 			j -= '0';
45723912Sjaap 		} else if (j == '(') {		/* \s+(dd, \s-(dd */
45823912Sjaap 			j = cbits(getch()) - '0';
45923912Sjaap 			j = 10 * j + cbits(getch()) - '0';
46023912Sjaap 		}
46123891Sjaap 		if (i == '-')
46223891Sjaap 			j = -j;
46323912Sjaap 		j += apts;
46423891Sjaap 	}
46523912Sjaap 	casps1(j);
46623891Sjaap }
46723891Sjaap 
46823891Sjaap 
setht()46923891Sjaap tchar setht()		/* set character height from \H'...' */
47023891Sjaap {
47123891Sjaap 	int n;
47223891Sjaap 	tchar c;
47323891Sjaap 
47423891Sjaap 	getch();
47523891Sjaap 	n = inumb(&apts);
47623891Sjaap 	getch();
47723891Sjaap 	if (n == 0 || nonumb)
47823891Sjaap 		n = apts;	/* does this work? */
47923891Sjaap 	c = CHARHT;
48023891Sjaap 	c |= ZBIT;
48123891Sjaap 	setsbits(c, n);
48223891Sjaap 	return(c);
48323891Sjaap }
48423891Sjaap 
setslant()48523891Sjaap tchar setslant()		/* set slant from \S'...' */
48623891Sjaap {
48723891Sjaap 	int n;
48823891Sjaap 	tchar c;
48923891Sjaap 
49023891Sjaap 	getch();
49123891Sjaap 	n = 0;
49223891Sjaap 	n = inumb(&n);
49323891Sjaap 	getch();
49423891Sjaap 	if (nonumb)
49523891Sjaap 		n = 0;
49623891Sjaap 	c = SLANT;
49723891Sjaap 	c |= ZBIT;
49823891Sjaap 	setsfbits(c, n+180);
49923891Sjaap 	return(c);
50023891Sjaap }
50123891Sjaap 
50223891Sjaap 
caseft()50323891Sjaap caseft()
50423891Sjaap {
50523891Sjaap 	skip();
50623891Sjaap 	setfont(1);
50723891Sjaap }
50823891Sjaap 
50923891Sjaap 
setfont(a)51023891Sjaap setfont(a)
51123891Sjaap int	a;
51223891Sjaap {
51323891Sjaap 	register i, j;
51423891Sjaap 
51523891Sjaap 	if (a)
51623891Sjaap 		i = getrq();
51723891Sjaap 	else
51823891Sjaap 		i = getsn();
51923891Sjaap 	if (!i || i == 'P') {
52023891Sjaap 		j = font1;
52123891Sjaap 		goto s0;
52223891Sjaap 	}
52323891Sjaap 	if (i == 'S' || i == '0')
52423891Sjaap 		return;
52523891Sjaap 	if ((j = findft(i)) == -1)
52623912Sjaap 		if ((j = setfp(0, i, 0)) == -1)	/* try to put it in position 0 */
52723912Sjaap 			return;
52823891Sjaap s0:
52923891Sjaap 	font1 = font;
53023891Sjaap 	font = j;
53123891Sjaap 	mchbits();
53223891Sjaap }
53323891Sjaap 
53423891Sjaap 
setwd()53523891Sjaap setwd()
53623891Sjaap {
53723891Sjaap 	register base, wid;
53823912Sjaap 	register tchar i;
53923912Sjaap 	int	delim, emsz, k;
54023912Sjaap 	int	savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
54123891Sjaap 
54223912Sjaap 	base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0;
54323891Sjaap 	if (ismot(i = getch()))
54423891Sjaap 		return;
54523891Sjaap 	delim = cbits(i);
54623912Sjaap 	savhp = numtab[HP].val;
54723912Sjaap 	numtab[HP].val = 0;
54823891Sjaap 	savapts = apts;
54923891Sjaap 	savapts1 = apts1;
55023891Sjaap 	savfont = font;
55123891Sjaap 	savfont1 = font1;
55223891Sjaap 	savpts = pts;
55323891Sjaap 	savpts1 = pts1;
55423891Sjaap 	setwdf++;
55523891Sjaap 	while (cbits(i = getch()) != delim && !nlflg) {
55623912Sjaap 		k = width(i);
55723912Sjaap 		wid += k;
55823912Sjaap 		numtab[HP].val += k;
55923891Sjaap 		if (!ismot(i)) {
56023912Sjaap 			emsz = POINT * xpts;
56123891Sjaap 		} else if (isvmot(i)) {
56223891Sjaap 			k = absmot(i);
56323891Sjaap 			if (isnmot(i))
56423891Sjaap 				k = -k;
56523891Sjaap 			base -= k;
56623912Sjaap 			emsz = 0;
56723891Sjaap 		} else
56823891Sjaap 			continue;
56923912Sjaap 		if (base < numtab[SB].val)
57023912Sjaap 			numtab[SB].val = base;
57123912Sjaap 		if ((k = base + emsz) > numtab[ST].val)
57223912Sjaap 			numtab[ST].val = k;
57323891Sjaap 	}
57423912Sjaap 	setn1(wid, 0, (tchar) 0);
57523912Sjaap 	numtab[HP].val = savhp;
57623891Sjaap 	apts = savapts;
57723891Sjaap 	apts1 = savapts1;
57823891Sjaap 	font = savfont;
57923891Sjaap 	font1 = savfont1;
58023891Sjaap 	pts = savpts;
58123891Sjaap 	pts1 = savpts1;
58223891Sjaap 	mchbits();
58323891Sjaap 	setwdf = 0;
58423891Sjaap }
58523891Sjaap 
58623891Sjaap 
vmot()58723891Sjaap tchar vmot()
58823891Sjaap {
58923891Sjaap 	dfact = lss;
59023891Sjaap 	vflag++;
59123891Sjaap 	return(mot());
59223891Sjaap }
59323891Sjaap 
59423891Sjaap 
hmot()59523891Sjaap tchar hmot()
59623891Sjaap {
59723891Sjaap 	dfact = EM;
59823891Sjaap 	return(mot());
59923891Sjaap }
60023891Sjaap 
60123891Sjaap 
mot()60223891Sjaap tchar mot()
60323891Sjaap {
60423912Sjaap 	register int j, n;
60523912Sjaap 	register tchar i;
60623891Sjaap 
60723891Sjaap 	j = HOR;
60823891Sjaap 	getch(); /*eat delim*/
60923891Sjaap 	if (n = atoi()) {
61023891Sjaap 		if (vflag)
61123891Sjaap 			j = VERT;
61223891Sjaap 		i = makem(quant(n, j));
61323891Sjaap 	} else
61423891Sjaap 		i = 0;
61523891Sjaap 	getch();
61623891Sjaap 	vflag = 0;
61723891Sjaap 	dfact = 1;
61823891Sjaap 	return(i);
61923891Sjaap }
62023891Sjaap 
62123891Sjaap 
sethl(k)62223891Sjaap tchar sethl(k)
62323891Sjaap int	k;
62423891Sjaap {
62523891Sjaap 	register j;
62623891Sjaap 	tchar i;
62723891Sjaap 
62823891Sjaap 	j = EM / 2;
62923891Sjaap 	if (k == 'u')
63023891Sjaap 		j = -j;
63123891Sjaap 	else if (k == 'r')
63223891Sjaap 		j = -2 * j;
63323891Sjaap 	vflag++;
63423891Sjaap 	i = makem(j);
63523891Sjaap 	vflag = 0;
63623891Sjaap 	return(i);
63723891Sjaap }
63823891Sjaap 
63923891Sjaap 
makem(i)64023891Sjaap tchar makem(i)
64123912Sjaap register int	i;
64223891Sjaap {
64323912Sjaap 	register tchar j;
64423891Sjaap 
64523891Sjaap 	if ((j = i) < 0)
64623891Sjaap 		j = -j;
64723891Sjaap 	j |= MOT;
64823891Sjaap 	if (i < 0)
64923891Sjaap 		j |= NMOT;
65023891Sjaap 	if (vflag)
65123891Sjaap 		j |= VMOT;
65223891Sjaap 	return(j);
65323891Sjaap }
65423891Sjaap 
65523891Sjaap 
getlg(i)65623891Sjaap tchar getlg(i)
65723891Sjaap tchar i;
65823891Sjaap {
65923891Sjaap 	tchar j, k;
66023912Sjaap 	register int lf;
66123891Sjaap 
662*31823Sjaap 		/* remember to map the font */
663*31823Sjaap 	if ((lf = fontbase[fbits(i) > NFONT ? 0 : fbits(i)]->ligfont) == 0) {
664*31823Sjaap 		/* font lacks ligatures */
66523891Sjaap 		return(i);
666*31823Sjaap 	}
66723891Sjaap 	j = getch0();
66823891Sjaap 	if (cbits(j) == 'i' && (lf & LFI))
66923891Sjaap 		j = LIG_FI;
67023891Sjaap 	else if (cbits(j) == 'l' && (lf & LFL))
67123891Sjaap 		j = LIG_FL;
67223891Sjaap 	else if (cbits(j) == 'f' && (lf & LFF)) {
67323891Sjaap 		if ((lf & (LFFI|LFFL)) && lg != 2) {
67423891Sjaap 			k = getch0();
67523891Sjaap 			if (cbits(k)=='i' && (lf&LFFI))
67623891Sjaap 				j = LIG_FFI;
67723891Sjaap 			else if (cbits(k)=='l' && (lf&LFFL))
67823891Sjaap 				j = LIG_FFL;
67923891Sjaap 			else {
68023912Sjaap 				*pbp++ = k;
68123891Sjaap 				j = LIG_FF;
68223891Sjaap 			}
68323891Sjaap 		} else
68423891Sjaap 			j = LIG_FF;
68523891Sjaap 	} else {
68623912Sjaap 		*pbp++ = j;
68723891Sjaap 		j = i;
68823891Sjaap 	}
68923891Sjaap 	return(i & SFMASK | j);
69023891Sjaap }
69123891Sjaap 
69223891Sjaap 
caselg()69323891Sjaap caselg()
69423891Sjaap {
69523891Sjaap 
69623891Sjaap 	lg = 1;
69723891Sjaap 	if (skip())
69823891Sjaap 		return;
69923891Sjaap 	lg = atoi();
70023891Sjaap }
70123891Sjaap 
70223891Sjaap 
casefp()70323891Sjaap casefp()
70423891Sjaap {
70523912Sjaap 	register int i, j;
70623912Sjaap 	register char *s;
70723891Sjaap 
70823891Sjaap 	skip();
70923891Sjaap 	if ((i = cbits(getch()) - '0') <= 0 || i > nfonts)
71023912Sjaap 		errprint("fp: bad font position %d", i);
71123891Sjaap 	else if (skip() || !(j = getrq()))
71223912Sjaap 		errprint("fp: no font name");
71323912Sjaap 	else if (skip() || !getname())
71423912Sjaap 		setfp(i, j, 0);
71523912Sjaap 	else		/* 3rd argument = filename */
71623912Sjaap 		setfp(i, j, nextf);
71723891Sjaap }
71823891Sjaap 
setfp(pos,f,truename)71923912Sjaap setfp(pos, f, truename)	/* mount font f at position pos[0...nfonts] */
72023891Sjaap int pos, f;
72123912Sjaap char *truename;
72223891Sjaap {
72323912Sjaap 	register k;
72423891Sjaap 	int n;
72523912Sjaap 	char longname[NS], shortname[20];
72623912Sjaap 	extern int nchtab;
72723891Sjaap 
72823912Sjaap 	if (fontlab[pos] == f)		/* if f already mounted at pos, */
72923912Sjaap 		return(pos);		/* don't remount it */
73023912Sjaap 	zapwcache(0);
73123912Sjaap 	if (truename)
73223912Sjaap 		strcpy(shortname, truename);
73323912Sjaap 	else {
73423912Sjaap 		shortname[0] = f & BYTEMASK;
73523912Sjaap 		shortname[1] = f >> BYTE;
73623912Sjaap 		shortname[2] = '\0';
73723912Sjaap 	}
73823891Sjaap 	sprintf(longname, "%s/dev%s/%s.out", fontfile, devname, shortname);
73923891Sjaap 	if ((k = open(longname, 0)) < 0) {
74023912Sjaap 		errprint("Can't open %s", longname);
74123891Sjaap 		return(-1);
74223891Sjaap 	}
74323912Sjaap 	n = fontbase[pos]->nwfont & BYTEMASK;
74423912Sjaap 	read(k, (char *) fontbase[pos], 3*n + nchtab + 128 - 32 + sizeof(struct Font));
745*31823Sjaap 
74623912Sjaap 	kerntab[pos] = (char *) fontab[pos] + (fontbase[pos]->nwfont & BYTEMASK);
74723891Sjaap 	/* have to reset the fitab pointer because the width may be different */
74823912Sjaap 	fitab[pos] = (char *) fontab[pos] + 3 * (fontbase[pos]->nwfont & BYTEMASK);
74923912Sjaap 	if ((fontbase[pos]->nwfont & BYTEMASK) > n) {
75023912Sjaap 		errprint("Font %s too big for position %d", shortname, pos);
75123891Sjaap 		return(-1);
75223891Sjaap 	}
75323891Sjaap 	fontbase[pos]->nwfont = n;	/* so can load a larger one again later */
75423891Sjaap 	close(k);
75523891Sjaap 	if (pos == smnt) {
75623912Sjaap 		smnt = 0;
75723891Sjaap 		sbold = 0;
75823891Sjaap 	}
75923891Sjaap 	if ((fontlab[pos] = f) == 'S')
76023891Sjaap 		smnt = pos;
76123891Sjaap 	bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
76223891Sjaap 		/* if there is a directory, no place to store its name. */
76323891Sjaap 		/* if position isn't zero, no place to store its value. */
76423891Sjaap 		/* only time a FONTPOS is pushed back is if it's a */
76523891Sjaap 		/* standard font on position 0 (i.e., mounted implicitly. */
76623891Sjaap 		/* there's a bug here:  if there are several input lines */
76723891Sjaap 		/* that look like .ft XX in short successtion, the output */
76823891Sjaap 		/* will all be in the last one because the "x font ..." */
76923891Sjaap 		/* comes out too soon.  pushing back FONTPOS doesn't work */
77023891Sjaap 		/* with .ft commands because input is flushed after .xx cmds */
77123891Sjaap 
77223912Sjaap 		/*
77323912Sjaap 		 * Trying to fix this FONTPOS problem: See findft()
77423891Sjaap 		 */
77523912Sjaap 	if ( pos > 0 && pos <= nfonts)
77623891Sjaap 		ptfpcmd(pos, shortname);
77723891Sjaap 	return(pos);
77823891Sjaap }
77923891Sjaap 
78023891Sjaap 
casecs()78123891Sjaap casecs()
78223891Sjaap {
78323891Sjaap 	register i, j;
78423891Sjaap 
78523891Sjaap 	noscale++;
78623891Sjaap 	skip();
78723891Sjaap 	if (!(i = getrq()) || (i = findft(i)) < 0)
78823891Sjaap 		goto rtn;
78923891Sjaap 	skip();
79023891Sjaap 	cstab[i] = atoi();
79123891Sjaap 	skip();
79223891Sjaap 	j = atoi();
79323891Sjaap 	if (nonumb)
79423891Sjaap 		ccstab[i] = 0;
79523891Sjaap 	else
79623891Sjaap 		ccstab[i] = findps(j);
79723891Sjaap rtn:
79823912Sjaap 	zapwcache(0);
79923891Sjaap 	noscale = 0;
80023891Sjaap }
80123891Sjaap 
80223891Sjaap 
casebd()80323891Sjaap casebd()
80423891Sjaap {
80523891Sjaap 	register i, j, k;
80623891Sjaap 
80723912Sjaap 	zapwcache(0);
80823891Sjaap 	k = 0;
80923891Sjaap bd0:
81023891Sjaap 	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
81123891Sjaap 		if (k)
81223891Sjaap 			goto bd1;
81323891Sjaap 		else
81423891Sjaap 			return;
81523891Sjaap 	}
81623891Sjaap 	if (j == smnt) {
81723891Sjaap 		k = smnt;
81823891Sjaap 		goto bd0;
81923891Sjaap 	}
82023891Sjaap 	if (k) {
82123891Sjaap 		sbold = j;
82223891Sjaap 		j = k;
82323891Sjaap 	}
82423891Sjaap bd1:
82523891Sjaap 	skip();
82623891Sjaap 	noscale++;
82723891Sjaap 	bdtab[j] = atoi();
82823891Sjaap 	noscale = 0;
82923891Sjaap }
83023891Sjaap 
83123891Sjaap 
casevs()83223891Sjaap casevs()
83323891Sjaap {
83423891Sjaap 	register i;
83523891Sjaap 
83623891Sjaap 	skip();
83723891Sjaap 	vflag++;
83823891Sjaap 	dfact = INCH; /* default scaling is points! */
83923891Sjaap 	dfactd = 72;
84023891Sjaap 	res = VERT;
84123891Sjaap 	i = inumb(&lss);
84223891Sjaap 	if (nonumb)
84323891Sjaap 		i = lss1;
84423891Sjaap 	/*	if(i < VERT)i = VERT; */
84523891Sjaap 	if (i < VERT)
84623891Sjaap 		i = 0;
84723891Sjaap 	lss1 = lss;
84823891Sjaap 	lss = i;
84923891Sjaap }
85023891Sjaap 
85123891Sjaap 
casess()85223891Sjaap casess()
85323891Sjaap {
85423891Sjaap 	register i;
85523891Sjaap 
85623891Sjaap 	noscale++;
85723891Sjaap 	skip();
85823891Sjaap 	if (i = atoi()) {
85923891Sjaap 		spacesz = i & 0177;
86023912Sjaap 		zapwcache(0);
86123891Sjaap 		sps = width(' ' | chbits);
86223891Sjaap 	}
86323891Sjaap 	noscale = 0;
86423891Sjaap }
86523891Sjaap 
86623891Sjaap 
xlss()86723891Sjaap tchar xlss()
86823891Sjaap {
86923891Sjaap 	/* stores \x'...' into
87023891Sjaap 	/* two successive tchars.
87123891Sjaap 	/* the first contains HX, the second the value,
87223891Sjaap 	/* encoded as a vertical motion.
87323891Sjaap 	/* decoding is done in n2.c by pchar().
87423891Sjaap 	*/
87523891Sjaap 	int	i;
87623891Sjaap 
87723891Sjaap 	getch();
87823891Sjaap 	dfact = lss;
87923891Sjaap 	i = quant(atoi(), VERT);
88023891Sjaap 	dfact = 1;
88123891Sjaap 	getch();
88223891Sjaap 	if (i >= 0)
88323912Sjaap 		*pbp++ = MOT | VMOT | i;
88423891Sjaap 	else
88523912Sjaap 		*pbp++ = MOT | VMOT | NMOT | -i;
88623912Sjaap 	return(HX);
88723891Sjaap }
88823912Sjaap 
88923912Sjaap char *
unpair(i)89023912Sjaap unpair(i)
89123912Sjaap register int i;
89223912Sjaap {	static char name[3];
89323912Sjaap 
89423912Sjaap 	name[0] = i & BYTEMASK;
89523912Sjaap 	name[1] = i >> BYTE;
89623912Sjaap 	name[2] = 0;
89723912Sjaap 	return (name);
89823912Sjaap }
899