Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "tdef.h"
2
#include "ext.h"
3
#include "fns.h"
4
 
5
/*
6
 * troff9.c
7
 * 
8
 * misc functions
9
 */
10
 
11
Tchar setz(void)
12
{
13
	Tchar i;
14
 
15
	if (!ismot(i = getch()))
16
		i |= ZBIT;
17
	return(i);
18
}
19
 
20
void setline(void)
21
{
22
	Tchar *i;
23
	Tchar c;
24
	int length;
25
	int j, w, cnt, delim, rem, temp;
26
	Tchar linebuf[NC];
27
 
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;
38
	}
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);
50
	}
51
	i = linebuf;
52
	if (length < 0) {
53
		*i++ = makem(length);
54
		length = -length;
55
	}
56
	if (!(cnt = length / w)) {
57
		*i++ = makem(-(temp = ((w - length) / 2)));
58
		*i++ = c;
59
		*i++ = makem(-(w - length - temp));
60
		goto s1;
61
	}
62
	if (rem = length % w) {
63
		if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
64
			*i++ = c | ZBIT;
65
		*i++ = makem(rem);
66
	}
67
	if (cnt) {
68
		*i++ = RPT;
69
		*i++ = cnt;
70
		*i++ = c;
71
	}
72
s1:
73
	*i = 0;
74
	eat(delim);
75
	pushback(linebuf);
76
}
77
 
78
 
79
eat(int c)
80
{
81
	int i;
82
 
83
	while ((i = cbits(getch())) != c && i != '\n')
84
		;
85
	return(i);
86
}
87
 
88
 
89
void setov(void)
90
{
91
	int j, k;
92
	Tchar i, o[NOV+1];
93
	int delim, w[NOV+1];
94
 
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);
101
	}
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;
115
				}
116
			}
117
		}
118
	else 
119
		return;
120
	*pbp++ = makem(w[0] / 2);
121
	for (k = 0; o[k]; k++)
122
		;
123
	while (k>0) {
124
		k--;
125
		*pbp++ = makem(-((w[k] + w[k+1]) / 2));
126
		*pbp++ = o[k];
127
	}
128
}
129
 
130
 
131
void setbra(void)
132
{
133
	int k;
134
	Tchar i, *j, dwn;
135
	int cnt, delim;
136
	Tchar brabuf[NC];
137
 
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++;
151
	}
152
	if (--cnt < 0)
153
		return;
154
	else if (!cnt) {
155
		ch = *(j - 2);
156
		return;
157
	}
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);
165
}
166
 
167
 
168
void setvline(void)
169
{
170
	int i;
171
	Tchar c, rem, ver, neg;
172
	int cnt, delim, v;
173
	Tchar vlbuf[NC];
174
	Tchar *vlp;
175
 
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;
187
	}
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;
197
	}
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 */
204
	}
205
 
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
void setdraw(void)	/* 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
	int drawch = '.';	/* character to draw with */
235
 
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 */
240
 
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 */
251
 
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;
271
		}
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();
284
			}
285
			i++;
286
			break;
287
		}
288
	}
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]));
298
		}
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;
306
		}
307
		drawbuf[j++] = DRAWFCN | chbits | ZBIT;	/* marks end for ptout */
308
		drawbuf[j] = 0;
309
		pushback(drawbuf);
310
	}
311
}
312
 
313
 
314
void casefc(void)
315
{
316
	int i;
317
	Tchar j;
318
 
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;
329
}
330
 
331
 
332
Tchar setfield(int x)
333
{
334
	Tchar rchar, ii, jj, *fp;
335
	Tchar **pp, *padptr[NPP];
336
	Tchar fbuf[FBUFSZ];
337
	int i, j, length, ws, npad, temp, type, savepos, savfc, savtc, savlc;
338
	static Tchar wbuf[] = { WORDSP, 0};
339
 
340
	if (x == tabch) 
341
		rchar = tabc | chbits;
342
	else if (x == ldrch) 
343
		rchar = dotc | chbits;
344
	else
345
		rchar = 0;
346
	temp = npad = ws = 0;
347
	savfc = fc;
348
	savtc = tabch;
349
	savlc = ldrch;
350
	tabch = ldrch = fc = IMP;
351
	savepos = numtabp[HP].val;
352
	gchtab[tabch] &= ~TABBIT;
353
	gchtab[ldrch] &= ~LDRBIT;
354
	gchtab[fc] &= ~FCBIT;
355
	gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
356
	for (j = 0; ; j++) {
357
		if ((tabtab[j] & TABMASK) == 0) {
358
			if (x == savfc)
359
				ERROR "zero field width." WARN;
360
			jj = 0;
361
			goto rtn;
362
		}
363
		if ((length = ((tabtab[j] & TABMASK) - numtabp[HP].val)) > 0 )
364
			break;
365
	}
366
	type = tabtab[j] & ~TABMASK;
367
	fp = fbuf;
368
	pp = padptr;
369
	if (x == savfc) {
370
		while (1) {
371
			j = cbits(ii = getch());
372
			jj = width(ii);
373
			widthp = jj;
374
			numtabp[HP].val += jj;
375
			if (j == padc) {
376
				npad++;
377
				*pp++ = fp;
378
				if (pp > padptr + NPP - 1)
379
					break;
380
				goto s1;
381
			} else if (j == savfc) 
382
				break;
383
			else if (j == '\n') {
384
				temp = j;
385
				if (nlflg && ip == 0) {
386
					numtabp[CD].val--;
387
					nlflg = 0;
388
				}
389
				break;
390
			}
391
			ws += jj;
392
s1:
393
			*fp++ = ii;
394
			if (fp > fbuf + FBUFSZ - 3)
395
				break;
396
		}
397
		if (ws)
398
			*fp++ = WORDSP;
399
		if (!npad) {
400
			npad++;
401
			*pp++ = fp;
402
			*fp++ = 0;
403
		}
404
		*fp++ = temp;
405
		*fp = 0;
406
		temp = i = (j = length - ws) / npad;
407
		i = (i / HOR) * HOR;
408
		if ((j -= i * npad) < 0)
409
			j = -j;
410
		ii = makem(i);
411
		if (temp < 0)
412
			ii |= NMOT;
413
		for (; npad > 0; npad--) {
414
			*(*--pp) = ii;
415
			if (j) {
416
				j -= HOR;
417
				(*(*pp)) += HOR;
418
			}
419
		}
420
		pushback(fbuf);
421
		jj = 0;
422
	} else if (type == 0) {
423
		/*plain tab or leader*/
424
		if ((j = width(rchar)) > 0) {
425
			int nchar = length / j;
426
			while (nchar-->0 && pbp < &pbbuf[NC-3]) {
427
				numtabp[HP].val += j;
428
				widthp = j;
429
				*pbp++ = rchar;
430
			}
431
			length %= j;
432
		}
433
		if (length)
434
			jj = length | MOT;
435
		else 
436
			jj = getch0();
437
		if (savepos > 0)
438
			pushback(wbuf);
439
	} else {
440
		/*center tab*/
441
		/*right tab*/
442
		while ((j = cbits(ii = getch())) != savtc && j != '\n' && j != savlc) {
443
			jj = width(ii);
444
			ws += jj;
445
			numtabp[HP].val += jj;
446
			widthp = jj;
447
			*fp++ = ii;
448
			if (fp > fbuf + FBUFSZ - 3) 
449
				break;
450
		}
451
		*fp++ = ii;
452
		*fp = 0;
453
		if (type == RTAB)
454
			length -= ws;
455
		else 
456
			length -= ws / 2; /*CTAB*/
457
		pushback(fbuf);
458
		if ((j = width(rchar)) != 0 && length > 0) {
459
			int nchar = length / j;
460
			while (nchar-- > 0 && pbp < &pbbuf[NC-3])
461
				*pbp++ = rchar;
462
			length %= j;
463
		}
464
		if (savepos > 0)
465
			pushback(wbuf);
466
		length = (length / HOR) * HOR;
467
		jj = makem(length);
468
		if (nlflg) {
469
			if (ip == 0)
470
				numtabp[CD].val--;
471
			nlflg = 0;
472
		}
473
	}
474
rtn:
475
	gchtab[fc] &= ~FCBIT;
476
	gchtab[tabch] &= ~TABBIT;
477
	gchtab[ldrch] &= ~LDRBIT;
478
	fc = savfc;
479
	tabch = savtc;
480
	ldrch = savlc;
481
	gchtab[fc] |= FCBIT;
482
	gchtab[tabch] = TABBIT;
483
	gchtab[ldrch] |= LDRBIT;
484
	numtabp[HP].val = savepos;
485
	return(jj);
486
}