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