123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- #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);
- }
|