]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/troff/n6.c
cc: use 7 octal digits for 21 bit runes
[plan9front.git] / sys / src / cmd / troff / n6.c
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
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
47 Tchar n_setch(int c)
48 {
49         return t_setch(c);
50 }
51
52 Tchar n_setabs(void)    /* set absolute char from \N'...' */
53 {                       /* for now, a no-op */
54         return t_setabs();
55 }
56
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
71 void n_mchbits(void)
72 {
73         chbits = 0;
74         setfbits(chbits, font);
75         sps = width(' ' | chbits);
76 }
77
78
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
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
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
128 void n_caseft(void)
129 {
130         skip();
131         setfont(1);
132 }
133
134
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
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
210 Tchar n_vmot(void)
211 {
212         dfact = lss;
213         vflag++;
214         return n_mot();
215 }
216
217
218 Tchar n_hmot(void)
219 {
220         dfact = EM;
221         return n_mot();
222 }
223
224
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
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
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
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
293 void n_casebd(void)
294 {
295         int i, j, k;
296
297         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
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
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 }