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