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