mkdev: remove devutf/C*
[troff.git] / troff / n9.c
blobc78f7c430d0abb1ee6d1611489182dc08ccb8908
1 #include "tdef.h"
2 #include "ext.h"
3 #include "fns.h"
5 /*
6 * troff9.c
7 *
8 * misc functions
9 */
11 Tchar setz(void)
13 Tchar i;
15 if (!ismot(i = getch()))
16 i |= ZBIT;
17 return i;
20 void setline(void)
22 Tchar *i;
23 Tchar c;
24 int length;
25 int j, w, cnt, delim, rem, temp;
26 Tchar linebuf[NC];
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;
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);
51 i = linebuf;
52 if (length < 0) {
53 *i++ = makem(length);
54 length = -length;
56 if (!(cnt = length / w)) {
57 *i++ = makem(-(temp = ((w - length) / 2)));
58 *i++ = c;
59 *i++ = makem(-(w - length - temp));
60 goto s1;
62 if (rem = length % w) {
63 if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
64 *i++ = c | ZBIT;
65 *i++ = makem(rem);
67 if (cnt) {
68 *i++ = RPT;
69 *i++ = cnt;
70 *i++ = c;
72 s1:
73 *i = 0;
74 eat(delim);
75 pushback(linebuf);
79 int eat(int c)
81 int i;
83 while ((i = cbits(getch())) != c && i != '\n')
85 return i;
89 void setov(void)
91 int j, k;
92 Tchar i, o[NOV+1];
93 int delim, w[NOV+1];
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);
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;
118 else
119 return;
120 *pbp++ = makem(w[0] / 2);
121 for (k = 0; o[k]; k++)
123 while (k>0) {
124 k--;
125 *pbp++ = makem(-((w[k] + w[k+1]) / 2));
126 *pbp++ = o[k];
131 void setbra(void)
133 int k;
134 Tchar i, *j, dwn;
135 int cnt, delim;
136 Tchar brabuf[NC];
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++;
152 if (--cnt < 0)
153 return;
154 else if (!cnt) {
155 ch = *(j - 2);
156 return;
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);
168 void setvline(void)
170 int i;
171 Tchar c, rem, ver, neg;
172 int cnt, delim, v;
173 Tchar vlbuf[NC];
174 Tchar *vlp;
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;
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;
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 */
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;
216 while (vlp < vlbuf + NC - 3 && cnt--) {
217 *vlp++ = c;
218 *vlp++ = ver;
220 *(vlp - 2) &= ~ZBIT;
221 if (!neg)
222 vlp--;
223 *vlp = 0;
224 pushback(vlbuf);
225 vflag = 0;
228 #define NPAIR (NC/2-6) /* max pairs in spline, etc. */
230 void setdraw(void) /* generate internal cookies for a drawing function */
232 int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
233 Tchar c, drawbuf[NC];
234 int drawch = '.'; /* character to draw with */
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 */
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 */
252 if (ismot(c = getch()))
253 return;
254 delim = cbits(c);
255 numerr.escarg = 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 if (type == 'c') {
269 dy[i] = 0;
270 goto eat;
272 vflag = 1;
273 dfact = lss;
274 dy[i] = quant(atoi0(), VERT);
275 if (dy[i] > MAXMOT)
276 dy[i] = MAXMOT;
277 else if (dy[i] < -MAXMOT)
278 dy[i] = -MAXMOT;
279 eat:
280 if (cbits(c = getch()) != ' ') { /* must be the end */
281 if (cbits(c) != delim) {
282 drawch = cbits(c);
283 getch();
285 i++;
286 break;
289 dfact = 1;
290 vflag = 0;
291 if (TROFF) {
292 drawbuf[0] = DRAWFCN | chbits | ZBIT;
293 drawbuf[1] = type | chbits | ZBIT;
294 drawbuf[2] = drawch | chbits | ZBIT;
295 for (k = 0, j = 3; k < i; k++) {
296 drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
297 drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
299 if (type == DRAWELLIPSE) {
300 drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */
301 j = 6;
302 } else if (type == DRAWBUILD) {
303 drawbuf[4] = drawbuf[3] | NMOT; /* net horizontal motion is zero */
304 drawbuf[2] &= ~ZBIT; /* width taken from drawing char */
305 j = 5;
307 drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */
308 drawbuf[j] = 0;
309 pushback(drawbuf);
314 void casefc(void)
316 int i;
317 Tchar j;
319 gchtab[fc] &= ~FCBIT;
320 fc = IMP;
321 padc = ' ';
322 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
323 return;
324 fc = i;
325 gchtab[fc] |= FCBIT;
326 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
327 return;
328 padc = ch;
332 Tchar setfield(int x)
334 Tchar ii, jj, *fp;
335 int i, j;
336 int length, ws, npad, temp, type;
337 Tchar **pp, *padptr[NPP];
338 Tchar fbuf[FBUFSZ];
339 int savfc, savtc, savlc;
340 Tchar rchar;
341 int savepos;
342 static Tchar wbuf[] = { WORDSP, 0};
344 if (x == tabch)
345 rchar = tabc | chbits;
346 else if (x == ldrch)
347 rchar = dotc | chbits;
348 temp = npad = ws = 0;
349 savfc = fc;
350 savtc = tabch;
351 savlc = ldrch;
352 tabch = ldrch = fc = IMP;
353 savepos = numtabp[HP].val;
354 gchtab[tabch] &= ~TABBIT;
355 gchtab[ldrch] &= ~LDRBIT;
356 gchtab[fc] &= ~FCBIT;
357 gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
358 for (j = 0; ; j++) {
359 if ((tabtab[j] & TABMASK) == 0) {
360 if (x == savfc)
361 ERROR "zero field width." WARN;
362 jj = 0;
363 goto rtn;
365 if ((length = ((tabtab[j] & TABMASK) - numtabp[HP].val)) > 0 )
366 break;
368 type = tabtab[j] & ~TABMASK;
369 fp = fbuf;
370 pp = padptr;
371 if (x == savfc) {
372 while (1) {
373 j = cbits(ii = getch());
374 jj = width(ii);
375 widthp = jj;
376 numtabp[HP].val += jj;
377 if (j == padc) {
378 npad++;
379 *pp++ = fp;
380 if (pp > padptr + NPP - 1)
381 break;
382 goto s1;
383 } else if (j == savfc)
384 break;
385 else if (j == '\n') {
386 temp = j;
387 if (nlflg && ip == 0) {
388 numtabp[CD].val--;
389 nlflg = 0;
391 break;
393 ws += jj;
395 *fp++ = ii;
396 if (fp > fbuf + FBUFSZ - 3)
397 break;
399 if (ws)
400 *fp++ = WORDSP;
401 if (!npad) {
402 npad++;
403 *pp++ = fp;
404 *fp++ = 0;
406 *fp++ = temp;
407 *fp = 0;
408 temp = i = (j = length - ws) / npad;
409 i = (i / HOR) * HOR;
410 if ((j -= i * npad) < 0)
411 j = -j;
412 ii = makem(i);
413 if (temp < 0)
414 ii |= NMOT;
415 for (; npad > 0; npad--) {
416 *(*--pp) = ii;
417 if (j) {
418 j -= HOR;
419 (*(*pp)) += HOR;
422 pushback(fbuf);
423 jj = 0;
424 } else if (type == 0) {
425 /*plain tab or leader*/
426 if ((j = width(rchar)) > 0) {
427 int nchar = length / j;
428 while (nchar-->0 && pbp < &pbbuf[NC-3]) {
429 numtabp[HP].val += j;
430 widthp = j;
431 *pbp++ = rchar;
433 length %= j;
435 if (length)
436 jj = length | MOT;
437 else
438 jj = getch0();
439 if (savepos > 0)
440 pushback(wbuf);
441 } else {
442 /*center tab*/
443 /*right tab*/
444 while ((j = cbits(ii = getch())) != savtc && j != '\n' && j != savlc) {
445 jj = width(ii);
446 ws += jj;
447 numtabp[HP].val += jj;
448 widthp = jj;
449 *fp++ = ii;
450 if (fp > fbuf + FBUFSZ - 3)
451 break;
453 *fp++ = ii;
454 *fp = 0;
455 if (type == RTAB)
456 length -= ws;
457 else
458 length -= ws / 2; /*CTAB*/
459 pushback(fbuf);
460 if ((j = width(rchar)) != 0 && length > 0) {
461 int nchar = length / j;
462 while (nchar-- > 0 && pbp < &pbbuf[NC-3])
463 *pbp++ = rchar;
464 length %= j;
466 if (savepos > 0)
467 pushback(wbuf);
468 length = (length / HOR) * HOR;
469 jj = makem(length);
470 if (nlflg) {
471 if (ip == 0)
472 numtabp[CD].val--;
473 nlflg = 0;
476 rtn:
477 gchtab[fc] &= ~FCBIT;
478 gchtab[tabch] &= ~TABBIT;
479 gchtab[ldrch] &= ~LDRBIT;
480 fc = savfc;
481 tabch = savtc;
482 ldrch = savlc;
483 gchtab[fc] |= FCBIT;
484 gchtab[tabch] = TABBIT;
485 gchtab[ldrch] |= LDRBIT;
486 numtabp[HP].val = savepos;
487 return jj;