|
|
1.1 root 1: #include "tdef.h"
2: #include "ext.h"
3: #include "fns.h"
4:
5: /*
6: * troff9.c
7: *
8: * misc functions
9: */
10:
11: Tchar setz(void)
12: {
13: Tchar i;
14:
15: if (!ismot(i = getch()))
16: i |= ZBIT;
17: return(i);
18: }
19:
20: void setline(void)
21: {
22: Tchar *i;
23: Tchar c;
24: int length;
25: int j, w, cnt, delim, rem, temp;
26: Tchar linebuf[NC];
27:
28: if (ismot(c = getch()))
29: return;
30: delim = cbits(c);
31: vflag = 0;
32: dfact = EM;
33: length = quant(atoi0(), HOR);
34: dfact = 1;
35: if (!length) {
36: eat(delim);
37: return;
38: }
39: s0:
40: if ((j = cbits(c = getch())) == delim || j == '\n') {
41: ch = c;
42: c = RULE | chbits;
43: } else if (cbits(c) == FILLER)
44: goto s0;
45: w = width(c);
46: if (w <= 0) {
47: ERROR "zero-width underline character ignored" WARN;
48: c = RULE | chbits;
49: w = width(c);
50: }
51: i = linebuf;
52: if (length < 0) {
53: *i++ = makem(length);
54: length = -length;
55: }
56: if (!(cnt = length / w)) {
57: *i++ = makem(-(temp = ((w - length) / 2)));
58: *i++ = c;
59: *i++ = makem(-(w - length - temp));
60: goto s1;
61: }
62: if (rem = length % w) {
63: if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
64: *i++ = c | ZBIT;
65: *i++ = makem(rem);
66: }
67: if (cnt) {
68: *i++ = RPT;
69: *i++ = cnt;
70: *i++ = c;
71: }
72: s1:
73: *i = 0;
74: eat(delim);
75: pushback(linebuf);
76: }
77:
78:
79: eat(int c)
80: {
81: int i;
82:
83: while ((i = cbits(getch())) != c && i != '\n')
84: ;
85: return(i);
86: }
87:
88:
89: void setov(void)
90: {
91: int j, k;
92: Tchar i, o[NOV+1];
93: int delim, w[NOV+1];
94:
95: if (ismot(i = getch()))
96: return;
97: delim = cbits(i);
98: for (k = 0; k < NOV && (j = cbits(i = getch())) != delim && j != '\n'; k++) {
99: o[k] = i;
100: w[k] = width(i);
101: }
102: o[k] = w[k] = 0;
103: if (o[0])
104: for (j = 1; j; ) {
105: j = 0;
106: for (k = 1; o[k] ; k++) {
107: if (w[k-1] < w[k]) {
108: j++;
109: i = w[k];
110: w[k] = w[k-1];
111: w[k-1] = i;
112: i = o[k];
113: o[k] = o[k-1];
114: o[k-1] = i;
115: }
116: }
117: }
118: else
119: return;
120: *pbp++ = makem(w[0] / 2);
121: for (k = 0; o[k]; k++)
122: ;
123: while (k>0) {
124: k--;
125: *pbp++ = makem(-((w[k] + w[k+1]) / 2));
126: *pbp++ = o[k];
127: }
128: }
129:
130:
131: void setbra(void)
132: {
133: int k;
134: Tchar i, *j, dwn;
135: int cnt, delim;
136: Tchar brabuf[NC];
137:
138: if (ismot(i = getch()))
139: return;
140: delim = cbits(i);
141: j = brabuf + 1;
142: cnt = 0;
143: if (NROFF)
144: dwn = (2 * t.Halfline) | MOT | VMOT;
145: else
146: dwn = EM | MOT | VMOT;
147: while ((k = cbits(i = getch())) != delim && k != '\n' && j <= brabuf + NC - 4) {
148: *j++ = i | ZBIT;
149: *j++ = dwn;
150: cnt++;
151: }
152: if (--cnt < 0)
153: return;
154: else if (!cnt) {
155: ch = *(j - 2);
156: return;
157: }
158: *j = 0;
159: if (NROFF)
160: *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
161: else
162: *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
163: *--j &= ~ZBIT;
164: pushback(brabuf);
165: }
166:
167:
168: void setvline(void)
169: {
170: int i;
171: Tchar c, rem, ver, neg;
172: int cnt, delim, v;
173: Tchar vlbuf[NC];
174: Tchar *vlp;
175:
176: if (ismot(c = getch()))
177: return;
178: delim = cbits(c);
179: dfact = lss;
180: vflag++;
181: i = quant(atoi0(), VERT);
182: dfact = 1;
183: if (!i) {
184: eat(delim);
185: vflag = 0;
186: return;
187: }
188: if ((cbits(c = getch())) == delim) {
189: c = BOXRULE | chbits; /*default box rule*/
190: } else
191: getch();
192: c |= ZBIT;
193: neg = 0;
194: if (i < 0) {
195: i = -i;
196: neg = NMOT;
197: }
198: if (NROFF)
199: v = 2 * t.Halfline;
200: else {
201: v = EM;
202: if (v < VERT) /* ATT EVK hack: Erik van Konijnenburg, */
203: v = VERT; /* hvlpb!evkonij, ATT NSI Hilversum, Holland */
204: }
205:
206: cnt = i / v;
207: rem = makem(i % v) | neg;
208: ver = makem(v) | neg;
209: vlp = vlbuf;
210: if (!neg)
211: *vlp++ = ver;
212: if (absmot(rem) != 0) {
213: *vlp++ = c;
214: *vlp++ = rem;
215: }
216: while (vlp < vlbuf + NC - 3 && cnt--) {
217: *vlp++ = c;
218: *vlp++ = ver;
219: }
220: *(vlp - 2) &= ~ZBIT;
221: if (!neg)
222: vlp--;
223: *vlp = 0;
224: pushback(vlbuf);
225: vflag = 0;
226: }
227:
228: #define NPAIR (NC/2-6) /* max pairs in spline, etc. */
229:
230: void setdraw(void) /* generate internal cookies for a drawing function */
231: {
232: int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
233: Tchar c, drawbuf[NC];
234: int drawch = '.'; /* character to draw with */
235:
236: /* input is \D'f dx dy dx dy ... c' (or at least it had better be) */
237: /* this does drawing function f with character c and the */
238: /* specified dx,dy pairs interpreted as appropriate */
239: /* pairs are deltas from last point, except for radii */
240:
241: /* l dx dy: line from here by dx,dy */
242: /* c x: circle of diameter x, left side here */
243: /* e x y: ellipse of diameters x,y, left side here */
244: /* a dx1 dy1 dx2 dy2:
245: ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */
246: /* ~ dx1 dy1 dx2 dy2...:
247: spline to dx1,dy1 to dx2,dy2 ... */
248: /* b x c:
249: built-up character of type c, ht x */
250: /* f dx dy ...: f is any other char: like spline */
251:
252: if (ismot(c = getch()))
253: return;
254: delim = cbits(c);
255: type = cbits(getch());
256: if (type == '~') /* head off the .tr ~ problem */
257: type = 's';
258: for (i = 0; i < NPAIR ; i++) {
259: skip();
260: vflag = 0;
261: dfact = EM;
262: dx[i] = quant(atoi0(), HOR);
263: if (dx[i] > MAXMOT)
264: dx[i] = MAXMOT;
265: else if (dx[i] < -MAXMOT)
266: dx[i] = -MAXMOT;
267: skip();
268: vflag = 1;
269: dfact = lss;
270: dy[i] = quant(atoi0(), VERT);
271: if (dy[i] > MAXMOT)
272: dy[i] = MAXMOT;
273: else if (dy[i] < -MAXMOT)
274: dy[i] = -MAXMOT;
275: if (cbits(c = getch()) != ' ') { /* must be the end */
276: if (cbits(c) != delim) {
277: drawch = cbits(c);
278: getch();
279: }
280: i++;
281: break;
282: }
283: }
284: dfact = 1;
285: vflag = 0;
286: if (TROFF) {
287: drawbuf[0] = DRAWFCN | chbits | ZBIT;
288: drawbuf[1] = type | chbits | ZBIT;
289: drawbuf[2] = drawch | chbits | ZBIT;
290: for (k = 0, j = 3; k < i; k++) {
291: drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
292: drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
293: }
294: if (type == DRAWELLIPSE) {
295: drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */
296: j = 6;
297: } else if (type == DRAWBUILD) {
298: drawbuf[4] = drawbuf[3] | NMOT; /* net horizontal motion is zero */
299: drawbuf[2] &= ~ZBIT; /* width taken from drawing char */
300: j = 5;
301: }
302: drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */
303: drawbuf[j] = 0;
304: pushback(drawbuf);
305: }
306: }
307:
308:
309: void casefc(void)
310: {
311: int i;
312: Tchar j;
313:
314: gchtab[fc] &= ~FCBIT;
315: fc = IMP;
316: padc = ' ';
317: if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
318: return;
319: fc = i;
320: gchtab[fc] |= FCBIT;
321: if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
322: return;
323: padc = ch;
324: }
325:
326:
327: Tchar setfield(int x)
328: {
329: Tchar ii, jj, *fp;
330: int i, j;
331: int length, ws, npad, temp, type;
332: Tchar **pp, *padptr[NPP];
333: Tchar fbuf[FBUFSZ];
334: int savfc, savtc, savlc;
335: Tchar rchar;
336: int savepos;
337:
338: if (x == tabch)
339: rchar = tabc | chbits;
340: else if (x == ldrch)
341: rchar = dotc | chbits;
342: temp = npad = ws = 0;
343: savfc = fc;
344: savtc = tabch;
345: savlc = ldrch;
346: tabch = ldrch = fc = IMP;
347: savepos = numtab[HP].val;
348: gchtab[tabch] &= ~TABBIT;
349: gchtab[ldrch] &= ~LDRBIT;
350: gchtab[fc] &= ~FCBIT;
351: gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
352: for (j = 0; ; j++) {
353: if ((tabtab[j] & TABMASK) == 0) {
354: if (x == savfc)
355: ERROR "zero field width." WARN;
356: jj = 0;
357: goto rtn;
358: }
359: if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 )
360: break;
361: }
362: type = tabtab[j] & ~TABMASK;
363: fp = fbuf;
364: pp = padptr;
365: if (x == savfc) {
366: while (1) {
367: j = cbits(ii = getch());
368: jj = width(ii);
369: widthp = jj;
370: numtab[HP].val += jj;
371: if (j == padc) {
372: npad++;
373: *pp++ = fp;
374: if (pp > padptr + NPP - 1)
375: break;
376: goto s1;
377: } else if (j == savfc)
378: break;
379: else if (j == '\n') {
380: temp = j;
381: nlflg = 0;
382: break;
383: }
384: ws += jj;
385: s1:
386: *fp++ = ii;
387: if (fp > fbuf + FBUFSZ - 3)
388: break;
389: }
390: if (!npad) {
391: npad++;
392: *pp++ = fp;
393: *fp++ = 0;
394: }
395: *fp++ = temp;
396: *fp = 0;
397: temp = i = (j = length - ws) / npad;
398: i = (i / HOR) * HOR;
399: if ((j -= i * npad) < 0)
400: j = -j;
401: ii = makem(i);
402: if (temp < 0)
403: ii |= NMOT;
404: for (; npad > 0; npad--) {
405: *(*--pp) = ii;
406: if (j) {
407: j -= HOR;
408: (*(*pp)) += HOR;
409: }
410: }
411: pushback(fbuf);
412: jj = 0;
413: } else if (type == 0) {
414: /*plain tab or leader*/
415: if ((j = width(rchar)) > 0) {
416: int nchar = length / j;
417: while (nchar-->0 && pbp < &pbbuf[NC-3]) {
418: numtab[HP].val += j;
419: widthp = j;
420: *pbp++ = rchar;
421: }
422: length %= j;
423: }
424: if (length)
425: jj = length | MOT;
426: else
427: jj = getch0();
428: } else {
429: /*center tab*/
430: /*right tab*/
431: while ((j = cbits(ii = getch())) != savtc && j != '\n' && j != savlc) {
432: jj = width(ii);
433: ws += jj;
434: numtab[HP].val += jj;
435: widthp = jj;
436: *fp++ = ii;
437: if (fp > fbuf + FBUFSZ - 3)
438: break;
439: }
440: *fp++ = ii;
441: *fp = 0;
442: if (type == RTAB)
443: length -= ws;
444: else
445: length -= ws / 2; /*CTAB*/
446: pushback(fbuf);
447: if ((j = width(rchar)) != 0 && length > 0) {
448: int nchar = length / j;
449: while (nchar-- > 0 && pbp < &pbbuf[NC-3])
450: *pbp++ = rchar;
451: length %= j;
452: }
453: length = (length / HOR) * HOR;
454: jj = makem(length);
455: nlflg = 0;
456: }
457: rtn:
458: gchtab[fc] &= ~FCBIT;
459: gchtab[tabch] &= ~TABBIT;
460: gchtab[ldrch] &= ~LDRBIT;
461: fc = savfc;
462: tabch = savtc;
463: ldrch = savlc;
464: gchtab[fc] |= FCBIT;
465: gchtab[tabch] = TABBIT;
466: gchtab[ldrch] |= LDRBIT;
467: numtab[HP].val = savepos;
468: return(jj);
469: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.