t10.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
t10.c (9444B) | |
--- | |
1 #include "tdef.h" | |
2 #include "fns.h" | |
3 #include "ext.h" | |
4 | |
5 /* | |
6 * troff10.c | |
7 * | |
8 * typesetter interface | |
9 */ | |
10 | |
11 int vpos = 0; /* absolute vertical position on pag… | |
12 int hpos = 0; /* ditto horizontal */ | |
13 | |
14 extern Font fonts[MAXFONTS+1]; | |
15 | |
16 int Inch; | |
17 int Hor; | |
18 int Vert; | |
19 int Unitwidth; | |
20 int nfonts; | |
21 | |
22 | |
23 | |
24 void t_ptinit(void) | |
25 { | |
26 int i; | |
27 char buf[100], *p; | |
28 | |
29 hmot = t_hmot; | |
30 makem = t_makem; | |
31 setabs = t_setabs; | |
32 setch = t_setch; | |
33 sethl = t_sethl; | |
34 setht = t_setht; | |
35 setslant = t_setslant; | |
36 vmot = t_vmot; | |
37 xlss = t_xlss; | |
38 findft = t_findft; | |
39 width = t_width; | |
40 mchbits = t_mchbits; | |
41 ptlead = t_ptlead; | |
42 ptout = t_ptout; | |
43 ptpause = t_ptpause; | |
44 setfont = t_setfont; | |
45 setps = t_setps; | |
46 setwd = t_setwd; | |
47 | |
48 /* open table for device, */ | |
49 /* read in resolution, size info, font info, etc., set params */ | |
50 if ((p = getenv("TYPESETTER")) != 0) | |
51 strcpy(devname, p); | |
52 if (termtab[0] == 0) | |
53 strcpy(termtab, DWBfontdir); | |
54 if (fontdir[0] == 0) | |
55 strcpy(fontdir, DWBfontdir); | |
56 if (devname[0] == 0) | |
57 strcpy(devname, TDEVNAME); | |
58 hyf = 1; | |
59 lg = 1; | |
60 | |
61 sprintf(buf, "/dev%s/DESC", devname); | |
62 strcat(termtab, buf); | |
63 if (getdesc(termtab) < 0) { | |
64 ERROR "can't open DESC file %s", termtab WARN; | |
65 done3(1); | |
66 } | |
67 if (!ascii) { | |
68 OUT "x T %s\n", devname PUT; | |
69 OUT "x res %d %d %d\n", Inch, Hor, Vert PUT; | |
70 OUT "x init\n" PUT; | |
71 } | |
72 for (i = 1; i <= nfonts; i++) | |
73 setfp(i, fontlab[i], (char *) 0, 0); | |
74 sps = EM/3; /* space size */ | |
75 ics = EM; /* insertion character space */ | |
76 for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++) | |
77 tabtab[i] = DTAB * (i + 1); | |
78 tabtab[NTAB-1] = 0; | |
79 pl = 11 * INCH; /* paper length */ | |
80 po = PO; /* page offset */ | |
81 spacesz = SS; | |
82 lss = lss1 = VS; | |
83 ll = ll1 = lt = lt1 = LL; | |
84 t_specnames(); /* install names like "hyphen", etc. */ | |
85 } | |
86 | |
87 void t_specnames(void) | |
88 { | |
89 int i; | |
90 | |
91 for (i = 0; spnames[i].n; i++) | |
92 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install); | |
93 } | |
94 | |
95 void t_ptout(Tchar i) | |
96 { | |
97 int dv; | |
98 Tchar *k; | |
99 int temp, a, b; | |
100 int diff; | |
101 | |
102 if (cbits(i) != '\n') { | |
103 if (olinep >= oline + olnsize) { | |
104 diff = olinep - oline; | |
105 olnsize += OLNSIZE; | |
106 if ((oline = (Tchar *)realloc((char *)oline, oln… | |
107 if (diff && olinep) | |
108 olinep = oline + diff; | |
109 } else { | |
110 ERROR "Output line overflow." WARN; | |
111 done(2); | |
112 } | |
113 } | |
114 *olinep++ = i; | |
115 return; | |
116 } | |
117 if (olinep == oline) { | |
118 lead += lss; | |
119 return; | |
120 } | |
121 | |
122 hpos = po; /* ??? */ | |
123 esc = 0; /* ??? */ | |
124 ptesc(); /* the problem is to get back to the left end of… | |
125 dv = 0; | |
126 for (k = oline; k < olinep; k++) { | |
127 if (ismot(*k) && isvmot(*k)) { | |
128 temp = absmot(*k); | |
129 if (isnmot(*k)) | |
130 temp = -temp; | |
131 dv += temp; | |
132 } | |
133 } | |
134 if (dv) { | |
135 vflag++; | |
136 *olinep++ = makem(-dv); | |
137 vflag = 0; | |
138 } | |
139 | |
140 b = dip->blss + lss; | |
141 lead += dip->blss + lss; | |
142 dip->blss = 0; | |
143 for (k = oline; k < olinep; ) | |
144 k += ptout0(k); /* now passing a pointer! */ | |
145 olinep = oline; | |
146 lead += dip->alss; | |
147 a = dip->alss; | |
148 dip->alss = 0; | |
149 /* | |
150 OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT; | |
151 */ | |
152 OUT "n%d %d\n", b, a PUT; /* be nice to chuck */ | |
153 } | |
154 | |
155 int ptout0(Tchar *pi) | |
156 { | |
157 int j, k, w; | |
158 int z, dx, dy, dx2, dy2, n; | |
159 Tchar i; | |
160 int outsize; /* size of object being printed */ | |
161 | |
162 w = 0; | |
163 outsize = 1; /* default */ | |
164 i = *pi; | |
165 k = cbits(i); | |
166 if (ismot(i)) { | |
167 j = absmot(i); | |
168 if (isnmot(i)) | |
169 j = -j; | |
170 if (isvmot(i)) | |
171 lead += j; | |
172 else | |
173 esc += j; | |
174 return(outsize); | |
175 } | |
176 if (k == CHARHT) { | |
177 xpts = fbits(i); /* sneaky, font bits as size bit… | |
178 if (xpts != mpts) | |
179 ptps(); | |
180 OUT "x H %ld\n", sbits(i) PUT; | |
181 return(outsize); | |
182 } | |
183 if (k == SLANT) { | |
184 OUT "x S %ld\n", sfbits(i)-180 PUT; | |
185 return(outsize); | |
186 } | |
187 if (k == WORDSP) { | |
188 oput('w'); | |
189 return(outsize); | |
190 } | |
191 if (sfbits(i) == oldbits) { | |
192 xfont = pfont; | |
193 xpts = ppts; | |
194 } else | |
195 xbits(i, 2); | |
196 if (k == XON) { | |
197 extern int xon; | |
198 ptflush(); /* guarantee that everything is out */ | |
199 if (esc) | |
200 ptesc(); | |
201 if (xfont != mfont) | |
202 ptfont(); | |
203 if (xpts != mpts) | |
204 ptps(); | |
205 if (lead) | |
206 ptlead(); | |
207 OUT "x X " PUT; | |
208 xon++; | |
209 for (j = 1; cbits(pi[j]) != XOFF; j++) | |
210 outascii(pi[j]); | |
211 oput('\n'); | |
212 xon--; | |
213 return j+1; | |
214 } | |
215 if (k < 040 && k != DRAWFCN) | |
216 return(outsize); | |
217 j = z = 0; | |
218 if (k != DRAWFCN) { | |
219 if (widcache[k].fontpts == (xfont<<8) + xpts && !setwdf… | |
220 w = widcache[k].width; | |
221 bd = 0; | |
222 cs = 0; | |
223 } else | |
224 w = getcw(k); | |
225 if (cs) { | |
226 if (bd) | |
227 w += (bd - 1) * HOR; | |
228 j = (cs - w) / 2; | |
229 w = cs - j; | |
230 if (bd) | |
231 w -= (bd - 1) * HOR; | |
232 } | |
233 if (iszbit(i)) { | |
234 if (cs) | |
235 w = -j; | |
236 else | |
237 w = 0; | |
238 z = 1; | |
239 } | |
240 } | |
241 esc += j; | |
242 if (xfont != mfont) | |
243 ptfont(); | |
244 if (xpts != mpts) | |
245 ptps(); | |
246 if (lead) | |
247 ptlead(); | |
248 /* put out the real character here */ | |
249 if (k == DRAWFCN) { | |
250 if (esc) | |
251 ptesc(); | |
252 w = 0; | |
253 dx = absmot(pi[3]); | |
254 if (isnmot(pi[3])) | |
255 dx = -dx; | |
256 dy = absmot(pi[4]); | |
257 if (isnmot(pi[4])) | |
258 dy = -dy; | |
259 switch (cbits(pi[1])) { | |
260 case DRAWCIRCLE: /* circle */ | |
261 OUT "D%c %d\n", DRAWCIRCLE, dx PUT; /* dx… | |
262 hpos += dx; | |
263 break; | |
264 case DRAWELLIPSE: | |
265 OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT; | |
266 hpos += dx; | |
267 break; | |
268 case DRAWBUILD: | |
269 k = cbits(pi[2]); | |
270 OUT "D%c %d ", DRAWBUILD, dx PUT; | |
271 if (k < ALPHABET) | |
272 OUT "%c\n", k PUT; | |
273 else | |
274 ptchname(k); | |
275 hpos += dx; | |
276 break; | |
277 case DRAWLINE: /* line */ | |
278 k = cbits(pi[2]); | |
279 OUT "D%c %d %d ", DRAWLINE, dx, dy PUT; | |
280 if (k < ALPHABET) | |
281 OUT "%c\n", k PUT; | |
282 else | |
283 ptchname(k); | |
284 hpos += dx; | |
285 vpos += dy; | |
286 break; | |
287 case DRAWARC: /* arc */ | |
288 dx2 = absmot(pi[5]); | |
289 if (isnmot(pi[5])) | |
290 dx2 = -dx2; | |
291 dy2 = absmot(pi[6]); | |
292 if (isnmot(pi[6])) | |
293 dy2 = -dy2; | |
294 OUT "D%c %d %d %d %d\n", DRAWARC, | |
295 dx, dy, dx2, dy2 PUT; | |
296 hpos += dx + dx2; | |
297 vpos += dy + dy2; | |
298 break; | |
299 | |
300 case 's': /* using 's' internally to avoid .tr ~ … | |
301 pi[1] = '~'; | |
302 case DRAWSPLINE: /* spline */ | |
303 default: /* something else; copy it like spline */ | |
304 OUT "D%c %d %d", (char)cbits(pi[1]), dx, dy PUT; | |
305 hpos += dx; | |
306 vpos += dy; | |
307 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == D… | |
308 /* it was somehow defective */ | |
309 OUT "\n" PUT; | |
310 break; | |
311 } | |
312 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { | |
313 dx = absmot(pi[n]); | |
314 if (isnmot(pi[n])) | |
315 dx = -dx; | |
316 dy = absmot(pi[n+1]); | |
317 if (isnmot(pi[n+1])) | |
318 dy = -dy; | |
319 OUT " %d %d", dx, dy PUT; | |
320 hpos += dx; | |
321 vpos += dy; | |
322 } | |
323 OUT "\n" PUT; | |
324 break; | |
325 } | |
326 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) | |
327 ; | |
328 outsize = n + 1; | |
329 } else if (k < ALPHABET) { | |
330 /* try to go faster and compress output */ | |
331 /* by printing nnc for small positive motion followed by… | |
332 /* kludgery; have to make sure set all the vars too */ | |
333 if (esc > 0 && esc < 100) { | |
334 oput(esc / 10 + '0'); | |
335 oput(esc % 10 + '0'); | |
336 oput(k); | |
337 hpos += esc; | |
338 esc = 0; | |
339 } else { | |
340 if (esc) | |
341 ptesc(); | |
342 oput('c'); | |
343 oput(k); | |
344 oput('\n'); | |
345 } | |
346 } else { | |
347 if (esc) | |
348 ptesc(); | |
349 ptchname(k); | |
350 } | |
351 if (bd) { | |
352 bd -= HOR; | |
353 if (esc += bd) | |
354 ptesc(); | |
355 if (k < ALPHABET) | |
356 OUT "c%c\n", k PUT; | |
357 else | |
358 ptchname(k); | |
359 if (z) | |
360 esc -= bd; | |
361 } | |
362 esc += w; | |
363 return(outsize); | |
364 } | |
365 | |
366 void ptchname(int k) | |
367 { | |
368 char *chn = chname(k); | |
369 | |
370 switch (chn[0]) { | |
371 case MBchar: | |
372 OUT "c%s\n", chn+1 PUT; /* \n not needed? */ | |
373 break; | |
374 case Number: | |
375 OUT "N%s\n", chn+1 PUT; | |
376 break; | |
377 case Troffchar: | |
378 OUT "C%s\n", chn+1 PUT; | |
379 break; | |
380 default: | |
381 ERROR "illegal char type %s", chn WARN; | |
382 break; | |
383 } | |
384 } | |
385 | |
386 void ptflush(void) /* get us to a clean output state */ | |
387 { | |
388 if (TROFF) { | |
389 /* ptesc(); but always H, no h */ | |
390 hpos += esc; | |
391 OUT "\nH%d\n", hpos PUT; | |
392 esc = 0; | |
393 ptps(); | |
394 ptfont(); | |
395 ptlead(); | |
396 } | |
397 } | |
398 | |
399 void ptps(void) | |
400 { | |
401 int i, j, k; | |
402 | |
403 i = xpts; | |
404 for (j = 0; i > (k = pstab[j]); j++) | |
405 if (!k) { | |
406 k = pstab[--j]; | |
407 break; | |
408 } | |
409 if (!ascii) | |
410 OUT "s%d\n", k PUT; /* really should put out stri… | |
411 mpts = i; | |
412 } | |
413 | |
414 void ptfont(void) | |
415 { | |
416 mfont = xfont; | |
417 if (ascii) | |
418 return; | |
419 if (xfont > nfonts) { | |
420 ptfpcmd(0, fonts[xfont].longname, 0); /* Put the … | |
421 * fontcache of the filter */ | |
422 OUT "f0\n" PUT; /* make sure that it gets noticed… | |
423 } else | |
424 OUT "f%d\n", xfont PUT; | |
425 } | |
426 | |
427 void ptfpcmd(int f, char *s, char *longname) | |
428 { | |
429 if (f > nfonts) /* a bit risky? */ | |
430 f = 0; | |
431 if (longname) { | |
432 OUT "x font %d %s %s\n", f, s, longname PUT; | |
433 } else { | |
434 OUT "x font %d %s\n", f, s PUT; | |
435 } | |
436 /* OUT "f%d\n", xfont PUT; /* need this for buggy version … | |
437 /* which apparently believes that x font… | |
438 /* to set the font, not just the positio… | |
439 } | |
440 | |
441 void t_ptlead(void) | |
442 { | |
443 vpos += lead; | |
444 if (!ascii) | |
445 OUT "V%d\n", vpos PUT; | |
446 lead = 0; | |
447 } | |
448 | |
449 void ptesc(void) | |
450 { | |
451 hpos += esc; | |
452 if (!ascii) | |
453 if (esc > 0) { | |
454 oput('h'); | |
455 if (esc>=10 && esc<100) { | |
456 oput(esc/10 + '0'); | |
457 oput(esc%10 + '0'); | |
458 } else | |
459 OUT "%d", esc PUT; | |
460 } else | |
461 OUT "H%d\n", hpos PUT; | |
462 esc = 0; | |
463 } | |
464 | |
465 void ptpage(int n) /* called at end of each output page, we hope … | |
466 { | |
467 int i; | |
468 | |
469 if (NROFF) | |
470 return; | |
471 ptlead(); | |
472 vpos = 0; | |
473 if (ascii) | |
474 return; | |
475 OUT "p%d\n", n PUT; /* new page */ | |
476 for (i = 0; i <= nfonts; i++) | |
477 if (fontlab[i]) { | |
478 if (fonts[i].truename) | |
479 OUT "x font %d %s %s\n", i, fonts[i].lon… | |
480 else | |
481 OUT "x font %d %s\n", i, fonts[i].longna… | |
482 } | |
483 ptps(); | |
484 ptfont(); | |
485 } | |
486 | |
487 void pttrailer(void) | |
488 { | |
489 if (TROFF) | |
490 OUT "x trailer\n" PUT; | |
491 } | |
492 | |
493 void ptstop(void) | |
494 { | |
495 if (TROFF) | |
496 OUT "x stop\n" PUT; | |
497 } | |
498 | |
499 void t_ptpause(void) | |
500 { | |
501 if (ascii) | |
502 return; | |
503 ptlead(); | |
504 vpos = 0; | |
505 pttrailer(); | |
506 ptlead(); | |
507 OUT "x pause\n" PUT; | |
508 flusho(); | |
509 mpts = mfont = 0; | |
510 ptesc(); | |
511 esc = po; | |
512 hpos = vpos = 0; /* probably in wrong place */ | |
513 } |