/*
 * t6.c
 * 
 * width functions, sizes and fonts
 */

#include "tdef.h"
#include "fns.h"
#include "ext.h"

int	fontlab[MAXFONTS+1];
int	cstab[MAXFONTS+1];
int	ccstab[MAXFONTS+1];
int	bdtab[MAXFONTS+1];
int	sbold = 0;

int
t_width(Tchar j)
{
	int i, k;

	if (iszbit(j))
		return 0;
	if (ismot(j)) {
		if (isvmot(j))
			return(0);
		k = absmot(j);
		if (isnmot(j))
			k = -k;
		return(k);
	}
	i = cbits(j);
	if (i < ' ') {
		if (i == '\b')
			return(-widthp);
		if (i == PRESC)
			i = eschar;
		else if (i == HX)
			return(0);
	}
	if (i == ohc)
		return(0);
	i = trtab[i];
	if (i < ' ')
		return(0);
	if (sfbits(j) == oldbits) {
		xfont = pfont;
		xpts = ppts;
	} else 
		xbits(j, 0);
	if (i < nchnames + ALPHABET && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf)
		k = widcache[i].width;
	else {
		k = getcw(i);
		if (bd)
			k += (bd - 1) * HOR;
		if (cs)
			k = cs;
	}
	widthp = k;
	return(k);
}

/*
 * clear width cache-- s means just space
 */
void zapwcache(int s)
{
	int i;

	if (s) {
		widcache[' '].fontpts = 0;
		return;
	}
	for (i=0; i<NWIDCACHE; i++)
		widcache[i].fontpts = 0;
}

int
onfont(int n, int f)	/* is char n on font f? */
{
	int i;
	Font *fp = &fonts[f];
	Chwid *cp, *ep;
	char *np;

	if (n < ALPHABET) {
		if (fp->wp[n].num == n)	/* ascii at front */
			return n;
		else
			return -1;
	}
	cp = &fp->wp[ALPHABET];
	ep = &fp->wp[fp->nchars];
	for ( ; cp < ep; cp++)	/* search others */
		if (cp->num == n)
			return cp - &fp->wp[0];
	/* maybe it was a \N... */
	np = chname(n);
	if (*np == Number) {
		i = atoi(np+1);		/* sscanf(np+1, "%d", &i); */
		cp = &fp->wp[0];
		ep = &fp->wp[fp->nchars];
		for ( ; cp < ep; cp++) {	/* search others */
			if (cp->code == i)
				return cp - &fp->wp[0];
		}
		return -2;	/* a \N that doesn't have an entry */
	}
	return -1;	/* vanilla not found */
}

int
getcw(int i)
{
	int k, n, x;
	Font *fp;
	int nocache = 0;
	if (i < ' ')
		return 0;
	bd = 0;
	fp = &fonts[xfont];
	if (i == ' ') {	/* a blank */
		k = (fp->spacewidth * spacesz + 6) / 12;
		/* this nonsense because .ss cmd uses 1/36 em as its units */
		/* 	and default is 12 */
	} else if ((n = onfont(i, xfont)) >= 0) {	/* on this font at n */
		k = fp->wp[n].wid;
		if (setwdf)
			numtabp[CT].val |= fp->wp[n].kern;
	} else if (n == -2) {		/* \N with default width */
		
		k = fp->defaultwidth;
	} else {			/* not on current font */
		nocache = 1;
		k = fp->defaultwidth;	/* default-size space */
		if (smnt) {
			int ii, jj;
			for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
				if ((n = onfont(i, ii)) >= 0) {
					k = fonts[ii].wp[n].wid;
					if (xfont == sbold)
						bd = bdtab[ii];
					if (setwdf)
						numtabp[CT].val |= fonts[ii].wp[n].kern;
					break;
				}
			}
		}
	}
	if (!bd)
		bd = bdtab[xfont];
	if (cs = cstab[xfont]) {
		nocache = 1;
		if (ccs = ccstab[xfont])
			x = ccs; 
		else 
			x = xpts;
		cs = (cs * EMPTS(x)) / 36;
	}
	/* was (k & BYTEMASK);  since .wid is unsigned, should never happen */
	if (k < 0)
		ERROR "can't happen: negative width %d in getcw %d\n", k, i WARN;
	k = (k * xpts + (Unitwidth / 2)) / Unitwidth;
	if (nocache|bd)
		widcache[i].fontpts = 0;
	else {
		widcache[i].fontpts = (xfont<<8) + xpts;
		widcache[i].width = k;
	}
	return(k);
	/* Unitwidth is Units/Point, where
	/* Units is the fundamental digitization
	/* of the character set widths, and
	/* Point is the number of goobies in a point
	/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
	/* In effect, it's the size at which the widths
	/* translate directly into units.
	*/
}

void xbits(Tchar i, int bitf)
{
	int k;

	if(TROFF) {
		xfont = fbits(i);
		k = sbits(i);
		if(k) {
			xpts = pstab[k-1];
			oldbits = sfbits(i);
			pfont = xfont;
			ppts = xpts;
			return;
		}
		switch(bitf) {
		case 0:
			xfont = font;
			xpts = pts;
			break;
		case 1:
			xfont = pfont;
			xpts = ppts;
			break;
		case 2:
			xfont = mfont;
			xpts = mpts;
		}
	}
}


/* these next two functions ought to be the same in troff and nroff, */
/* but the data structures they search are different. */
/* silly historical problem. */


Tchar t_setch(int c)
{
	int j;
	char temp[50];
	char *s;

	j = 0;
	s = temp;
	if (c == '(') {	/* \(xx */
		if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
			return(0);
	} else {	/* \C'...' */
		c = getach();
		while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1)
			s++;
	}
	*s = '\0';
#ifdef UNICODE
	return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
#else
	if (NROFF) {
		j = chadd(temp, Troffchar, Lookup);
		if ( j == -1)
			return 0;
		else
			return j | chbits;
	} else
		return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
		
#endif /*UNICODE*/
}

Tchar t_setabs(void)		/* set absolute char from \N'...' */
{
	int n;
	char temp[10];

	getch();	/* delim */
	n = 0;
	n = inumb(&n);
	getch();	/* delim */
	if (nonumb)
		return 0;
	sprintf(temp, "%d", n);	/* convert into "#n" */
	n = chadd(temp, Number, Install);
	return n | chbits;
}


/*
 * fontlab[] is a cache that contains font information
 * for each font.
 * fontlab[] contains the 1- or 2-character name of the
 * font current associated with that font.
 * fonts 1..nfonts correspond to the mounted fonts;
 * the last of these are the special fonts.
 * If we don't use the (named) font in one of the
 * standard positions, we install the name in the next
 * free slot of fontlab[] and font[].
 * Whenever we need info about the font, we
 * read in the data into the next free slot with getfont.
 * The ptfont() (t10.c) routine will tell
 * the device filter to put the font always at position
 * zero if xfont > nfonts, so no need to change these filters.
 * Yes, this is a bit kludgy.
 *
 * This gives the new specs of findft:
 * 	find the font name i, where i also can be a number.
 * 	Installs the font(name) i when not present
 * 	returns -1 on error
 */

int
t_findft(int i)
{
	int k;
	Uchar *p;

	p = unpair(i);

	if (isdigit(p[0])) {		/* first look for numbers */
		k = p[0] - '0';
		if (p[1] > 0 && isdigit(p[1]))
			k = 10 * k + p[1] - '0';
		if (k > 0 && k <= nfonts && k < smnt)
			return(k);	/* mounted font:  .ft 3 */
		if (fontlab[k] && k <= MAXFONTS) {	/* translate */
			return(k);			/*number to a name */
		} else {
			fprintf(stderr, "troff: no font at position %d\n", k);
			return(-1);	/* wild number */
		}
	}

	/*
	 * Now we look for font names
	 */
	for (k = 1; fontlab[k] != i; k++) {
		if (k > MAXFONTS)
			return(-1);	/* running out of fontlab space */
		if (fontlab[k] == 0) {	/* passed all existing names */
			if (setfp(k, i, (char *) 0, 1) == -1)
				return(-1);
			else {
				fontlab[k] = i;	/* install the name */
				return(k);
			}
		}
	}
	return(k);			/* was one of the existing names */
}


void caseps(void)
{
	int i;

	if (TROFF) {
		if(skip())
			i = apts1;
		else {
			noscale++;
			i = inumb(&apts);	/* this is a disaster for fractional point sizes */
			noscale = 0;
			if(nonumb)
				i = apts1;
		}
		casps1(i);
	}
}


void casps1(int i)
{

/*
 * in olden times, it used to ignore changes to 0 or negative.
 * this is meant to allow the requested size to be anything,
 * in particular so eqn can generate lots of \s-3's and still
 * get back by matching \s+3's.

	if (i <= 0)
		return;
*/
	apts1 = apts;
	apts = i;
	pts1 = pts;
	pts = findps(i);
	mchbits();
}

int
findps(int i)
{
	int j, k;

	for (j=k=0 ; pstab[j] != 0 ; j++)
		if (abs(pstab[j]-i) < abs(pstab[k]-i))
			k = j;

	return(pstab[k]);
}


void t_mchbits(void)
{
	int i, j, k;

	i = pts;
	for (j = 0; i > (k = pstab[j]); j++)
		if (!k) {
			j--;
			break;
		}
	chbits = 0;
	setsbits(chbits, ++j);
	setfbits(chbits, font);
	sps = width(' ' | chbits);
	zapwcache(1);
}

void t_setps(void)
{
	int i, j;

	j = 0;
	i = cbits(getch());
	if (isdigit(i)) {		/* \sd or \sdd */
		i -= '0';
		if (i == 0)		/* \s0 */
			j = apts1;
		else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) {	/* \sdd */
			j = 10 * i + j - '0';
			ch = 0;
		} else		/* \sd */
			j = i;
	} else if (i == '(') {		/* \s(dd */
		j = cbits(getch()) - '0';
		j = 10 * j + cbits(getch()) - '0';
		if (j == 0)		/* \s(00 */
			j = apts1;
	} else if (i == '+' || i == '-') {	/* \s+, \s- */
		j = cbits(getch());
		if (isdigit(j)) {		/* \s+d, \s-d */
			j -= '0';
		} else if (j == '(') {		/* \s+(dd, \s-(dd */
			j = cbits(getch()) - '0';
			j = 10 * j + cbits(getch()) - '0';
		}
		if (i == '-')
			j = -j;
		j += apts;
	}
	casps1(j);
}


Tchar t_setht(void)		/* set character height from \H'...' */
{
	int n;
	Tchar c;

	getch();
	n = inumb(&apts);
	getch();
	if (n == 0 || nonumb)
		n = apts;	/* does this work? */
	c = CHARHT;
	c |= ZBIT;
	setsbits(c, n);
	setfbits(c, pts);	/* sneaky, CHARHT font bits are size bits */
	return(c);
}

Tchar t_setslant(void)		/* set slant from \S'...' */
{
	int n;
	Tchar c;

	getch();
	n = 0;
	n = inumb(&n);
	getch();
	if (nonumb)
		n = 0;
	c = SLANT;
	c |= ZBIT;
	setsfbits(c, n+180);
	return(c);
}


void caseft(void)
{
	if (!TROFF) {
		n_caseft();
		return;
	}
	skip();
	setfont(1);
}


void t_setfont(int a)
{
	int i, j;

	if (a)
		i = getrq();
	else 
		i = getsn();
	if (!i || i == 'P') {
		j = font1;
		goto s0;
	}
	if (/* i == 'S' || */ i == '0')	/* an experiment -- why can't we change to it? */
		return;
	if ((j = findft(i)) == -1)
		if ((j = setfp(0, i, (char*) 0, 1)) == -1)	/* try to put it in position 0 */
			return;
s0:
	font1 = font;
	font = j;
	mchbits();
}


void t_setwd(void)
{
	int base, wid;
	Tchar i;
	int delim, emsz, k;
	int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;

	base = numtabp[ST].val = numtabp[SB].val = wid = numtabp[CT].val = 0;
	if (ismot(i = getch()))
		return;
	delim = cbits(i);
	savhp = numtabp[HP].val;
	numtabp[HP].val = 0;
	savapts = apts;
	savapts1 = apts1;
	savfont = font;
	savfont1 = font1;
	savpts = pts;
	savpts1 = pts1;
	setwdf++;
	while (cbits(i = getch()) != delim && !nlflg) {
		k = width(i);
		wid += k;
		numtabp[HP].val += k;
		if (!ismot(i)) {
			emsz = (INCH/72) * xpts;
		} else if (isvmot(i)) {
			k = absmot(i);
			if (isnmot(i))
				k = -k;
			base -= k;
			emsz = 0;
		} else 
			continue;
		if (base < numtabp[SB].val)
			numtabp[SB].val = base;
		if ((k = base + emsz) > numtabp[ST].val)
			numtabp[ST].val = k;
	}
	setn1(wid, 0, (Tchar) 0);
	numtabp[HP].val = savhp;
	apts = savapts;
	apts1 = savapts1;
	font = savfont;
	font1 = savfont1;
	pts = savpts;
	pts1 = savpts1;
	mchbits();
	setwdf = 0;
}


Tchar t_vmot(void)
{
	dfact = lss;
	vflag++;
	return t_mot();
}


Tchar t_hmot(void)
{
	dfact = EM;
	return t_mot();
}


Tchar t_mot(void)
{
	int j, n;
	Tchar i;

	j = HOR;
	getch(); /*eat delim*/
	if (n = atoi0()) {
		if (vflag)
			j = VERT;
		i = makem(quant(n, j));
	} else
		i = 0;
	getch();
	vflag = 0;
	dfact = 1;
	return(i);
}


Tchar t_sethl(int k)
{
	int j;
	Tchar i;

	j = EM / 2;
	if (k == 'u')
		j = -j;
	else if (k == 'r')
		j = -2 * j;
	vflag++;
	i = makem(j);
	vflag = 0;
	return(i);
}


Tchar t_makem(int i)
{
	Tchar j;

	if (i >= 0)
		j = i;
	else
		j = -i;
	if (Hor > 1 && !vflag)
		j = (j + Hor/2)/Hor * Hor;
	j |= MOT;
	if (i < 0)
		j |= NMOT;
	if (vflag)
		j |= VMOT;
	return(j);
}


Tchar getlg(Tchar i)
{
	Tchar j, k;
	int lf;

	if (!TROFF)
		return i;
	if ((lf = fonts[fbits(i)].ligfont) == 0) /* font lacks ligatures */
		return(i);
	j = getch0();
	if (cbits(j) == 'i' && (lf & LFI))
		j = LIG_FI;
	else if (cbits(j) == 'l' && (lf & LFL))
		j = LIG_FL;
	else if (cbits(j) == 'f' && (lf & LFF)) {
		if ((lf & (LFFI|LFFL)) && lg != 2) {
			k = getch0();
			if (cbits(k)=='i' && (lf&LFFI))
				j = LIG_FFI;
			else if (cbits(k)=='l' && (lf&LFFL))
				j = LIG_FFL;
			else {
				*pbp++ = k;
				j = LIG_FF;
			}
		} else 
			j = LIG_FF;
	} else {
		*pbp++ = j;
		j = i;
	}
	return(i & SFMASK | j);
}


void caselg(void)
{

	if(TROFF) {
		skip();
		lg = atoi0();
		if (nonumb)
			lg = 1;
	}
}

void casefp(void)
{
	int i, j;

	if (!TROFF) {
		n_casefp();
		return;
	}
	skip();
	i = cbits(getch());
	if (isdigit(i)) {
		i -= '0';
		j = cbits(getch());
		if (isdigit(j))
			i = 10 * i + j - '0';
	}
	if (i <= 0 || i > nfonts)
		ERROR "fp: bad font position %d", i WARN;
	else if (skip() || !(j = getrq()))
		ERROR "fp: no font name" WARN; 
	else if (skip() || !getname())
		setfp(i, j, (char*) 0, 1);
	else		/* 3rd argument = filename */
		setfp(i, j, nextf, 1);
}

char *strdupl(const char *s)	/* make a copy of s */
{
	char *t;

	t = (char *) malloc(strlen(s) + 1);
	if (t == NULL)
		ERROR "out of space in strdupl(%s)", s FATAL;
	strcpy(t, s);
	return t;
}

int
setfp(int pos, int f, char *truename, int print)	/* mount font f at position pos[0...nfonts] */
{
	char pathname[NS], shortname[NS], *sl;

	sl = (char*)0;
	zapwcache(0);
	if (truename)
		strcpy(shortname, truename);
	else
		strcpy(shortname, (char *) unpair(f));
	if (truename && strrchr(truename, '/')) {	/* .fp 1 R dir/file: use verbatim */
		sprintf(pathname, "%s", truename);
		if (fonts[pos].truename)
			free(fonts[pos].truename);
		fonts[pos].truename = strdupl(truename);
	} else if (truename) {			/* synonym: .fp 1 R Avant */
		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, truename);
		truename = 0;	/* so doesn't get repeated by ptfpcmd */
	} else					/* vanilla: .fp 5 XX */
		sprintf(pathname, "%s/dev%s/%s", fontdir, devname, shortname);
	if (truename == 0 && fonts[pos].truename != 0) {
		free(fonts[pos].truename);
		fonts[pos].truename = 0;
	}
	if (getfont(pathname, pos) < 0) {
		ERROR "Can't open font file %s", pathname WARN;
		return -1;
	}
	if (print && !ascii) {
		ptfpcmd(pos, fonts[pos].longname, truename);
		ptfont();
	}
	if (pos == smnt) {
		smnt = 0; 
		sbold = 0; 
	}
	fontlab[pos] = f;
	if (smnt == 0 && fonts[pos].specfont)
		smnt = pos;
	bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
	return pos;
}

/*
 * .cs request; don't check legality of optional arguments
 */
void casecs(void)
{
	int i, j;

	if (TROFF) {
		int savtr = trace;

		trace = 0;
		noscale++;
		skip();
		if (!(i = getrq()) || (i = findft(i)) < 0)
			goto rtn;
		skip();
		cstab[i] = atoi0();
		skip();
		j = atoi0();
		if(nonumb)
			ccstab[i] = 0;
		else
			ccstab[i] = findps(j);
	rtn:
		zapwcache(0);
		noscale = 0;
		trace = savtr;
	}
}


void casebd(void)
{
	int i, j, k;

	j=0;
	if (!TROFF) {
		n_casebd();
		return;
	}
	zapwcache(0);
	k = 0;
bd0:
	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
		if (k)
			goto bd1;
		else 
			return;
	}
	if (j == smnt) {
		k = smnt;
		goto bd0;
	}
	if (k) {
		sbold = j;
		j = k;
	}
bd1:
	skip();
	noscale++;
	bdtab[j] = atoi0();
	noscale = 0;
}


void casevs(void)
{
	int i;

	if (!TROFF) {
		n_casevs();
		return;
	}
	skip();
	vflag++;
	dfact = INCH; /* default scaling is points! */
	dfactd = 72;
	res = VERT;
	i = inumb(&lss);
	if (nonumb)
		i = lss1;
	if (i < VERT) 
		i = VERT;
	lss1 = lss;
	lss = i;
}


void casess(void)
{
	int i;

	if(TROFF) {
		noscale++;
		skip();
		if(i = atoi0()) {
			spacesz = i & 0177;
			zapwcache(0);
			sps = width(' ' | chbits);
		}
		noscale = 0;
	}
}


Tchar t_xlss(void)
{
	/* stores \x'...' into two successive Tchars.
	/* the first contains HX, the second the value,
	/* encoded as a vertical motion.
	/* decoding is done in n2.c by pchar().
	*/
	int i;

	getch();
	dfact = lss;
	i = quant(atoi0(), VERT);
	dfact = 1;
	getch();
	if (i >= 0)
		*pbp++ = MOT | VMOT | i;
	else
		*pbp++ = MOT | VMOT | NMOT | -i;
	return(HX);
}

Uchar *unpair(int i)
{
	static Uchar name[3];

	name[0] = i & SHORTMASK;
	name[1] = (i >> SHORT) & SHORTMASK;
	name[2] = 0;
	return name;
}
