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