xref: /csrg-svn/local/ditroff/ditroff.van/t6.c (revision 54111)
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