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