123886Sjaap #ifndef lint
2*23908Sjaap static char sccsid[] = "@(#)n9.c	2.1 (CWI) 85/07/18";
323886Sjaap #endif lint
423886Sjaap #include "tdef.h"
523886Sjaap #ifdef NROFF
623886Sjaap #include "tw.h"
723886Sjaap #endif
823886Sjaap #include <sgtty.h>
923886Sjaap #include "ext.h"
1023886Sjaap 
11*23908Sjaap /*
12*23908Sjaap  * troff9.c
13*23908Sjaap  *
14*23908Sjaap  * misc functions
15*23908Sjaap  */
16*23908Sjaap 
setz()1723886Sjaap tchar setz()
1823886Sjaap {
1923886Sjaap 	tchar i;
2023886Sjaap 
2123886Sjaap 	if (!ismot(i = getch()))
2223886Sjaap 		i |= ZBIT;
2323886Sjaap 	return(i);
2423886Sjaap }
2523886Sjaap 
setline()2623886Sjaap setline()
2723886Sjaap {
2823886Sjaap 	register tchar *i;
2923886Sjaap 	tchar c;
3023886Sjaap 	int	length;
3123886Sjaap 	int	w, cnt, delim, rem, temp;
32*23908Sjaap 	tchar linebuf[NC];
3323886Sjaap 
3423886Sjaap 	if (ismot(c = getch()))
3523886Sjaap 		return;
3623886Sjaap 	delim = cbits(c);
3723886Sjaap 	vflag = 0;
3823886Sjaap 	dfact = EM;
3923886Sjaap 	length = quant(atoi(), HOR);
4023886Sjaap 	dfact = 1;
4123886Sjaap 	if (!length) {
4223886Sjaap 		eat(delim);
4323886Sjaap 		return;
4423886Sjaap 	}
4523886Sjaap s0:
4623886Sjaap 	if ((cbits(c = getch())) == delim) {
4723886Sjaap 		ch = c;
4823886Sjaap 		c = RULE | chbits;
4923886Sjaap 	} else if (cbits(c) == FILLER)
5023886Sjaap 		goto s0;
5123886Sjaap 	w = width(c);
52*23908Sjaap 	i = linebuf;
5323886Sjaap 	if (length < 0) {
5423886Sjaap 		*i++ = makem(length);
5523886Sjaap 		length = -length;
5623886Sjaap 	}
5723886Sjaap 	if (!(cnt = length / w)) {
5823886Sjaap 		*i++ = makem(-(temp = ((w - length) / 2)));
5923886Sjaap 		*i++ = c;
6023886Sjaap 		*i++ = makem(-(w - length - temp));
6123886Sjaap 		goto s1;
6223886Sjaap 	}
6323886Sjaap 	if (rem = length % w) {
6423886Sjaap 		if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
6523886Sjaap 			*i++ = c | ZBIT;
6623886Sjaap 		*i++ = makem(rem);
6723886Sjaap 	}
6823886Sjaap 	if (cnt) {
6923886Sjaap 		*i++ = RPT;
7023886Sjaap 		*i++ = cnt;
7123886Sjaap 		*i++ = c;
7223886Sjaap 	}
7323886Sjaap s1:
7423886Sjaap 	*i++ = 0;
7523886Sjaap 	eat(delim);
76*23908Sjaap 	pushback(linebuf);
7723886Sjaap }
7823886Sjaap 
7923886Sjaap 
eat(c)8023886Sjaap eat(c)
81*23908Sjaap register int	c;
8223886Sjaap {
8323886Sjaap 	register i;
8423886Sjaap 
8523886Sjaap 	while ((i = cbits(getch())) != c &&  (i != '\n'))
8623886Sjaap 		;
8723886Sjaap 	return(i);
8823886Sjaap }
8923886Sjaap 
9023886Sjaap 
setov()9123886Sjaap setov()
9223886Sjaap {
9323886Sjaap 	register j, k;
94*23908Sjaap 	tchar i, o[NOV];
95*23908Sjaap 	int delim, w[NOV];
9623886Sjaap 
9723886Sjaap 	if (ismot(i = getch()))
9823886Sjaap 		return;
9923886Sjaap 	delim = cbits(i);
10023886Sjaap 	for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) &&  (j != '\n'); k++) {
10123886Sjaap 		o[k] = i;
10223886Sjaap 		w[k] = width(i);
10323886Sjaap 	}
10423886Sjaap 	o[k] = w[k] = 0;
10523886Sjaap 	if (o[0])
10623886Sjaap 		for (j = 1; j; ) {
10723886Sjaap 			j = 0;
10823886Sjaap 			for (k = 1; o[k] ; k++) {
10923886Sjaap 				if (w[k-1] < w[k]) {
11023886Sjaap 					j++;
11123886Sjaap 					i = w[k];
11223886Sjaap 					w[k] = w[k-1];
11323886Sjaap 					w[k-1] = i;
11423886Sjaap 					i = o[k];
11523886Sjaap 					o[k] = o[k-1];
11623886Sjaap 					o[k-1] = i;
11723886Sjaap 				}
11823886Sjaap 			}
11923886Sjaap 		}
12023886Sjaap 	else
12123886Sjaap 		return;
122*23908Sjaap 	*pbp++ = makem(w[0] / 2);
123*23908Sjaap 	for (k = 0; o[k]; k++)
124*23908Sjaap 		;
125*23908Sjaap 	while (k>0) {
126*23908Sjaap 		k--;
127*23908Sjaap 		*pbp++ = makem(-((w[k] + w[k+1]) / 2));
128*23908Sjaap 		*pbp++ = o[k];
12923886Sjaap 	}
13023886Sjaap }
13123886Sjaap 
13223886Sjaap 
setbra()13323886Sjaap setbra()
13423886Sjaap {
13523886Sjaap 	register k;
13623886Sjaap 	tchar i, *j, dwn;
13723886Sjaap 	int	cnt, delim;
138*23908Sjaap 	tchar brabuf[NC];
13923886Sjaap 
14023886Sjaap 	if (ismot(i = getch()))
14123886Sjaap 		return;
14223886Sjaap 	delim = cbits(i);
143*23908Sjaap 	j = brabuf + 1;
14423886Sjaap 	cnt = 0;
14523886Sjaap #ifdef NROFF
14623886Sjaap 	dwn = (2 * t.Halfline) | MOT | VMOT;
14723886Sjaap #endif
14823886Sjaap #ifndef NROFF
14923886Sjaap 	dwn = EM | MOT | VMOT;
15023886Sjaap #endif
151*23908Sjaap 	while (((k = cbits(i = getch())) != delim) && (k != '\n') &&  (j <= (brabuf + NC - 4))) {
15223886Sjaap 		*j++ = i | ZBIT;
15323886Sjaap 		*j++ = dwn;
15423886Sjaap 		cnt++;
15523886Sjaap 	}
15623886Sjaap 	if (--cnt < 0)
15723886Sjaap 		return;
15823886Sjaap 	else if (!cnt) {
15923886Sjaap 		ch = *(j - 2);
16023886Sjaap 		return;
16123886Sjaap 	}
16223886Sjaap 	*j = 0;
16323886Sjaap #ifdef NROFF
164*23908Sjaap 	*--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
16523886Sjaap #endif
16623886Sjaap #ifndef NROFF
167*23908Sjaap 	*--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
16823886Sjaap #endif
16923886Sjaap 	*--j &= ~ZBIT;
170*23908Sjaap 	pushback(brabuf);
17123886Sjaap }
17223886Sjaap 
17323886Sjaap 
setvline()17423886Sjaap setvline()
17523886Sjaap {
17623886Sjaap 	register i;
177*23908Sjaap 	tchar c, rem, ver, neg;
17823886Sjaap 	int	cnt, delim, v;
179*23908Sjaap 	tchar vlbuf[NC];
180*23908Sjaap 	register tchar *vlp;
18123886Sjaap 
18223886Sjaap 	if (ismot(c = getch()))
18323886Sjaap 		return;
18423886Sjaap 	delim = cbits(c);
18523886Sjaap 	dfact = lss;
18623886Sjaap 	vflag++;
18723886Sjaap 	i = quant(atoi(), VERT);
18823886Sjaap 	dfact = 1;
18923886Sjaap 	if (!i) {
19023886Sjaap 		eat(delim);
19123886Sjaap 		vflag = 0;
19223886Sjaap 		return;
19323886Sjaap 	}
19423886Sjaap 	if ((cbits(c = getch())) == delim) {
19523886Sjaap 		c = BOXRULE | chbits;	/*default box rule*/
19623886Sjaap 	} else
19723886Sjaap 		getch();
19823886Sjaap 	c |= ZBIT;
19923886Sjaap 	neg = 0;
20023886Sjaap 	if (i < 0) {
20123886Sjaap 		i = -i;
20223886Sjaap 		neg = NMOT;
20323886Sjaap 	}
20423886Sjaap #ifdef NROFF
20523886Sjaap 	v = 2 * t.Halfline;
20623886Sjaap #endif
20723886Sjaap #ifndef NROFF
20823886Sjaap 	v = EM;
20923886Sjaap #endif
21023886Sjaap 	cnt = i / v;
21123886Sjaap 	rem = makem(i % v) | neg;
21223886Sjaap 	ver = makem(v) | neg;
213*23908Sjaap 	vlp = vlbuf;
21423886Sjaap 	if (!neg)
215*23908Sjaap 		*vlp++ = ver;
21623886Sjaap 	if (absmot(rem) != 0) {
217*23908Sjaap 		*vlp++ = c;
218*23908Sjaap 		*vlp++ = rem;
21923886Sjaap 	}
220*23908Sjaap 	while ((vlp < (vlbuf + NC - 3)) && cnt--) {
221*23908Sjaap 		*vlp++ = c;
222*23908Sjaap 		*vlp++ = ver;
22323886Sjaap 	}
224*23908Sjaap 	*(vlp - 2) &= ~ZBIT;
22523886Sjaap 	if (!neg)
226*23908Sjaap 		vlp--;
227*23908Sjaap 	*vlp++ = 0;
228*23908Sjaap 	pushback(vlbuf);
22923886Sjaap 	vflag = 0;
23023886Sjaap }
23123886Sjaap 
232*23908Sjaap #define	NPAIR	(NC/2-6)	/* max pairs in spline, etc. */
23323886Sjaap 
setdraw()23423886Sjaap setdraw()	/* generate internal cookies for a drawing function */
23523886Sjaap {
236*23908Sjaap 	int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
237*23908Sjaap 	tchar c, drawbuf[NC];
238*23908Sjaap 
239*23908Sjaap 	/* input is \D'f dx dy dx dy ... c' (or at least it had better be) */
24023886Sjaap 	/* this does drawing function f with character c and the */
241*23908Sjaap 	/* specified dx,dy pairs interpreted as appropriate */
242*23908Sjaap 	/* pairs are deltas from last point, except for radii */
24323886Sjaap 
244*23908Sjaap 	/* l dx dy:	line from here by dx,dy */
24523886Sjaap 	/* c x:		circle of diameter x, left side here */
24623886Sjaap 	/* e x y:	ellipse of diameters x,y, left side here */
247*23908Sjaap 	/* a dx1 dy1 dx2 dy2:
248*23908Sjaap 			ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */
249*23908Sjaap 	/* ~ dx1 dy1 dx2 dy2...:
250*23908Sjaap 			spline to dx1,dy1 to dx2,dy2 ... */
251*23908Sjaap 	/* f dx dy ...:	f is any other char:  like spline */
25223886Sjaap 
25323886Sjaap 	if (ismot(c = getch()))
25423886Sjaap 		return;
25523886Sjaap 	delim = cbits(c);
25623886Sjaap 	type = cbits(getch());
257*23908Sjaap 	for (i = 0; i < NPAIR ; i++) {
25823886Sjaap 		c = getch();
25923886Sjaap 		if (cbits(c) == delim)
26023886Sjaap 			break;
26123886Sjaap 	/* ought to pick up optional drawing character */
26223886Sjaap 		if (cbits(c) != ' ')
26323886Sjaap 			ch = c;
26423886Sjaap 		vflag = 0;
26523886Sjaap 		dfact = EM;
26623886Sjaap 		dx[i] = quant(atoi(), HOR);
26723886Sjaap 		if (dx[i] > MAXMOT)
26823886Sjaap 			dx[i] = MAXMOT;
26923886Sjaap 		else if (dx[i] < -MAXMOT)
27023886Sjaap 			dx[i] = -MAXMOT;
27123886Sjaap 		if (cbits((c = getch())) == delim) {	/* spacer */
27223886Sjaap 			dy[i++] = 0;
27323886Sjaap 			break;
27423886Sjaap 		}
27523886Sjaap 		vflag = 1;
27623886Sjaap 		dfact = lss;
27723886Sjaap 		dy[i] = quant(atoi(), VERT);
27823886Sjaap 		if (dy[i] > MAXMOT)
27923886Sjaap 			dy[i] = MAXMOT;
28023886Sjaap 		else if (dy[i] < -MAXMOT)
28123886Sjaap 			dy[i] = -MAXMOT;
28223886Sjaap 	}
28323886Sjaap 	dfact = 1;
28423886Sjaap 	vflag = 0;
28523886Sjaap #ifndef NROFF
286*23908Sjaap 	drawbuf[0] = DRAWFCN | chbits | ZBIT;
287*23908Sjaap 	drawbuf[1] = type | chbits | ZBIT;
288*23908Sjaap 	drawbuf[2] = '.' | chbits | ZBIT;	/* use default drawing character */
28923886Sjaap 	for (k = 0, j = 3; k < i; k++) {
290*23908Sjaap 		drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
291*23908Sjaap 		drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
29223886Sjaap 	}
29323886Sjaap 	if (type == DRAWELLIPSE) {
294*23908Sjaap 		drawbuf[5] = drawbuf[4] | NMOT;	/* so the net vertical is zero */
29523886Sjaap 		j = 6;
29623886Sjaap 	}
297*23908Sjaap 	drawbuf[j++] = DRAWFCN | chbits | ZBIT;	/* marks end for ptout */
298*23908Sjaap 	drawbuf[j] = 0;
299*23908Sjaap 	pushback(drawbuf);
30023886Sjaap #endif
30123886Sjaap }
30223886Sjaap 
30323886Sjaap 
casefc()30423886Sjaap casefc()
30523886Sjaap {
30623886Sjaap 	register i;
30723886Sjaap 	tchar j;
30823886Sjaap 
309*23908Sjaap 	gchtab[fc] &= ~FCBIT;
31023886Sjaap 	fc = IMP;
31123886Sjaap 	padc = ' ';
31223886Sjaap 	if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
31323886Sjaap 		return;
31423886Sjaap 	fc = i;
315*23908Sjaap 	gchtab[fc] |= FCBIT;
31623886Sjaap 	if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
31723886Sjaap 		return;
31823886Sjaap 	padc = ch;
31923886Sjaap }
32023886Sjaap 
32123886Sjaap 
322*23908Sjaap tchar
setfield(x)323*23908Sjaap setfield(x)
32423886Sjaap int	x;
32523886Sjaap {
326*23908Sjaap 	register tchar ii, jj, *fp;
32723886Sjaap 	register i, j;
328*23908Sjaap 	int length, ws, npad, temp, type;
329*23908Sjaap 	tchar **pp, *padptr[NPP];
330*23908Sjaap 	tchar fbuf[FBUFSZ];
331*23908Sjaap 	int savfc, savtc, savlc;
332*23908Sjaap 	tchar rchar;
333*23908Sjaap 	int savepos;
33423886Sjaap 
33523886Sjaap 	if (x == tabch)
33623886Sjaap 		rchar = tabc | chbits;
33723886Sjaap 	else if (x ==  ldrch)
33823886Sjaap 		rchar = dotc | chbits;
33923886Sjaap 	temp = npad = ws = 0;
34023886Sjaap 	savfc = fc;
34123886Sjaap 	savtc = tabch;
34223886Sjaap 	savlc = ldrch;
34323886Sjaap 	tabch = ldrch = fc = IMP;
344*23908Sjaap 	savepos = numtab[HP].val;
345*23908Sjaap 	gchtab[tabch] &= ~TABBIT;
346*23908Sjaap 	gchtab[ldrch] &= ~LDRBIT;
347*23908Sjaap 	gchtab[fc] &= ~FCBIT;
348*23908Sjaap 	gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
34923886Sjaap 	for (j = 0; ; j++) {
350*23908Sjaap 		if ((tabtab[j] & TABMASK) == 0) {
35123886Sjaap 			if (x == savfc)
352*23908Sjaap 				errprint("zero field width.");
35323886Sjaap 			jj = 0;
35423886Sjaap 			goto rtn;
35523886Sjaap 		}
356*23908Sjaap 		if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 )
35723886Sjaap 			break;
35823886Sjaap 	}
359*23908Sjaap 	type = tabtab[j] & (~TABMASK);
36023886Sjaap 	fp = fbuf;
36123886Sjaap 	pp = padptr;
36223886Sjaap 	if (x == savfc) {
36323886Sjaap 		while (1) {
364*23908Sjaap 			j = cbits(ii = getch());
365*23908Sjaap 			jj = width(ii);
366*23908Sjaap 			widthp = jj;
367*23908Sjaap 			numtab[HP].val += jj;
368*23908Sjaap 			if (j == padc) {
36923886Sjaap 				npad++;
37023886Sjaap 				*pp++ = fp;
37123886Sjaap 				if (pp > (padptr + NPP - 1))
37223886Sjaap 					break;
37323886Sjaap 				goto s1;
37423886Sjaap 			} else if (j == savfc)
37523886Sjaap 				break;
37623886Sjaap 			else if (j == '\n') {
37723886Sjaap 				temp = j;
37823886Sjaap 				nlflg = 0;
37923886Sjaap 				break;
38023886Sjaap 			}
381*23908Sjaap 			ws += jj;
38223886Sjaap s1:
38323886Sjaap 			*fp++ = ii;
38423886Sjaap 			if (fp > (fbuf + FBUFSZ - 3))
38523886Sjaap 				break;
38623886Sjaap 		}
38723886Sjaap 		if (!npad) {
38823886Sjaap 			npad++;
38923886Sjaap 			*pp++ = fp;
39023886Sjaap 			*fp++ = 0;
39123886Sjaap 		}
39223886Sjaap 		*fp++ = temp;
39323886Sjaap 		*fp++ = 0;
39423886Sjaap 		temp = i = (j = length - ws) / npad;
39523886Sjaap 		i = (i / HOR) * HOR;
39623886Sjaap 		if ((j -= i * npad) < 0)
39723886Sjaap 			j = -j;
39823886Sjaap 		ii = makem(i);
39923886Sjaap 		if (temp < 0)
40023886Sjaap 			ii |= NMOT;
40123886Sjaap 		for (; npad > 0; npad--) {
40223886Sjaap 			*(*--pp) = ii;
40323886Sjaap 			if (j) {
40423886Sjaap 				j -= HOR;
40523886Sjaap 				(*(*pp)) += HOR;
40623886Sjaap 			}
40723886Sjaap 		}
408*23908Sjaap 		pushback(fbuf);
40923886Sjaap 		jj = 0;
41023886Sjaap 	} else if (type == 0) {
41123886Sjaap 		/*plain tab or leader*/
412*23908Sjaap 		if ((j = width(rchar)) > 0) {
413*23908Sjaap 			int nchar = length / j;
414*23908Sjaap 			while (nchar-->0 && pbp < &pbbuf[NC-3]) {
415*23908Sjaap 				numtab[HP].val += j;
416*23908Sjaap 				widthp = j;
417*23908Sjaap 				*pbp++ = rchar;
418*23908Sjaap 			}
41923886Sjaap 			length %= j;
42023886Sjaap 		}
42123886Sjaap 		if (length)
42223886Sjaap 			jj = length | MOT;
42323886Sjaap 		else
42423886Sjaap 			jj = getch0();
42523886Sjaap 	} else {
42623886Sjaap 		/*center tab*/
42723886Sjaap 		/*right tab*/
42823886Sjaap 		while (((j = cbits(ii = getch())) != savtc) &&  (j != '\n') && (j != savlc)) {
429*23908Sjaap 			jj = width(ii);
430*23908Sjaap 			ws += jj;
431*23908Sjaap 			numtab[HP].val += jj;
432*23908Sjaap 			widthp = jj;
43323886Sjaap 			*fp++ = ii;
43423886Sjaap 			if (fp > (fbuf + FBUFSZ - 3))
43523886Sjaap 				break;
43623886Sjaap 		}
43723886Sjaap 		*fp++ = ii;
43823886Sjaap 		*fp++ = 0;
43923886Sjaap 		if (type == RTAB)
44023886Sjaap 			length -= ws;
44123886Sjaap 		else
44223886Sjaap 			length -= ws / 2; /*CTAB*/
443*23908Sjaap 		pushback(fbuf);
444*23908Sjaap 		if ((j = width(rchar)) != 0 && length > 0) {
445*23908Sjaap 			int nchar = length / j;
446*23908Sjaap 			while (nchar-- > 0 && pbp < &pbbuf[NC-3])
447*23908Sjaap 				*pbp++ = rchar;
44823886Sjaap 			length %= j;
44923886Sjaap 		}
45023886Sjaap 		length = (length / HOR) * HOR;
45123886Sjaap 		jj = makem(length);
45223886Sjaap 		nlflg = 0;
45323886Sjaap 	}
45423886Sjaap rtn:
455*23908Sjaap 	gchtab[fc] &= ~FCBIT;
456*23908Sjaap 	gchtab[tabch] &= ~TABBIT;
457*23908Sjaap 	gchtab[ldrch] &= ~LDRBIT;
45823886Sjaap 	fc = savfc;
45923886Sjaap 	tabch = savtc;
46023886Sjaap 	ldrch = savlc;
461*23908Sjaap 	gchtab[fc] |= FCBIT;
462*23908Sjaap 	gchtab[tabch] = TABBIT;
463*23908Sjaap 	gchtab[ldrch] |= LDRBIT;
464*23908Sjaap 	numtab[HP].val = savepos;
46523886Sjaap 	return(jj);
46623886Sjaap }
46723886Sjaap 
46823886Sjaap 
469