xref: /plan9/sys/src/cmd/troff/n6.c (revision 14f51593fd82e19ba95969a8c07ff71131015979)
1 #include "tdef.h"
2 #include "ext.h"
3 #include "fns.h"
4 #include <ctype.h>
5 
6 /*
7  * n6.c -- width functions, sizes and fonts
8 */
9 
n_width(Tchar j)10 n_width(Tchar j)
11 {
12 	int i, k;
13 
14 	if (iszbit(j))
15 		return 0;
16 	if (ismot(j)) {
17 		if (isvmot(j))
18 			return(0);
19 		k = absmot(j);
20 		if (isnmot(j))
21 			k = -k;
22 		return(k);
23 	}
24 	i = cbits(j);
25 	if (i < ' ') {
26 		if (i == '\b')
27 			return(-widthp);
28 		if (i == PRESC)
29 			i = eschar;
30 		else if (i == HX)
31 			return(0);
32 	}
33 	if (i == ohc)
34 		return(0);
35 	i = trtab[i];
36 	if (i < ' ')
37 		return(0);
38 	if (i >= t.tfont.nchars)	/* not on the font */
39 		k = t.Char;		/* really ought to check properly */
40 	else
41 		k = t.tfont.wp[i].wid * t.Char;
42 	widthp = k;
43 	return(k);
44 }
45 
46 
n_setch(int c)47 Tchar n_setch(int c)
48 {
49 	return t_setch(c);
50 }
51 
n_setabs(void)52 Tchar n_setabs(void)	/* set absolute char from \N'...' */
53 {			/* for now, a no-op */
54 	return t_setabs();
55 }
56 
n_findft(int i)57 int n_findft(int i)
58 {
59 	int k;
60 
61 	if ((k = i - '0') >= 0 && k <= nfonts && k < smnt)
62 		return(k);
63 	for (k = 0; fontlab[k] != i; k++)
64 		if (k > nfonts)
65 			return(-1);
66 	return(k);
67 }
68 
69 
70 
n_mchbits(void)71 void n_mchbits(void)
72 {
73 	chbits = 0;
74 	setfbits(chbits, font);
75 	sps = width(' ' | chbits);
76 }
77 
78 
n_setps(void)79 void n_setps(void )
80 {
81 	int i, j;
82 
83 	i = cbits(getch());
84 	if (isdigit(i)) {		/* \sd or \sdd */
85 		i -= '0';
86 		if (i == 0) {		/* \s0 */
87 			;
88 		} else if (i <= 3 && (ch=getch()) && isdigit(cbits(ch))) {	/* \sdd */
89 			ch = 0;
90 		}
91 	} else if (i == '(') {		/* \s(dd */
92 		getch();
93 		getch();
94 	} else if (i == '+' || i == '-') {	/* \s+, \s- */
95 		j = cbits(getch());
96 		if (isdigit(j)) {		/* \s+d, \s-d */
97 			;
98 		} else if (j == '(') {		/* \s+(dd, \s-(dd */
99 			getch();
100 			getch();
101 		}
102 	}
103 }
104 
105 
n_setht(void)106 Tchar n_setht(void)		/* set character height from \H'...' */
107 {
108 
109 	getch();
110 	inumb(&apts);
111 	getch();
112 	return(0);
113 }
114 
115 
n_setslant(void)116 Tchar n_setslant(void)		/* set slant from \S'...' */
117 {
118 	int n;
119 
120 	getch();
121 	n = 0;
122 	n = inumb(&n);
123 	getch();
124 	return(0);
125 }
126 
127 
n_caseft(void)128 void n_caseft(void)
129 {
130 	skip();
131 	setfont(1);
132 }
133 
134 
n_setfont(int a)135 void n_setfont(int a)
136 {
137 	int i, j;
138 
139 	if (a)
140 		i = getrq();
141 	else
142 		i = getsn();
143 	if (!i || i == 'P') {
144 		j = font1;
145 		goto s0;
146 	}
147 	if (i == 'S' || i == '0')
148 		return;
149 	if ((j = findft(i)) == -1)
150 		return;
151 s0:
152 	font1 = font;
153 	font = j;
154 	mchbits();
155 }
156 
157 
n_setwd(void)158 void n_setwd(void)
159 {
160 	int base, wid;
161 	Tchar i;
162 	int	delim, emsz, k;
163 	int	savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
164 
165 	base = numtabp[ST].val = numtabp[ST].val = wid = numtabp[CT].val = 0;
166 	if (ismot(i = getch()))
167 		return;
168 	delim = cbits(i);
169 	savhp = numtabp[HP].val;
170 	numtabp[HP].val = 0;
171 	savapts = apts;
172 	savapts1 = apts1;
173 	savfont = font;
174 	savfont1 = font1;
175 	savpts = pts;
176 	savpts1 = pts1;
177 	setwdf++;
178 	while (cbits(i = getch()) != delim && !nlflg) {
179 		k = width(i);
180 		wid += k;
181 		numtabp[HP].val += k;
182 		if (!ismot(i)) {
183 			emsz = (INCH * pts + 36) / 72;
184 		} else if (isvmot(i)) {
185 			k = absmot(i);
186 			if (isnmot(i))
187 				k = -k;
188 			base -= k;
189 			emsz = 0;
190 		} else
191 			continue;
192 		if (base < numtabp[SB].val)
193 			numtabp[SB].val = base;
194 		if ((k = base + emsz) > numtabp[ST].val)
195 			numtabp[ST].val = k;
196 	}
197 	setn1(wid, 0, (Tchar) 0);
198 	numtabp[HP].val = savhp;
199 	apts = savapts;
200 	apts1 = savapts1;
201 	font = savfont;
202 	font1 = savfont1;
203 	pts = savpts;
204 	pts1 = savpts1;
205 	mchbits();
206 	setwdf = 0;
207 }
208 
209 
n_vmot(void)210 Tchar n_vmot(void)
211 {
212 	dfact = lss;
213 	vflag++;
214 	return n_mot();
215 }
216 
217 
n_hmot(void)218 Tchar n_hmot(void)
219 {
220 	dfact = EM;
221 	return n_mot();
222 }
223 
224 
n_mot(void)225 Tchar n_mot(void)
226 {
227 	int j, n;
228 	Tchar i;
229 
230 	j = HOR;
231 	getch(); /*eat delim*/
232 	if (n = atoi0()) {
233 		if (vflag)
234 			j = VERT;
235 		i = makem(quant(n, j));
236 	} else
237 		i = 0;
238 	getch();
239 	vflag = 0;
240 	dfact = 1;
241 	return(i);
242 }
243 
244 
n_sethl(int k)245 Tchar n_sethl(int k)
246 {
247 	int j;
248 	Tchar i;
249 
250 	j = t.Halfline;
251 	if (k == 'u')
252 		j = -j;
253 	else if (k == 'r')
254 		j = -2 * j;
255 	vflag++;
256 	i = makem(j);
257 	vflag = 0;
258 	return(i);
259 }
260 
261 
n_makem(int i)262 Tchar n_makem(int i)
263 {
264 	Tchar j;
265 
266 	if (i >= 0)
267 		j = i;
268 	else
269 		j = -i;
270 	j |= MOT;
271 	if (i < 0)
272 		j |= NMOT;
273 	if (vflag)
274 		j |= VMOT;
275 	return(j);
276 }
277 
278 
n_casefp(void)279 void n_casefp(void)
280 {
281 	int i, j;
282 
283 	skip();
284 	if ((i = cbits(getch()) - '0') < 0 || i > nfonts)
285 		return;
286 	if (skip() || !(j = getrq()))
287 		return;
288 	fontlab[i] = j;
289 }
290 
291 
292 
n_casebd(void)293 void n_casebd(void)
294 {
295 	int i, j, k;
296 
297 	j = k = 0;
298 bd0:
299 	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
300 		if (k)
301 			goto bd1;
302 		else
303 			return;
304 	}
305 	if (j == smnt) {
306 		k = smnt;
307 		goto bd0;
308 	}
309 	if (k) {
310 		sbold = j;
311 		j = k;
312 	}
313 bd1:
314 	skip();
315 	noscale++;
316 	bdtab[j] = atoi0();
317 	noscale = 0;
318 }
319 
320 
n_casevs(void)321 void n_casevs(void)
322 {
323 	int i;
324 
325 	skip();
326 	vflag++;
327 	dfact = INCH; /*default scaling is points!*/
328 	dfactd = 72;
329 	res = VERT;
330 	i = inumb(&lss);
331 	if (nonumb)
332 		i = lss1;
333 	if (i < VERT)
334 		i = VERT;	/* was VERT */
335 	lss1 = lss;
336 	lss = i;
337 }
338 
339 
340 
341 
n_xlss(void)342 Tchar n_xlss(void)
343 {
344 	/* stores \x'...' into
345 	/* two successive Tchars.
346 	/* the first contains HX, the second the value,
347 	/* encoded as a vertical motion.
348 	/* decoding is done in n2.c by pchar().
349 	*/
350 	int	i;
351 
352 	getch();
353 	dfact = lss;
354 	i = quant(atoi0(), VERT);
355 	dfact = 1;
356 	getch();
357 	if (i >= 0)
358 		*pbp++ = MOT | VMOT | i;
359 	else
360 		*pbp++ = MOT | VMOT | NMOT | -i;
361 	return(HX);
362 }
363