diff options
Diffstat (limited to 'src/cmd/troff/n9.c')
-rw-r--r-- | src/cmd/troff/n9.c | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/src/cmd/troff/n9.c b/src/cmd/troff/n9.c new file mode 100644 index 00000000..5cd70648 --- /dev/null +++ b/src/cmd/troff/n9.c @@ -0,0 +1,488 @@ +#include "tdef.h" +#include "ext.h" +#include "fns.h" + +/* + * troff9.c + * + * misc functions + */ + +Tchar setz(void) +{ + Tchar i; + + if (!ismot(i = getch())) + i |= ZBIT; + return(i); +} + +void setline(void) +{ + Tchar *i; + Tchar c; + int length; + int j, w, cnt, delim, rem, temp; + Tchar linebuf[NC]; + + if (ismot(c = getch())) + return; + delim = cbits(c); + vflag = 0; + dfact = EM; + length = quant(atoi0(), HOR); + dfact = 1; + if (!length) { + eat(delim); + return; + } +s0: + if ((j = cbits(c = getch())) == delim || j == '\n') { + ch = c; + c = RULE | chbits; + } else if (cbits(c) == FILLER) + goto s0; + w = width(c); + if (w <= 0) { + ERROR "zero-width underline character ignored" WARN; + c = RULE | chbits; + w = width(c); + } + i = linebuf; + if (length < 0) { + *i++ = makem(length); + length = -length; + } + if (!(cnt = length / w)) { + *i++ = makem(-(temp = ((w - length) / 2))); + *i++ = c; + *i++ = makem(-(w - length - temp)); + goto s1; + } + if (rem = length % w) { + if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN) + *i++ = c | ZBIT; + *i++ = makem(rem); + } + if (cnt) { + *i++ = RPT; + *i++ = cnt; + *i++ = c; + } +s1: + *i = 0; + eat(delim); + pushback(linebuf); +} + + +eat(int c) +{ + int i; + + while ((i = cbits(getch())) != c && i != '\n') + ; + return(i); +} + + +void setov(void) +{ + int j, k; + Tchar i, o[NOV+1]; + int delim, w[NOV+1]; + + if (ismot(i = getch())) + return; + delim = cbits(i); + for (k = 0; k < NOV && (j = cbits(i = getch())) != delim && j != '\n'; k++) { + o[k] = i; + w[k] = width(i); + } + o[k] = w[k] = 0; + if (o[0]) + for (j = 1; j; ) { + j = 0; + for (k = 1; o[k] ; k++) { + if (w[k-1] < w[k]) { + j++; + i = w[k]; + w[k] = w[k-1]; + w[k-1] = i; + i = o[k]; + o[k] = o[k-1]; + o[k-1] = i; + } + } + } + else + return; + *pbp++ = makem(w[0] / 2); + for (k = 0; o[k]; k++) + ; + while (k>0) { + k--; + *pbp++ = makem(-((w[k] + w[k+1]) / 2)); + *pbp++ = o[k]; + } +} + + +void setbra(void) +{ + int k; + Tchar i, *j, dwn; + int cnt, delim; + Tchar brabuf[NC]; + + if (ismot(i = getch())) + return; + delim = cbits(i); + j = brabuf + 1; + cnt = 0; + if (NROFF) + dwn = (2 * t.Halfline) | MOT | VMOT; + else + dwn = EM | MOT | VMOT; + while ((k = cbits(i = getch())) != delim && k != '\n' && j <= brabuf + NC - 4) { + *j++ = i | ZBIT; + *j++ = dwn; + cnt++; + } + if (--cnt < 0) + return; + else if (!cnt) { + ch = *(j - 2); + return; + } + *j = 0; + if (NROFF) + *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT; + else + *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT; + *--j &= ~ZBIT; + pushback(brabuf); +} + + +void setvline(void) +{ + int i; + Tchar c, rem, ver, neg; + int cnt, delim, v; + Tchar vlbuf[NC]; + Tchar *vlp; + + if (ismot(c = getch())) + return; + delim = cbits(c); + dfact = lss; + vflag++; + i = quant(atoi0(), VERT); + dfact = 1; + if (!i) { + eat(delim); + vflag = 0; + return; + } + if ((cbits(c = getch())) == delim) { + c = BOXRULE | chbits; /*default box rule*/ + } else + getch(); + c |= ZBIT; + neg = 0; + if (i < 0) { + i = -i; + neg = NMOT; + } + if (NROFF) + v = 2 * t.Halfline; + else { + v = EM; + if (v < VERT) /* ATT EVK hack: Erik van Konijnenburg, */ + v = VERT; /* hvlpb!evkonij, ATT NSI Hilversum, Holland */ + } + + cnt = i / v; + rem = makem(i % v) | neg; + ver = makem(v) | neg; + vlp = vlbuf; + if (!neg) + *vlp++ = ver; + if (absmot(rem) != 0) { + *vlp++ = c; + *vlp++ = rem; + } + while (vlp < vlbuf + NC - 3 && cnt--) { + *vlp++ = c; + *vlp++ = ver; + } + *(vlp - 2) &= ~ZBIT; + if (!neg) + vlp--; + *vlp = 0; + pushback(vlbuf); + vflag = 0; +} + +#define NPAIR (NC/2-6) /* max pairs in spline, etc. */ + +void setdraw(void) /* generate internal cookies for a drawing function */ +{ + int i, j, k, dx[NPAIR], dy[NPAIR], delim, type; + Tchar c, drawbuf[NC]; + int drawch = '.'; /* character to draw with */ + + /* input is \D'f dx dy dx dy ... c' (or at least it had better be) */ + /* this does drawing function f with character c and the */ + /* specified dx,dy pairs interpreted as appropriate */ + /* pairs are deltas from last point, except for radii */ + + /* l dx dy: line from here by dx,dy */ + /* c x: circle of diameter x, left side here */ + /* e x y: ellipse of diameters x,y, left side here */ + /* a dx1 dy1 dx2 dy2: + ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */ + /* ~ dx1 dy1 dx2 dy2...: + spline to dx1,dy1 to dx2,dy2 ... */ + /* b x c: + built-up character of type c, ht x */ + /* f dx dy ...: f is any other char: like spline */ + + if (ismot(c = getch())) + return; + delim = cbits(c); + numerr.escarg = type = cbits(getch()); + if (type == '~') /* head off the .tr ~ problem */ + type = 's'; + for (i = 0; i < NPAIR ; i++) { + skip(); + vflag = 0; + dfact = EM; + dx[i] = quant(atoi0(), HOR); + if (dx[i] > MAXMOT) + dx[i] = MAXMOT; + else if (dx[i] < -MAXMOT) + dx[i] = -MAXMOT; + skip(); + if (type == 'c') { + dy[i] = 0; + goto eat; + } + vflag = 1; + dfact = lss; + dy[i] = quant(atoi0(), VERT); + if (dy[i] > MAXMOT) + dy[i] = MAXMOT; + else if (dy[i] < -MAXMOT) + dy[i] = -MAXMOT; +eat: + if (cbits(c = getch()) != ' ') { /* must be the end */ + if (cbits(c) != delim) { + drawch = cbits(c); + getch(); + } + i++; + break; + } + } + dfact = 1; + vflag = 0; + if (TROFF) { + drawbuf[0] = DRAWFCN | chbits | ZBIT; + drawbuf[1] = type | chbits | ZBIT; + drawbuf[2] = drawch | chbits | ZBIT; + for (k = 0, j = 3; k < i; k++) { + drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k])); + drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k])); + } + if (type == DRAWELLIPSE) { + drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */ + j = 6; + } else if (type == DRAWBUILD) { + drawbuf[4] = drawbuf[3] | NMOT; /* net horizontal motion is zero */ + drawbuf[2] &= ~ZBIT; /* width taken from drawing char */ + j = 5; + } + drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */ + drawbuf[j] = 0; + pushback(drawbuf); + } +} + + +void casefc(void) +{ + int i; + Tchar j; + + gchtab[fc] &= ~FCBIT; + fc = IMP; + padc = ' '; + if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n') + return; + fc = i; + gchtab[fc] |= FCBIT; + if (skip() || ismot(ch) || (ch = cbits(ch)) == fc) + return; + padc = ch; +} + + +Tchar setfield(int x) +{ + Tchar ii, jj, *fp; + int i, j; + int length, ws, npad, temp, type; + Tchar **pp, *padptr[NPP]; + Tchar fbuf[FBUFSZ]; + int savfc, savtc, savlc; + Tchar rchar; + int savepos; + static Tchar wbuf[] = { WORDSP, 0}; + + if (x == tabch) + rchar = tabc | chbits; + else if (x == ldrch) + rchar = dotc | chbits; + temp = npad = ws = 0; + savfc = fc; + savtc = tabch; + savlc = ldrch; + tabch = ldrch = fc = IMP; + savepos = numtabp[HP].val; + gchtab[tabch] &= ~TABBIT; + gchtab[ldrch] &= ~LDRBIT; + gchtab[fc] &= ~FCBIT; + gchtab[IMP] |= TABBIT|LDRBIT|FCBIT; + for (j = 0; ; j++) { + if ((tabtab[j] & TABMASK) == 0) { + if (x == savfc) + ERROR "zero field width." WARN; + jj = 0; + goto rtn; + } + if ((length = ((tabtab[j] & TABMASK) - numtabp[HP].val)) > 0 ) + break; + } + type = tabtab[j] & ~TABMASK; + fp = fbuf; + pp = padptr; + if (x == savfc) { + while (1) { + j = cbits(ii = getch()); + jj = width(ii); + widthp = jj; + numtabp[HP].val += jj; + if (j == padc) { + npad++; + *pp++ = fp; + if (pp > padptr + NPP - 1) + break; + goto s1; + } else if (j == savfc) + break; + else if (j == '\n') { + temp = j; + if (nlflg && ip == 0) { + numtabp[CD].val--; + nlflg = 0; + } + break; + } + ws += jj; +s1: + *fp++ = ii; + if (fp > fbuf + FBUFSZ - 3) + break; + } + if (ws) + *fp++ = WORDSP; + if (!npad) { + npad++; + *pp++ = fp; + *fp++ = 0; + } + *fp++ = temp; + *fp = 0; + temp = i = (j = length - ws) / npad; + i = (i / HOR) * HOR; + if ((j -= i * npad) < 0) + j = -j; + ii = makem(i); + if (temp < 0) + ii |= NMOT; + for (; npad > 0; npad--) { + *(*--pp) = ii; + if (j) { + j -= HOR; + (*(*pp)) += HOR; + } + } + pushback(fbuf); + jj = 0; + } else if (type == 0) { + /*plain tab or leader*/ + if ((j = width(rchar)) > 0) { + int nchar = length / j; + while (nchar-->0 && pbp < &pbbuf[NC-3]) { + numtabp[HP].val += j; + widthp = j; + *pbp++ = rchar; + } + length %= j; + } + if (length) + jj = length | MOT; + else + jj = getch0(); + if (savepos > 0) + pushback(wbuf); + } else { + /*center tab*/ + /*right tab*/ + while ((j = cbits(ii = getch())) != savtc && j != '\n' && j != savlc) { + jj = width(ii); + ws += jj; + numtabp[HP].val += jj; + widthp = jj; + *fp++ = ii; + if (fp > fbuf + FBUFSZ - 3) + break; + } + *fp++ = ii; + *fp = 0; + if (type == RTAB) + length -= ws; + else + length -= ws / 2; /*CTAB*/ + pushback(fbuf); + if ((j = width(rchar)) != 0 && length > 0) { + int nchar = length / j; + while (nchar-- > 0 && pbp < &pbbuf[NC-3]) + *pbp++ = rchar; + length %= j; + } + if (savepos > 0) + pushback(wbuf); + length = (length / HOR) * HOR; + jj = makem(length); + if (nlflg) { + if (ip == 0) + numtabp[CD].val--; + nlflg = 0; + } + } +rtn: + gchtab[fc] &= ~FCBIT; + gchtab[tabch] &= ~TABBIT; + gchtab[ldrch] &= ~LDRBIT; + fc = savfc; + tabch = savtc; + ldrch = savlc; + gchtab[fc] |= FCBIT; + gchtab[tabch] = TABBIT; + gchtab[ldrch] |= LDRBIT; + numtabp[HP].val = savepos; + return(jj); +} |