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+1];
97 	int	delim, w[NOV+1];
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[NC / 2], dy[NC / 2], 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 	/* p s x y ...:	for polygons filled with stipple s */
249 
250 	if (ismot(c = getch()))
251 		return;
252 	delim = cbits(c);
253 	type = cbits(getch());
254 	for (i = 0; ; i++) {
255 		if (i > (NC / 2 - 3))
256 			i--;
257 		if (nlflg)
258 			break;
259 		c = getch();
260 		if (cbits(c) == delim)
261 			break;
262 		if (cbits(c) != ' ')
263 			ch = c;
264 		vflag = 0;
265 		if (i == 0 && (type == DRAWPOLY || type == DRAWUBPOLY)) {
266 			dfact = 1;
267 			dx[0] = quant(atoi(), 1);
268 			if (dx[0] < 0 || dx[0] > MAXMOT)
269 				dx[0] = 0;
270 			dy[0] = 0;
271 			continue;
272 		}
273 		dfact = EM;
274 		dx[i] = quant(atoi(), HOR);
275 		if (dx[i] > MAXMOT)
276 			dx[i] = MAXMOT;
277 		else if (dx[i] < -MAXMOT)
278 			dx[i] = -MAXMOT;
279 		if (cbits((c = getch())) == delim) {	/* spacer */
280 			dy[i++] = 0;
281 			break;
282 		}
283 		vflag = 1;
284 		dfact = lss;
285 		dy[i] = quant(atoi(), VERT);
286 		if (dy[i] > MAXMOT)
287 			dy[i] = MAXMOT;
288 		else if (dy[i] < -MAXMOT)
289 			dy[i] = -MAXMOT;
290 	}
291 	dfact = 1;
292 	vflag = 0;
293 #ifndef NROFF
294 	cbuf[0] = DRAWFCN | chbits | ZBIT;
295 	cbuf[1] = type | chbits | ZBIT;
296 	for (k = 0, j = 2; k < i; k++) {
297 		cbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
298 		cbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
299 	}
300 	if (type == DRAWELLIPSE) {
301 		cbuf[4] = cbuf[3] | NMOT;	/* so net vertical is zero */
302 		j = 5;
303 	} else if (type == DRAWTHICK || type == DRAWSTYLE) {
304 		cbuf[3] = cbuf[2] | NMOT;	/* so net horizontal is zero */
305 	}
306 	cbuf[j++] = '.' | chbits | ZBIT;	/* marks end for ptout */
307 	cbuf[j] = 0;
308 	cp = cbuf;
309 #endif
310 }
311 
312 
313 casefc()
314 {
315 	register i;
316 	tchar j;
317 
318 	fc = IMP;
319 	padc = ' ';
320 	if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
321 		return;
322 	fc = i;
323 	if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
324 		return;
325 	padc = ch;
326 }
327 
328 
329 tchar setfield(x)
330 int	x;
331 {
332 	tchar ii, jj, *fp;
333 	register i, j;
334 	int	length, ws, npad, temp, type;
335 	tchar * *pp, *padptr[NPP];
336 	static tchar fbuf[FBUFSZ];
337 	int	savfc, savtc, savlc;
338 
339 	if (x == tabch)
340 		rchar = tabc | chbits;
341 	else if (x ==  ldrch)
342 		rchar = dotc | chbits;
343 	temp = npad = ws = 0;
344 	savfc = fc;
345 	savtc = tabch;
346 	savlc = ldrch;
347 	tabch = ldrch = fc = IMP;
348 	for (j = 0; ; j++) {
349 		if ((tabtab[j] & TMASK) == 0) {
350 			if (x == savfc)
351 				fprintf(stderr, "troff: zero field width.\n");
352 			jj = 0;
353 			goto rtn;
354 		}
355 		v.hp = sumhp();	/* XXX */
356 		if ((length = ((tabtab[j] & TMASK) - v.hp)) > 0 )
357 			break;
358 	}
359 	type = tabtab[j] & (~TMASK);
360 	fp = fbuf;
361 	pp = padptr;
362 	if (x == savfc) {
363 		while (1) {
364 			if (((j = cbits(ii = getch()))) == 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 += width(ii);
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 		cp = fbuf;
405 		jj = 0;
406 	} else if (type == 0) {
407 		/*plain tab or leader*/
408 		if ((j = width(rchar)) == 0)
409 			nchar = 0;
410 		else {
411 			nchar = length / j;
412 			length %= j;
413 		}
414 		if (length)
415 			jj = length | MOT;
416 		else
417 			jj = getch0();
418 	} else {
419 		/*center tab*/
420 		/*right tab*/
421 		while (((j = cbits(ii = getch())) != savtc) &&  (j != '\n') && (j != savlc)) {
422 			ws += width(ii);
423 			*fp++ = ii;
424 			if (fp > (fbuf + FBUFSZ - 3))
425 				break;
426 		}
427 		*fp++ = ii;
428 		*fp++ = 0;
429 		if (type == RTAB)
430 			length -= ws;
431 		else
432 			length -= ws / 2; /*CTAB*/
433 		if (((j = width(rchar)) == 0) || (length <= 0))
434 			nchar = 0;
435 		else {
436 			nchar = length / j;
437 			length %= j;
438 		}
439 		length = (length / HOR) * HOR;
440 		jj = makem(length);
441 		cp = fbuf;
442 		nlflg = 0;
443 	}
444 rtn:
445 	fc = savfc;
446 	tabch = savtc;
447 	ldrch = savlc;
448 	return(jj);
449 }
450 
451 
452