xref: /plan9/sys/src/cmd/troff/t6.c (revision 14f51593fd82e19ba95969a8c07ff71131015979)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * t6.c
33e12c5d1SDavid du Colombier  *
43e12c5d1SDavid du Colombier  * width functions, sizes and fonts
53e12c5d1SDavid du Colombier  */
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier #include "tdef.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier #include "ext.h"
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier int	fontlab[MAXFONTS+1];
123e12c5d1SDavid du Colombier int	cstab[MAXFONTS+1];
133e12c5d1SDavid du Colombier int	ccstab[MAXFONTS+1];
143e12c5d1SDavid du Colombier int	bdtab[MAXFONTS+1];
153e12c5d1SDavid du Colombier int	sbold = 0;
163e12c5d1SDavid du Colombier 
t_width(Tchar j)173e12c5d1SDavid du Colombier t_width(Tchar j)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	int i, k;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier 	if (iszbit(j))
223e12c5d1SDavid du Colombier 		return 0;
233e12c5d1SDavid du Colombier 	if (ismot(j)) {
243e12c5d1SDavid du Colombier 		if (isvmot(j))
253e12c5d1SDavid du Colombier 			return(0);
263e12c5d1SDavid du Colombier 		k = absmot(j);
273e12c5d1SDavid du Colombier 		if (isnmot(j))
283e12c5d1SDavid du Colombier 			k = -k;
293e12c5d1SDavid du Colombier 		return(k);
303e12c5d1SDavid du Colombier 	}
313e12c5d1SDavid du Colombier 	i = cbits(j);
323e12c5d1SDavid du Colombier 	if (i < ' ') {
333e12c5d1SDavid du Colombier 		if (i == '\b')
343e12c5d1SDavid du Colombier 			return(-widthp);
353e12c5d1SDavid du Colombier 		if (i == PRESC)
363e12c5d1SDavid du Colombier 			i = eschar;
373e12c5d1SDavid du Colombier 		else if (i == HX)
383e12c5d1SDavid du Colombier 			return(0);
393e12c5d1SDavid du Colombier 	}
403e12c5d1SDavid du Colombier 	if (i == ohc)
413e12c5d1SDavid du Colombier 		return(0);
423e12c5d1SDavid du Colombier 	i = trtab[i];
433e12c5d1SDavid du Colombier 	if (i < ' ')
443e12c5d1SDavid du Colombier 		return(0);
453e12c5d1SDavid du Colombier 	if (sfbits(j) == oldbits) {
463e12c5d1SDavid du Colombier 		xfont = pfont;
473e12c5d1SDavid du Colombier 		xpts = ppts;
483e12c5d1SDavid du Colombier 	} else
493e12c5d1SDavid du Colombier 		xbits(j, 0);
503e12c5d1SDavid du Colombier 	if (i < nchnames + ALPHABET && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf)
513e12c5d1SDavid du Colombier 		k = widcache[i].width;
523e12c5d1SDavid du Colombier 	else {
533e12c5d1SDavid du Colombier 		k = getcw(i);
543e12c5d1SDavid du Colombier 		if (bd)
553e12c5d1SDavid du Colombier 			k += (bd - 1) * HOR;
563e12c5d1SDavid du Colombier 		if (cs)
573e12c5d1SDavid du Colombier 			k = cs;
583e12c5d1SDavid du Colombier 	}
593e12c5d1SDavid du Colombier 	widthp = k;
603e12c5d1SDavid du Colombier 	return(k);
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier 
633e12c5d1SDavid du Colombier /*
643e12c5d1SDavid du Colombier  * clear width cache-- s means just space
653e12c5d1SDavid du Colombier  */
zapwcache(int s)663e12c5d1SDavid du Colombier void zapwcache(int s)
673e12c5d1SDavid du Colombier {
683e12c5d1SDavid du Colombier 	int i;
693e12c5d1SDavid du Colombier 
703e12c5d1SDavid du Colombier 	if (s) {
713e12c5d1SDavid du Colombier 		widcache[' '].fontpts = 0;
723e12c5d1SDavid du Colombier 		return;
733e12c5d1SDavid du Colombier 	}
743e12c5d1SDavid du Colombier 	for (i=0; i<NWIDCACHE; i++)
753e12c5d1SDavid du Colombier 		widcache[i].fontpts = 0;
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier 
onfont(int n,int f)783e12c5d1SDavid du Colombier onfont(int n, int f)	/* is char n on font f? */
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier 	int i;
813e12c5d1SDavid du Colombier 	Font *fp = &fonts[f];
823e12c5d1SDavid du Colombier 	Chwid *cp, *ep;
833e12c5d1SDavid du Colombier 	char *np;
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 	if (n < ALPHABET) {
863e12c5d1SDavid du Colombier 		if (fp->wp[n].num == n)	/* ascii at front */
873e12c5d1SDavid du Colombier 			return n;
883e12c5d1SDavid du Colombier 		else
893e12c5d1SDavid du Colombier 			return -1;
903e12c5d1SDavid du Colombier 	}
913e12c5d1SDavid du Colombier 	cp = &fp->wp[ALPHABET];
923e12c5d1SDavid du Colombier 	ep = &fp->wp[fp->nchars];
933e12c5d1SDavid du Colombier 	for ( ; cp < ep; cp++)	/* search others */
943e12c5d1SDavid du Colombier 		if (cp->num == n)
953e12c5d1SDavid du Colombier 			return cp - &fp->wp[0];
963e12c5d1SDavid du Colombier 	/* maybe it was a \N... */
973e12c5d1SDavid du Colombier 	np = chname(n);
983e12c5d1SDavid du Colombier 	if (*np == Number) {
993e12c5d1SDavid du Colombier 		i = atoi(np+1);		/* sscanf(np+1, "%d", &i); */
1003e12c5d1SDavid du Colombier 		cp = &fp->wp[0];
1013e12c5d1SDavid du Colombier 		ep = &fp->wp[fp->nchars];
1023e12c5d1SDavid du Colombier 		for ( ; cp < ep; cp++) {	/* search others */
1033e12c5d1SDavid du Colombier 			if (cp->code == i)
1043e12c5d1SDavid du Colombier 				return cp - &fp->wp[0];
1053e12c5d1SDavid du Colombier 		}
1063e12c5d1SDavid du Colombier 		return -2;	/* a \N that doesn't have an entry */
1073e12c5d1SDavid du Colombier 	}
1083e12c5d1SDavid du Colombier 	return -1;	/* vanilla not found */
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier 
getcw(int i)1113e12c5d1SDavid du Colombier getcw(int i)
1123e12c5d1SDavid du Colombier {
1133e12c5d1SDavid du Colombier 	int k, n, x;
1143e12c5d1SDavid du Colombier 	Font *fp;
1153e12c5d1SDavid du Colombier 	int nocache = 0;
1163e12c5d1SDavid du Colombier 	if (i < ' ')
1173e12c5d1SDavid du Colombier 		return 0;
1183e12c5d1SDavid du Colombier 	bd = 0;
1193e12c5d1SDavid du Colombier 	fp = &fonts[xfont];
1203e12c5d1SDavid du Colombier 	if (i == ' ') {	/* a blank */
1213e12c5d1SDavid du Colombier 		k = (fp->spacewidth * spacesz + 6) / 12;
1223e12c5d1SDavid du Colombier 		/* this nonsense because .ss cmd uses 1/36 em as its units */
1233e12c5d1SDavid du Colombier 		/* 	and default is 12 */
1243e12c5d1SDavid du Colombier 	} else if ((n = onfont(i, xfont)) >= 0) {	/* on this font at n */
1253e12c5d1SDavid du Colombier 		k = fp->wp[n].wid;
1263e12c5d1SDavid du Colombier 		if (setwdf)
127219b2ee8SDavid du Colombier 			numtabp[CT].val |= fp->wp[n].kern;
1283e12c5d1SDavid du Colombier 	} else if (n == -2) {		/* \N with default width */
129219b2ee8SDavid du Colombier 
1303e12c5d1SDavid du Colombier 		k = fp->defaultwidth;
1313e12c5d1SDavid du Colombier 	} else {			/* not on current font */
1323e12c5d1SDavid du Colombier 		nocache = 1;
1333e12c5d1SDavid du Colombier 		k = fp->defaultwidth;	/* default-size space */
1343e12c5d1SDavid du Colombier 		if (smnt) {
1353e12c5d1SDavid du Colombier 			int ii, jj;
1363e12c5d1SDavid du Colombier 			for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
1373e12c5d1SDavid du Colombier 				if ((n = onfont(i, ii)) >= 0) {
1383e12c5d1SDavid du Colombier 					k = fonts[ii].wp[n].wid;
1393e12c5d1SDavid du Colombier 					if (xfont == sbold)
1403e12c5d1SDavid du Colombier 						bd = bdtab[ii];
1413e12c5d1SDavid du Colombier 					if (setwdf)
142219b2ee8SDavid du Colombier 						numtabp[CT].val |= fonts[ii].wp[n].kern;
1433e12c5d1SDavid du Colombier 					break;
1443e12c5d1SDavid du Colombier 				}
1453e12c5d1SDavid du Colombier 			}
1463e12c5d1SDavid du Colombier 		}
1473e12c5d1SDavid du Colombier 	}
1483e12c5d1SDavid du Colombier 	if (!bd)
1493e12c5d1SDavid du Colombier 		bd = bdtab[xfont];
1503e12c5d1SDavid du Colombier 	if (cs = cstab[xfont]) {
1513e12c5d1SDavid du Colombier 		nocache = 1;
1523e12c5d1SDavid du Colombier 		if (ccs = ccstab[xfont])
1533e12c5d1SDavid du Colombier 			x = ccs;
1543e12c5d1SDavid du Colombier 		else
1553e12c5d1SDavid du Colombier 			x = xpts;
1563e12c5d1SDavid du Colombier 		cs = (cs * EMPTS(x)) / 36;
1573e12c5d1SDavid du Colombier 	}
1583e12c5d1SDavid du Colombier 	/* was (k & BYTEMASK);  since .wid is unsigned, should never happen */
1593e12c5d1SDavid du Colombier 	if (k < 0)
1603e12c5d1SDavid du Colombier 		ERROR "can't happen: negative width %d in getcw %d\n", k, i WARN;
1613e12c5d1SDavid du Colombier 	k = (k * xpts + (Unitwidth / 2)) / Unitwidth;
1623e12c5d1SDavid du Colombier 	if (nocache|bd)
1633e12c5d1SDavid du Colombier 		widcache[i].fontpts = 0;
1643e12c5d1SDavid du Colombier 	else {
1653e12c5d1SDavid du Colombier 		widcache[i].fontpts = (xfont<<8) + xpts;
1663e12c5d1SDavid du Colombier 		widcache[i].width = k;
1673e12c5d1SDavid du Colombier 	}
1683e12c5d1SDavid du Colombier 	return(k);
1693e12c5d1SDavid du Colombier 	/* Unitwidth is Units/Point, where
1703e12c5d1SDavid du Colombier 	/* Units is the fundamental digitization
1713e12c5d1SDavid du Colombier 	/* of the character set widths, and
1723e12c5d1SDavid du Colombier 	/* Point is the number of goobies in a point
1733e12c5d1SDavid du Colombier 	/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
1743e12c5d1SDavid du Colombier 	/* In effect, it's the size at which the widths
1753e12c5d1SDavid du Colombier 	/* translate directly into units.
1763e12c5d1SDavid du Colombier 	*/
1773e12c5d1SDavid du Colombier }
1783e12c5d1SDavid du Colombier 
xbits(Tchar i,int bitf)1793e12c5d1SDavid du Colombier void xbits(Tchar i, int bitf)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier 	int k;
1823e12c5d1SDavid du Colombier 
1833e12c5d1SDavid du Colombier 	if(TROFF) {
1843e12c5d1SDavid du Colombier 		xfont = fbits(i);
1853e12c5d1SDavid du Colombier 		k = sbits(i);
1863e12c5d1SDavid du Colombier 		if(k) {
1873e12c5d1SDavid du Colombier 			xpts = pstab[k-1];
1883e12c5d1SDavid du Colombier 			oldbits = sfbits(i);
1893e12c5d1SDavid du Colombier 			pfont = xfont;
1903e12c5d1SDavid du Colombier 			ppts = xpts;
1913e12c5d1SDavid du Colombier 			return;
1923e12c5d1SDavid du Colombier 		}
1933e12c5d1SDavid du Colombier 		switch(bitf) {
1943e12c5d1SDavid du Colombier 		case 0:
1953e12c5d1SDavid du Colombier 			xfont = font;
1963e12c5d1SDavid du Colombier 			xpts = pts;
1973e12c5d1SDavid du Colombier 			break;
1983e12c5d1SDavid du Colombier 		case 1:
1993e12c5d1SDavid du Colombier 			xfont = pfont;
2003e12c5d1SDavid du Colombier 			xpts = ppts;
2013e12c5d1SDavid du Colombier 			break;
2023e12c5d1SDavid du Colombier 		case 2:
2033e12c5d1SDavid du Colombier 			xfont = mfont;
2043e12c5d1SDavid du Colombier 			xpts = mpts;
2053e12c5d1SDavid du Colombier 		}
2063e12c5d1SDavid du Colombier 	}
2073e12c5d1SDavid du Colombier }
2083e12c5d1SDavid du Colombier 
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier /* these next two functions ought to be the same in troff and nroff, */
2113e12c5d1SDavid du Colombier /* but the data structures they search are different. */
2123e12c5d1SDavid du Colombier /* silly historical problem. */
2133e12c5d1SDavid du Colombier 
2143e12c5d1SDavid du Colombier 
t_setch(int c)2153e12c5d1SDavid du Colombier Tchar t_setch(int c)
2163e12c5d1SDavid du Colombier {
2173e12c5d1SDavid du Colombier 	char temp[50];
2183e12c5d1SDavid du Colombier 	char *s;
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 	s = temp;
2213e12c5d1SDavid du Colombier 	if (c == '(') {	/* \(xx */
2223e12c5d1SDavid du Colombier 		if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
2233e12c5d1SDavid du Colombier 			return(0);
2243e12c5d1SDavid du Colombier 	} else {	/* \C'...' */
2253e12c5d1SDavid du Colombier 		c = getach();
2263e12c5d1SDavid du Colombier 		while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1)
2273e12c5d1SDavid du Colombier 			s++;
2283e12c5d1SDavid du Colombier 	}
2293e12c5d1SDavid du Colombier 	*s = '\0';
230219b2ee8SDavid du Colombier #ifdef UNICODE
2313e12c5d1SDavid du Colombier 	return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
232219b2ee8SDavid du Colombier #else
233219b2ee8SDavid du Colombier 	if (NROFF) {
234*14f51593SDavid du Colombier 		int j;
235*14f51593SDavid du Colombier 
236219b2ee8SDavid du Colombier 		j = chadd(temp, Troffchar, Lookup);
237219b2ee8SDavid du Colombier 		if ( j == -1)
238219b2ee8SDavid du Colombier 			return 0;
239219b2ee8SDavid du Colombier 		else
240219b2ee8SDavid du Colombier 			return j | chbits;
241219b2ee8SDavid du Colombier 	} else
242219b2ee8SDavid du Colombier 		return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
243219b2ee8SDavid du Colombier 
244219b2ee8SDavid du Colombier #endif /*UNICODE*/
2453e12c5d1SDavid du Colombier }
2463e12c5d1SDavid du Colombier 
t_setabs(void)2473e12c5d1SDavid du Colombier Tchar t_setabs(void)		/* set absolute char from \N'...' */
2483e12c5d1SDavid du Colombier {
2493e12c5d1SDavid du Colombier 	int n;
2503e12c5d1SDavid du Colombier 	char temp[10];
2513e12c5d1SDavid du Colombier 
2523e12c5d1SDavid du Colombier 	getch();	/* delim */
2533e12c5d1SDavid du Colombier 	n = 0;
2543e12c5d1SDavid du Colombier 	n = inumb(&n);
2553e12c5d1SDavid du Colombier 	getch();	/* delim */
2563e12c5d1SDavid du Colombier 	if (nonumb)
2573e12c5d1SDavid du Colombier 		return 0;
2583e12c5d1SDavid du Colombier 	sprintf(temp, "%d", n);	/* convert into "#n" */
2593e12c5d1SDavid du Colombier 	n = chadd(temp, Number, Install);
2603e12c5d1SDavid du Colombier 	return n | chbits;
2613e12c5d1SDavid du Colombier }
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier 
2643e12c5d1SDavid du Colombier /*
2653e12c5d1SDavid du Colombier  * fontlab[] is a cache that contains font information
2663e12c5d1SDavid du Colombier  * for each font.
2673e12c5d1SDavid du Colombier  * fontlab[] contains the 1- or 2-character name of the
2683e12c5d1SDavid du Colombier  * font current associated with that font.
2693e12c5d1SDavid du Colombier  * fonts 1..nfonts correspond to the mounted fonts;
2703e12c5d1SDavid du Colombier  * the last of these are the special fonts.
2713e12c5d1SDavid du Colombier  * If we don't use the (named) font in one of the
2723e12c5d1SDavid du Colombier  * standard positions, we install the name in the next
2733e12c5d1SDavid du Colombier  * free slot of fontlab[] and font[].
2743e12c5d1SDavid du Colombier  * Whenever we need info about the font, we
2753e12c5d1SDavid du Colombier  * read in the data into the next free slot with getfont.
2763e12c5d1SDavid du Colombier  * The ptfont() (t10.c) routine will tell
2773e12c5d1SDavid du Colombier  * the device filter to put the font always at position
2783e12c5d1SDavid du Colombier  * zero if xfont > nfonts, so no need to change these filters.
2793e12c5d1SDavid du Colombier  * Yes, this is a bit kludgy.
2803e12c5d1SDavid du Colombier  *
2813e12c5d1SDavid du Colombier  * This gives the new specs of findft:
2823e12c5d1SDavid du Colombier  * 	find the font name i, where i also can be a number.
2833e12c5d1SDavid du Colombier  * 	Installs the font(name) i when not present
2843e12c5d1SDavid du Colombier  * 	returns -1 on error
2853e12c5d1SDavid du Colombier  */
2863e12c5d1SDavid du Colombier 
2873e12c5d1SDavid du Colombier 
t_findft(int i)2883e12c5d1SDavid du Colombier t_findft(int i)
2893e12c5d1SDavid du Colombier {
2903e12c5d1SDavid du Colombier 	int k;
291219b2ee8SDavid du Colombier 	Uchar *p;
2923e12c5d1SDavid du Colombier 
2933e12c5d1SDavid du Colombier 	p = unpair(i);
2943e12c5d1SDavid du Colombier 
2953e12c5d1SDavid du Colombier 	if (isdigit(p[0])) {		/* first look for numbers */
2963e12c5d1SDavid du Colombier 		k = p[0] - '0';
2973e12c5d1SDavid du Colombier 		if (p[1] > 0 && isdigit(p[1]))
2983e12c5d1SDavid du Colombier 			k = 10 * k + p[1] - '0';
2993e12c5d1SDavid du Colombier 		if (k > 0 && k <= nfonts && k < smnt)
3003e12c5d1SDavid du Colombier 			return(k);	/* mounted font:  .ft 3 */
3013e12c5d1SDavid du Colombier 		if (fontlab[k] && k <= MAXFONTS) {	/* translate */
3023e12c5d1SDavid du Colombier 			return(k);			/*number to a name */
3033e12c5d1SDavid du Colombier 		} else {
3043e12c5d1SDavid du Colombier 			fprintf(stderr, "troff: no font at position %d\n", k);
3053e12c5d1SDavid du Colombier 			return(-1);	/* wild number */
3063e12c5d1SDavid du Colombier 		}
3073e12c5d1SDavid du Colombier 	}
3083e12c5d1SDavid du Colombier 
3093e12c5d1SDavid du Colombier 	/*
3103e12c5d1SDavid du Colombier 	 * Now we look for font names
3113e12c5d1SDavid du Colombier 	 */
3123e12c5d1SDavid du Colombier 	for (k = 1; fontlab[k] != i; k++) {
3133e12c5d1SDavid du Colombier 		if (k > MAXFONTS)
3143e12c5d1SDavid du Colombier 			return(-1);	/* running out of fontlab space */
3153e12c5d1SDavid du Colombier 		if (fontlab[k] == 0) {	/* passed all existing names */
3163e12c5d1SDavid du Colombier 			if (setfp(k, i, (char *) 0, 1) == -1)
3173e12c5d1SDavid du Colombier 				return(-1);
3183e12c5d1SDavid du Colombier 			else {
3193e12c5d1SDavid du Colombier 				fontlab[k] = i;	/* install the name */
3203e12c5d1SDavid du Colombier 				return(k);
3213e12c5d1SDavid du Colombier 			}
3223e12c5d1SDavid du Colombier 		}
3233e12c5d1SDavid du Colombier 	}
3243e12c5d1SDavid du Colombier 	return(k);			/* was one of the existing names */
3253e12c5d1SDavid du Colombier }
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier 
caseps(void)3283e12c5d1SDavid du Colombier void caseps(void)
3293e12c5d1SDavid du Colombier {
3303e12c5d1SDavid du Colombier 	int i;
3313e12c5d1SDavid du Colombier 
3323e12c5d1SDavid du Colombier 	if (TROFF) {
3333e12c5d1SDavid du Colombier 		if(skip())
3343e12c5d1SDavid du Colombier 			i = apts1;
3353e12c5d1SDavid du Colombier 		else {
3363e12c5d1SDavid du Colombier 			noscale++;
3373e12c5d1SDavid du Colombier 			i = inumb(&apts);	/* this is a disaster for fractional point sizes */
3383e12c5d1SDavid du Colombier 			noscale = 0;
3393e12c5d1SDavid du Colombier 			if(nonumb)
340219b2ee8SDavid du Colombier 				i = apts1;
3413e12c5d1SDavid du Colombier 		}
3423e12c5d1SDavid du Colombier 		casps1(i);
3433e12c5d1SDavid du Colombier 	}
3443e12c5d1SDavid du Colombier }
3453e12c5d1SDavid du Colombier 
3463e12c5d1SDavid du Colombier 
casps1(int i)3473e12c5d1SDavid du Colombier void casps1(int i)
3483e12c5d1SDavid du Colombier {
3493e12c5d1SDavid du Colombier 
3503e12c5d1SDavid du Colombier /*
3513e12c5d1SDavid du Colombier  * in olden times, it used to ignore changes to 0 or negative.
3523e12c5d1SDavid du Colombier  * this is meant to allow the requested size to be anything,
3533e12c5d1SDavid du Colombier  * in particular so eqn can generate lots of \s-3's and still
3543e12c5d1SDavid du Colombier  * get back by matching \s+3's.
3553e12c5d1SDavid du Colombier 
3563e12c5d1SDavid du Colombier 	if (i <= 0)
3573e12c5d1SDavid du Colombier 		return;
3583e12c5d1SDavid du Colombier */
3593e12c5d1SDavid du Colombier 	apts1 = apts;
3603e12c5d1SDavid du Colombier 	apts = i;
3613e12c5d1SDavid du Colombier 	pts1 = pts;
3623e12c5d1SDavid du Colombier 	pts = findps(i);
3633e12c5d1SDavid du Colombier 	mchbits();
3643e12c5d1SDavid du Colombier }
3653e12c5d1SDavid du Colombier 
3663e12c5d1SDavid du Colombier 
findps(int i)3673e12c5d1SDavid du Colombier findps(int i)
3683e12c5d1SDavid du Colombier {
3693e12c5d1SDavid du Colombier 	int j, k;
3703e12c5d1SDavid du Colombier 
3713e12c5d1SDavid du Colombier 	for (j=k=0 ; pstab[j] != 0 ; j++)
3723e12c5d1SDavid du Colombier 		if (abs(pstab[j]-i) < abs(pstab[k]-i))
3733e12c5d1SDavid du Colombier 			k = j;
3743e12c5d1SDavid du Colombier 
3753e12c5d1SDavid du Colombier 	return(pstab[k]);
3763e12c5d1SDavid du Colombier }
3773e12c5d1SDavid du Colombier 
3783e12c5d1SDavid du Colombier 
t_mchbits(void)3793e12c5d1SDavid du Colombier void t_mchbits(void)
3803e12c5d1SDavid du Colombier {
3813e12c5d1SDavid du Colombier 	int i, j, k;
3823e12c5d1SDavid du Colombier 
3833e12c5d1SDavid du Colombier 	i = pts;
3843e12c5d1SDavid du Colombier 	for (j = 0; i > (k = pstab[j]); j++)
3853e12c5d1SDavid du Colombier 		if (!k) {
3863e12c5d1SDavid du Colombier 			j--;
3873e12c5d1SDavid du Colombier 			break;
3883e12c5d1SDavid du Colombier 		}
3893e12c5d1SDavid du Colombier 	chbits = 0;
3903e12c5d1SDavid du Colombier 	setsbits(chbits, ++j);
3913e12c5d1SDavid du Colombier 	setfbits(chbits, font);
3923e12c5d1SDavid du Colombier 	sps = width(' ' | chbits);
3933e12c5d1SDavid du Colombier 	zapwcache(1);
3943e12c5d1SDavid du Colombier }
3953e12c5d1SDavid du Colombier 
t_setps(void)3963e12c5d1SDavid du Colombier void t_setps(void)
3973e12c5d1SDavid du Colombier {
3983e12c5d1SDavid du Colombier 	int i, j;
3993e12c5d1SDavid du Colombier 
4003e12c5d1SDavid du Colombier 	i = cbits(getch());
401*14f51593SDavid du Colombier 	j = i;				/* make compiler happy */
4023e12c5d1SDavid du Colombier 	if (isdigit(i)) {		/* \sd or \sdd */
4033e12c5d1SDavid du Colombier 		i -= '0';
4043e12c5d1SDavid du Colombier 		if (i == 0)		/* \s0 */
4053e12c5d1SDavid du Colombier 			j = apts1;
406219b2ee8SDavid du Colombier 		else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) {	/* \sdd */
4073e12c5d1SDavid du Colombier 			j = 10 * i + j - '0';
4083e12c5d1SDavid du Colombier 			ch = 0;
4093e12c5d1SDavid du Colombier 		} else		/* \sd */
4103e12c5d1SDavid du Colombier 			j = i;
4113e12c5d1SDavid du Colombier 	} else if (i == '(') {		/* \s(dd */
4123e12c5d1SDavid du Colombier 		j = cbits(getch()) - '0';
4133e12c5d1SDavid du Colombier 		j = 10 * j + cbits(getch()) - '0';
4143e12c5d1SDavid du Colombier 		if (j == 0)		/* \s(00 */
4153e12c5d1SDavid du Colombier 			j = apts1;
4163e12c5d1SDavid du Colombier 	} else if (i == '+' || i == '-') {	/* \s+, \s- */
4173e12c5d1SDavid du Colombier 		j = cbits(getch());
4183e12c5d1SDavid du Colombier 		if (isdigit(j)) {		/* \s+d, \s-d */
4193e12c5d1SDavid du Colombier 			j -= '0';
4203e12c5d1SDavid du Colombier 		} else if (j == '(') {		/* \s+(dd, \s-(dd */
4213e12c5d1SDavid du Colombier 			j = cbits(getch()) - '0';
4223e12c5d1SDavid du Colombier 			j = 10 * j + cbits(getch()) - '0';
4233e12c5d1SDavid du Colombier 		}
4243e12c5d1SDavid du Colombier 		if (i == '-')
4253e12c5d1SDavid du Colombier 			j = -j;
4263e12c5d1SDavid du Colombier 		j += apts;
4273e12c5d1SDavid du Colombier 	}
4283e12c5d1SDavid du Colombier 	casps1(j);
4293e12c5d1SDavid du Colombier }
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier 
t_setht(void)4323e12c5d1SDavid du Colombier Tchar t_setht(void)		/* set character height from \H'...' */
4333e12c5d1SDavid du Colombier {
4343e12c5d1SDavid du Colombier 	int n;
4353e12c5d1SDavid du Colombier 	Tchar c;
4363e12c5d1SDavid du Colombier 
4373e12c5d1SDavid du Colombier 	getch();
4383e12c5d1SDavid du Colombier 	n = inumb(&apts);
4393e12c5d1SDavid du Colombier 	getch();
4403e12c5d1SDavid du Colombier 	if (n == 0 || nonumb)
4413e12c5d1SDavid du Colombier 		n = apts;	/* does this work? */
4423e12c5d1SDavid du Colombier 	c = CHARHT;
4433e12c5d1SDavid du Colombier 	c |= ZBIT;
4443e12c5d1SDavid du Colombier 	setsbits(c, n);
445219b2ee8SDavid du Colombier 	setfbits(c, pts);	/* sneaky, CHARHT font bits are size bits */
4463e12c5d1SDavid du Colombier 	return(c);
4473e12c5d1SDavid du Colombier }
4483e12c5d1SDavid du Colombier 
t_setslant(void)4493e12c5d1SDavid du Colombier Tchar t_setslant(void)		/* set slant from \S'...' */
4503e12c5d1SDavid du Colombier {
4513e12c5d1SDavid du Colombier 	int n;
4523e12c5d1SDavid du Colombier 	Tchar c;
4533e12c5d1SDavid du Colombier 
4543e12c5d1SDavid du Colombier 	getch();
4553e12c5d1SDavid du Colombier 	n = 0;
4563e12c5d1SDavid du Colombier 	n = inumb(&n);
4573e12c5d1SDavid du Colombier 	getch();
4583e12c5d1SDavid du Colombier 	if (nonumb)
4593e12c5d1SDavid du Colombier 		n = 0;
4603e12c5d1SDavid du Colombier 	c = SLANT;
4613e12c5d1SDavid du Colombier 	c |= ZBIT;
4623e12c5d1SDavid du Colombier 	setsfbits(c, n+180);
4633e12c5d1SDavid du Colombier 	return(c);
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier 
4663e12c5d1SDavid du Colombier 
caseft(void)4673e12c5d1SDavid du Colombier void caseft(void)
4683e12c5d1SDavid du Colombier {
4693e12c5d1SDavid du Colombier 	if (!TROFF) {
4703e12c5d1SDavid du Colombier 		n_caseft();
4713e12c5d1SDavid du Colombier 		return;
4723e12c5d1SDavid du Colombier 	}
4733e12c5d1SDavid du Colombier 	skip();
4743e12c5d1SDavid du Colombier 	setfont(1);
4753e12c5d1SDavid du Colombier }
4763e12c5d1SDavid du Colombier 
4773e12c5d1SDavid du Colombier 
t_setfont(int a)4783e12c5d1SDavid du Colombier void t_setfont(int a)
4793e12c5d1SDavid du Colombier {
4803e12c5d1SDavid du Colombier 	int i, j;
4813e12c5d1SDavid du Colombier 
4823e12c5d1SDavid du Colombier 	if (a)
4833e12c5d1SDavid du Colombier 		i = getrq();
4843e12c5d1SDavid du Colombier 	else
4853e12c5d1SDavid du Colombier 		i = getsn();
4863e12c5d1SDavid du Colombier 	if (!i || i == 'P') {
4873e12c5d1SDavid du Colombier 		j = font1;
4883e12c5d1SDavid du Colombier 		goto s0;
4893e12c5d1SDavid du Colombier 	}
4903e12c5d1SDavid du Colombier 	if (/* i == 'S' || */ i == '0')	/* an experiment -- why can't we change to it? */
4913e12c5d1SDavid du Colombier 		return;
4923e12c5d1SDavid du Colombier 	if ((j = findft(i)) == -1)
4933e12c5d1SDavid du Colombier 		if ((j = setfp(0, i, (char*) 0, 1)) == -1)	/* try to put it in position 0 */
4943e12c5d1SDavid du Colombier 			return;
4953e12c5d1SDavid du Colombier s0:
4963e12c5d1SDavid du Colombier 	font1 = font;
4973e12c5d1SDavid du Colombier 	font = j;
4983e12c5d1SDavid du Colombier 	mchbits();
4993e12c5d1SDavid du Colombier }
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 
t_setwd(void)5023e12c5d1SDavid du Colombier void t_setwd(void)
5033e12c5d1SDavid du Colombier {
5043e12c5d1SDavid du Colombier 	int base, wid;
5053e12c5d1SDavid du Colombier 	Tchar i;
5063e12c5d1SDavid du Colombier 	int delim, emsz, k;
5073e12c5d1SDavid du Colombier 	int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
5083e12c5d1SDavid du Colombier 
509219b2ee8SDavid du Colombier 	base = numtabp[ST].val = numtabp[SB].val = wid = numtabp[CT].val = 0;
5103e12c5d1SDavid du Colombier 	if (ismot(i = getch()))
5113e12c5d1SDavid du Colombier 		return;
5123e12c5d1SDavid du Colombier 	delim = cbits(i);
513219b2ee8SDavid du Colombier 	savhp = numtabp[HP].val;
514219b2ee8SDavid du Colombier 	numtabp[HP].val = 0;
5153e12c5d1SDavid du Colombier 	savapts = apts;
5163e12c5d1SDavid du Colombier 	savapts1 = apts1;
5173e12c5d1SDavid du Colombier 	savfont = font;
5183e12c5d1SDavid du Colombier 	savfont1 = font1;
5193e12c5d1SDavid du Colombier 	savpts = pts;
5203e12c5d1SDavid du Colombier 	savpts1 = pts1;
5213e12c5d1SDavid du Colombier 	setwdf++;
5223e12c5d1SDavid du Colombier 	while (cbits(i = getch()) != delim && !nlflg) {
5233e12c5d1SDavid du Colombier 		k = width(i);
5243e12c5d1SDavid du Colombier 		wid += k;
525219b2ee8SDavid du Colombier 		numtabp[HP].val += k;
5263e12c5d1SDavid du Colombier 		if (!ismot(i)) {
5273e12c5d1SDavid du Colombier 			emsz = (INCH/72) * xpts;
5283e12c5d1SDavid du Colombier 		} else if (isvmot(i)) {
5293e12c5d1SDavid du Colombier 			k = absmot(i);
5303e12c5d1SDavid du Colombier 			if (isnmot(i))
5313e12c5d1SDavid du Colombier 				k = -k;
5323e12c5d1SDavid du Colombier 			base -= k;
5333e12c5d1SDavid du Colombier 			emsz = 0;
5343e12c5d1SDavid du Colombier 		} else
5353e12c5d1SDavid du Colombier 			continue;
536219b2ee8SDavid du Colombier 		if (base < numtabp[SB].val)
537219b2ee8SDavid du Colombier 			numtabp[SB].val = base;
538219b2ee8SDavid du Colombier 		if ((k = base + emsz) > numtabp[ST].val)
539219b2ee8SDavid du Colombier 			numtabp[ST].val = k;
5403e12c5d1SDavid du Colombier 	}
5413e12c5d1SDavid du Colombier 	setn1(wid, 0, (Tchar) 0);
542219b2ee8SDavid du Colombier 	numtabp[HP].val = savhp;
5433e12c5d1SDavid du Colombier 	apts = savapts;
5443e12c5d1SDavid du Colombier 	apts1 = savapts1;
5453e12c5d1SDavid du Colombier 	font = savfont;
5463e12c5d1SDavid du Colombier 	font1 = savfont1;
5473e12c5d1SDavid du Colombier 	pts = savpts;
5483e12c5d1SDavid du Colombier 	pts1 = savpts1;
5493e12c5d1SDavid du Colombier 	mchbits();
5503e12c5d1SDavid du Colombier 	setwdf = 0;
5513e12c5d1SDavid du Colombier }
5523e12c5d1SDavid du Colombier 
5533e12c5d1SDavid du Colombier 
t_vmot(void)5543e12c5d1SDavid du Colombier Tchar t_vmot(void)
5553e12c5d1SDavid du Colombier {
5563e12c5d1SDavid du Colombier 	dfact = lss;
5573e12c5d1SDavid du Colombier 	vflag++;
5583e12c5d1SDavid du Colombier 	return t_mot();
5593e12c5d1SDavid du Colombier }
5603e12c5d1SDavid du Colombier 
5613e12c5d1SDavid du Colombier 
t_hmot(void)5623e12c5d1SDavid du Colombier Tchar t_hmot(void)
5633e12c5d1SDavid du Colombier {
5643e12c5d1SDavid du Colombier 	dfact = EM;
5653e12c5d1SDavid du Colombier 	return t_mot();
5663e12c5d1SDavid du Colombier }
5673e12c5d1SDavid du Colombier 
5683e12c5d1SDavid du Colombier 
t_mot(void)5693e12c5d1SDavid du Colombier Tchar t_mot(void)
5703e12c5d1SDavid du Colombier {
5713e12c5d1SDavid du Colombier 	int j, n;
5723e12c5d1SDavid du Colombier 	Tchar i;
5733e12c5d1SDavid du Colombier 
5743e12c5d1SDavid du Colombier 	j = HOR;
5753e12c5d1SDavid du Colombier 	getch(); /*eat delim*/
5763e12c5d1SDavid du Colombier 	if (n = atoi0()) {
5773e12c5d1SDavid du Colombier 		if (vflag)
5783e12c5d1SDavid du Colombier 			j = VERT;
5793e12c5d1SDavid du Colombier 		i = makem(quant(n, j));
5803e12c5d1SDavid du Colombier 	} else
5813e12c5d1SDavid du Colombier 		i = 0;
5823e12c5d1SDavid du Colombier 	getch();
5833e12c5d1SDavid du Colombier 	vflag = 0;
5843e12c5d1SDavid du Colombier 	dfact = 1;
5853e12c5d1SDavid du Colombier 	return(i);
5863e12c5d1SDavid du Colombier }
5873e12c5d1SDavid du Colombier 
5883e12c5d1SDavid du Colombier 
t_sethl(int k)5893e12c5d1SDavid du Colombier Tchar t_sethl(int k)
5903e12c5d1SDavid du Colombier {
5913e12c5d1SDavid du Colombier 	int j;
5923e12c5d1SDavid du Colombier 	Tchar i;
5933e12c5d1SDavid du Colombier 
5943e12c5d1SDavid du Colombier 	j = EM / 2;
5953e12c5d1SDavid du Colombier 	if (k == 'u')
5963e12c5d1SDavid du Colombier 		j = -j;
5973e12c5d1SDavid du Colombier 	else if (k == 'r')
5983e12c5d1SDavid du Colombier 		j = -2 * j;
5993e12c5d1SDavid du Colombier 	vflag++;
6003e12c5d1SDavid du Colombier 	i = makem(j);
6013e12c5d1SDavid du Colombier 	vflag = 0;
6023e12c5d1SDavid du Colombier 	return(i);
6033e12c5d1SDavid du Colombier }
6043e12c5d1SDavid du Colombier 
6053e12c5d1SDavid du Colombier 
t_makem(int i)6063e12c5d1SDavid du Colombier Tchar t_makem(int i)
6073e12c5d1SDavid du Colombier {
6083e12c5d1SDavid du Colombier 	Tchar j;
6093e12c5d1SDavid du Colombier 
6103e12c5d1SDavid du Colombier 	if (i >= 0)
6113e12c5d1SDavid du Colombier 		j = i;
6123e12c5d1SDavid du Colombier 	else
6133e12c5d1SDavid du Colombier 		j = -i;
6143e12c5d1SDavid du Colombier 	if (Hor > 1 && !vflag)
6153e12c5d1SDavid du Colombier 		j = (j + Hor/2)/Hor * Hor;
6163e12c5d1SDavid du Colombier 	j |= MOT;
6173e12c5d1SDavid du Colombier 	if (i < 0)
6183e12c5d1SDavid du Colombier 		j |= NMOT;
6193e12c5d1SDavid du Colombier 	if (vflag)
6203e12c5d1SDavid du Colombier 		j |= VMOT;
6213e12c5d1SDavid du Colombier 	return(j);
6223e12c5d1SDavid du Colombier }
6233e12c5d1SDavid du Colombier 
6243e12c5d1SDavid du Colombier 
getlg(Tchar i)6253e12c5d1SDavid du Colombier Tchar getlg(Tchar i)
6263e12c5d1SDavid du Colombier {
6273e12c5d1SDavid du Colombier 	Tchar j, k;
6283e12c5d1SDavid du Colombier 	int lf;
6293e12c5d1SDavid du Colombier 
6303e12c5d1SDavid du Colombier 	if (!TROFF)
6313e12c5d1SDavid du Colombier 		return i;
6323e12c5d1SDavid du Colombier 	if ((lf = fonts[fbits(i)].ligfont) == 0) /* font lacks ligatures */
6333e12c5d1SDavid du Colombier 		return(i);
6343e12c5d1SDavid du Colombier 	j = getch0();
6353e12c5d1SDavid du Colombier 	if (cbits(j) == 'i' && (lf & LFI))
6363e12c5d1SDavid du Colombier 		j = LIG_FI;
6373e12c5d1SDavid du Colombier 	else if (cbits(j) == 'l' && (lf & LFL))
6383e12c5d1SDavid du Colombier 		j = LIG_FL;
6393e12c5d1SDavid du Colombier 	else if (cbits(j) == 'f' && (lf & LFF)) {
6403e12c5d1SDavid du Colombier 		if ((lf & (LFFI|LFFL)) && lg != 2) {
6413e12c5d1SDavid du Colombier 			k = getch0();
6423e12c5d1SDavid du Colombier 			if (cbits(k)=='i' && (lf&LFFI))
6433e12c5d1SDavid du Colombier 				j = LIG_FFI;
6443e12c5d1SDavid du Colombier 			else if (cbits(k)=='l' && (lf&LFFL))
6453e12c5d1SDavid du Colombier 				j = LIG_FFL;
6463e12c5d1SDavid du Colombier 			else {
6473e12c5d1SDavid du Colombier 				*pbp++ = k;
6483e12c5d1SDavid du Colombier 				j = LIG_FF;
6493e12c5d1SDavid du Colombier 			}
6503e12c5d1SDavid du Colombier 		} else
6513e12c5d1SDavid du Colombier 			j = LIG_FF;
6523e12c5d1SDavid du Colombier 	} else {
6533e12c5d1SDavid du Colombier 		*pbp++ = j;
6543e12c5d1SDavid du Colombier 		j = i;
6553e12c5d1SDavid du Colombier 	}
6563e12c5d1SDavid du Colombier 	return(i & SFMASK | j);
6573e12c5d1SDavid du Colombier }
6583e12c5d1SDavid du Colombier 
6593e12c5d1SDavid du Colombier 
caselg(void)6603e12c5d1SDavid du Colombier void caselg(void)
6613e12c5d1SDavid du Colombier {
6623e12c5d1SDavid du Colombier 
6633e12c5d1SDavid du Colombier 	if(TROFF) {
664219b2ee8SDavid du Colombier 		skip();
6653e12c5d1SDavid du Colombier 		lg = atoi0();
666219b2ee8SDavid du Colombier 		if (nonumb)
667219b2ee8SDavid du Colombier 			lg = 1;
6683e12c5d1SDavid du Colombier 	}
6693e12c5d1SDavid du Colombier }
6703e12c5d1SDavid du Colombier 
casefp(void)6713e12c5d1SDavid du Colombier void casefp(void)
6723e12c5d1SDavid du Colombier {
6733e12c5d1SDavid du Colombier 	int i, j;
6743e12c5d1SDavid du Colombier 
6753e12c5d1SDavid du Colombier 	if (!TROFF) {
6763e12c5d1SDavid du Colombier 		n_casefp();
6773e12c5d1SDavid du Colombier 		return;
6783e12c5d1SDavid du Colombier 	}
6793e12c5d1SDavid du Colombier 	skip();
6803e12c5d1SDavid du Colombier 	i = cbits(getch());
6813e12c5d1SDavid du Colombier 	if (isdigit(i)) {
6823e12c5d1SDavid du Colombier 		i -= '0';
6833e12c5d1SDavid du Colombier 		j = cbits(getch());
6843e12c5d1SDavid du Colombier 		if (isdigit(j))
6853e12c5d1SDavid du Colombier 			i = 10 * i + j - '0';
6863e12c5d1SDavid du Colombier 	}
6873e12c5d1SDavid du Colombier 	if (i <= 0 || i > nfonts)
6883e12c5d1SDavid du Colombier 		ERROR "fp: bad font position %d", i WARN;
6893e12c5d1SDavid du Colombier 	else if (skip() || !(j = getrq()))
6903e12c5d1SDavid du Colombier 		ERROR "fp: no font name" WARN;
6913e12c5d1SDavid du Colombier 	else if (skip() || !getname())
6923e12c5d1SDavid du Colombier 		setfp(i, j, (char*) 0, 1);
6933e12c5d1SDavid du Colombier 	else		/* 3rd argument = filename */
6943e12c5d1SDavid du Colombier 		setfp(i, j, nextf, 1);
6953e12c5d1SDavid du Colombier }
6963e12c5d1SDavid du Colombier 
strdupl(const char * s)697219b2ee8SDavid du Colombier char *strdupl(const char *s)	/* make a copy of s */
6983e12c5d1SDavid du Colombier {
6993e12c5d1SDavid du Colombier 	char *t;
7003e12c5d1SDavid du Colombier 
7013e12c5d1SDavid du Colombier 	t = (char *) malloc(strlen(s) + 1);
7023e12c5d1SDavid du Colombier 	if (t == NULL)
703219b2ee8SDavid du Colombier 		ERROR "out of space in strdupl(%s)", s FATAL;
7043e12c5d1SDavid du Colombier 	strcpy(t, s);
7053e12c5d1SDavid du Colombier 	return t;
7063e12c5d1SDavid du Colombier }
7073e12c5d1SDavid du Colombier 
setfp(int pos,int f,char * truename,int print)7083e12c5d1SDavid du Colombier setfp(int pos, int f, char *truename, int print)	/* mount font f at position pos[0...nfonts] */
7093e12c5d1SDavid du Colombier {
710*14f51593SDavid du Colombier 	char pathname[NS], shortname[NS];
7113e12c5d1SDavid du Colombier 
7123e12c5d1SDavid du Colombier 	zapwcache(0);
7133e12c5d1SDavid du Colombier 	if (truename)
7143e12c5d1SDavid du Colombier 		strcpy(shortname, truename);
7153e12c5d1SDavid du Colombier 	else
716219b2ee8SDavid du Colombier 		strcpy(shortname, (char *) unpair(f));
7173e12c5d1SDavid du Colombier 	if (truename && strrchr(truename, '/')) {	/* .fp 1 R dir/file: use verbatim */
7183e12c5d1SDavid du Colombier 		sprintf(pathname, "%s", truename);
7193e12c5d1SDavid du Colombier 		if (fonts[pos].truename)
7203e12c5d1SDavid du Colombier 			free(fonts[pos].truename);
721219b2ee8SDavid du Colombier 		fonts[pos].truename = strdupl(truename);
7223e12c5d1SDavid du Colombier 	} else if (truename) {			/* synonym: .fp 1 R Avant */
7233e12c5d1SDavid du Colombier 		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, truename);
7243e12c5d1SDavid du Colombier 		truename = 0;	/* so doesn't get repeated by ptfpcmd */
7253e12c5d1SDavid du Colombier 	} else					/* vanilla: .fp 5 XX */
7263e12c5d1SDavid du Colombier 		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, shortname);
7273e12c5d1SDavid du Colombier 	if (truename == 0 && fonts[pos].truename != 0) {
7283e12c5d1SDavid du Colombier 		free(fonts[pos].truename);
7293e12c5d1SDavid du Colombier 		fonts[pos].truename = 0;
7303e12c5d1SDavid du Colombier 	}
7313e12c5d1SDavid du Colombier 	if (getfont(pathname, pos) < 0) {
7323e12c5d1SDavid du Colombier 		ERROR "Can't open font file %s", pathname WARN;
7333e12c5d1SDavid du Colombier 		return -1;
7343e12c5d1SDavid du Colombier 	}
7353e12c5d1SDavid du Colombier 	if (print && !ascii) {
7363e12c5d1SDavid du Colombier 		ptfpcmd(pos, fonts[pos].longname, truename);
7373e12c5d1SDavid du Colombier 		ptfont();
7383e12c5d1SDavid du Colombier 	}
7393e12c5d1SDavid du Colombier 	if (pos == smnt) {
7403e12c5d1SDavid du Colombier 		smnt = 0;
7413e12c5d1SDavid du Colombier 		sbold = 0;
7423e12c5d1SDavid du Colombier 	}
7433e12c5d1SDavid du Colombier 	fontlab[pos] = f;
7443e12c5d1SDavid du Colombier 	if (smnt == 0 && fonts[pos].specfont)
7453e12c5d1SDavid du Colombier 		smnt = pos;
7463e12c5d1SDavid du Colombier 	bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
7473e12c5d1SDavid du Colombier 	return pos;
7483e12c5d1SDavid du Colombier }
7493e12c5d1SDavid du Colombier 
750219b2ee8SDavid du Colombier /*
751219b2ee8SDavid du Colombier  * .cs request; don't check legality of optional arguments
752219b2ee8SDavid du Colombier  */
casecs(void)7533e12c5d1SDavid du Colombier void casecs(void)
7543e12c5d1SDavid du Colombier {
7553e12c5d1SDavid du Colombier 	int i, j;
7563e12c5d1SDavid du Colombier 
7573e12c5d1SDavid du Colombier 	if (TROFF) {
758219b2ee8SDavid du Colombier 		int savtr = trace;
759219b2ee8SDavid du Colombier 
760219b2ee8SDavid du Colombier 		trace = 0;
7613e12c5d1SDavid du Colombier 		noscale++;
7623e12c5d1SDavid du Colombier 		skip();
7633e12c5d1SDavid du Colombier 		if (!(i = getrq()) || (i = findft(i)) < 0)
7643e12c5d1SDavid du Colombier 			goto rtn;
7653e12c5d1SDavid du Colombier 		skip();
7663e12c5d1SDavid du Colombier 		cstab[i] = atoi0();
7673e12c5d1SDavid du Colombier 		skip();
7683e12c5d1SDavid du Colombier 		j = atoi0();
7693e12c5d1SDavid du Colombier 		if(nonumb)
7703e12c5d1SDavid du Colombier 			ccstab[i] = 0;
7713e12c5d1SDavid du Colombier 		else
7723e12c5d1SDavid du Colombier 			ccstab[i] = findps(j);
7733e12c5d1SDavid du Colombier 	rtn:
7743e12c5d1SDavid du Colombier 		zapwcache(0);
7753e12c5d1SDavid du Colombier 		noscale = 0;
776219b2ee8SDavid du Colombier 		trace = savtr;
7773e12c5d1SDavid du Colombier 	}
7783e12c5d1SDavid du Colombier }
7793e12c5d1SDavid du Colombier 
7803e12c5d1SDavid du Colombier 
casebd(void)7813e12c5d1SDavid du Colombier void casebd(void)
7823e12c5d1SDavid du Colombier {
7833e12c5d1SDavid du Colombier 	int i, j, k;
7843e12c5d1SDavid du Colombier 
7853e12c5d1SDavid du Colombier 	if (!TROFF) {
7863e12c5d1SDavid du Colombier 		n_casebd();
7873e12c5d1SDavid du Colombier 		return;
7883e12c5d1SDavid du Colombier 	}
7893e12c5d1SDavid du Colombier 	zapwcache(0);
790*14f51593SDavid du Colombier 	j = k = 0;
7913e12c5d1SDavid du Colombier bd0:
7923e12c5d1SDavid du Colombier 	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
7933e12c5d1SDavid du Colombier 		if (k)
7943e12c5d1SDavid du Colombier 			goto bd1;
7953e12c5d1SDavid du Colombier 		else
7963e12c5d1SDavid du Colombier 			return;
7973e12c5d1SDavid du Colombier 	}
7983e12c5d1SDavid du Colombier 	if (j == smnt) {
7993e12c5d1SDavid du Colombier 		k = smnt;
8003e12c5d1SDavid du Colombier 		goto bd0;
8013e12c5d1SDavid du Colombier 	}
8023e12c5d1SDavid du Colombier 	if (k) {
8033e12c5d1SDavid du Colombier 		sbold = j;
8043e12c5d1SDavid du Colombier 		j = k;
8053e12c5d1SDavid du Colombier 	}
8063e12c5d1SDavid du Colombier bd1:
8073e12c5d1SDavid du Colombier 	skip();
8083e12c5d1SDavid du Colombier 	noscale++;
8093e12c5d1SDavid du Colombier 	bdtab[j] = atoi0();
8103e12c5d1SDavid du Colombier 	noscale = 0;
8113e12c5d1SDavid du Colombier }
8123e12c5d1SDavid du Colombier 
8133e12c5d1SDavid du Colombier 
casevs(void)8143e12c5d1SDavid du Colombier void casevs(void)
8153e12c5d1SDavid du Colombier {
8163e12c5d1SDavid du Colombier 	int i;
8173e12c5d1SDavid du Colombier 
8183e12c5d1SDavid du Colombier 	if (!TROFF) {
8193e12c5d1SDavid du Colombier 		n_casevs();
8203e12c5d1SDavid du Colombier 		return;
8213e12c5d1SDavid du Colombier 	}
8223e12c5d1SDavid du Colombier 	skip();
8233e12c5d1SDavid du Colombier 	vflag++;
8243e12c5d1SDavid du Colombier 	dfact = INCH; /* default scaling is points! */
8253e12c5d1SDavid du Colombier 	dfactd = 72;
8263e12c5d1SDavid du Colombier 	res = VERT;
8273e12c5d1SDavid du Colombier 	i = inumb(&lss);
8283e12c5d1SDavid du Colombier 	if (nonumb)
8293e12c5d1SDavid du Colombier 		i = lss1;
8303e12c5d1SDavid du Colombier 	if (i < VERT)
8313e12c5d1SDavid du Colombier 		i = VERT;
8323e12c5d1SDavid du Colombier 	lss1 = lss;
8333e12c5d1SDavid du Colombier 	lss = i;
8343e12c5d1SDavid du Colombier }
8353e12c5d1SDavid du Colombier 
8363e12c5d1SDavid du Colombier 
casess(void)8373e12c5d1SDavid du Colombier void casess(void)
8383e12c5d1SDavid du Colombier {
8393e12c5d1SDavid du Colombier 	int i;
8403e12c5d1SDavid du Colombier 
8413e12c5d1SDavid du Colombier 	if(TROFF) {
8423e12c5d1SDavid du Colombier 		noscale++;
8433e12c5d1SDavid du Colombier 		skip();
8443e12c5d1SDavid du Colombier 		if(i = atoi0()) {
8453e12c5d1SDavid du Colombier 			spacesz = i & 0177;
8463e12c5d1SDavid du Colombier 			zapwcache(0);
8473e12c5d1SDavid du Colombier 			sps = width(' ' | chbits);
8483e12c5d1SDavid du Colombier 		}
8493e12c5d1SDavid du Colombier 		noscale = 0;
8503e12c5d1SDavid du Colombier 	}
8513e12c5d1SDavid du Colombier }
8523e12c5d1SDavid du Colombier 
8533e12c5d1SDavid du Colombier 
t_xlss(void)8543e12c5d1SDavid du Colombier Tchar t_xlss(void)
8553e12c5d1SDavid du Colombier {
8563e12c5d1SDavid du Colombier 	/* stores \x'...' into two successive Tchars.
8573e12c5d1SDavid du Colombier 	/* the first contains HX, the second the value,
8583e12c5d1SDavid du Colombier 	/* encoded as a vertical motion.
8593e12c5d1SDavid du Colombier 	/* decoding is done in n2.c by pchar().
8603e12c5d1SDavid du Colombier 	*/
8613e12c5d1SDavid du Colombier 	int i;
8623e12c5d1SDavid du Colombier 
8633e12c5d1SDavid du Colombier 	getch();
8643e12c5d1SDavid du Colombier 	dfact = lss;
8653e12c5d1SDavid du Colombier 	i = quant(atoi0(), VERT);
8663e12c5d1SDavid du Colombier 	dfact = 1;
8673e12c5d1SDavid du Colombier 	getch();
8683e12c5d1SDavid du Colombier 	if (i >= 0)
8693e12c5d1SDavid du Colombier 		*pbp++ = MOT | VMOT | i;
8703e12c5d1SDavid du Colombier 	else
8713e12c5d1SDavid du Colombier 		*pbp++ = MOT | VMOT | NMOT | -i;
8723e12c5d1SDavid du Colombier 	return(HX);
8733e12c5d1SDavid du Colombier }
8743e12c5d1SDavid du Colombier 
unpair(int i)875219b2ee8SDavid du Colombier Uchar *unpair(int i)
8763e12c5d1SDavid du Colombier {
877219b2ee8SDavid du Colombier 	static Uchar name[3];
8783e12c5d1SDavid du Colombier 
879219b2ee8SDavid du Colombier 	name[0] = i & SHORTMASK;
880219b2ee8SDavid du Colombier 	name[1] = (i >> SHORT) & SHORTMASK;
8813e12c5d1SDavid du Colombier 	name[2] = 0;
882219b2ee8SDavid du Colombier 	return name;
8833e12c5d1SDavid du Colombier }
884