Blob


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)
25 {
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 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;
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] = 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 }
87 void t_specnames(void)
88 {
89 int i;
91 for (i = 0; spnames[i].n; i++)
92 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
93 }
95 void t_ptout(Tchar i)
96 {
97 int dv;
98 Tchar *k;
99 int temp, a, b;
100 int diff;
102 if (cbits(i) != '\n') {
103 if (olinep >= oline + olnsize) {
104 diff = olinep - oline;
105 olnsize += OLNSIZE;
106 if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
107 if (diff && olinep)
108 olinep = oline + diff;
109 } else {
110 ERROR "Output line overflow." WARN;
111 done(2);
114 *olinep++ = i;
115 return;
117 if (olinep == oline) {
118 lead += lss;
119 return;
122 hpos = po; /* ??? */
123 esc = 0; /* ??? */
124 ptesc(); /* the problem is to get back to the left end of the line */
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;
134 if (dv) {
135 vflag++;
136 *olinep++ = makem(-dv);
137 vflag = 0;
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 */
155 int ptout0(Tchar *pi)
157 int j, k, w;
158 int z, dx, dy, dx2, dy2, n;
159 Tchar i;
160 int outsize; /* size of object being printed */
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);
176 if (k == CHARHT) {
177 xpts = fbits(i); /* sneaky, font bits as size bits */
178 if (xpts != mpts)
179 ptps();
180 OUT "x H %ld\n", sbits(i) PUT;
181 return(outsize);
183 if (k == SLANT) {
184 OUT "x S %ld\n", sfbits(i)-180 PUT;
185 return(outsize);
187 if (k == WORDSP) {
188 oput('w');
189 return(outsize);
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;
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;
233 if (iszbit(i)) {
234 if (cs)
235 w = -j;
236 else
237 w = 0;
238 z = 1;
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 is diameter */
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;
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]) == DRAWFCN) {
308 /* it was somehow defective */
309 OUT "\n" PUT;
310 break;
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;
323 OUT "\n" PUT;
324 break;
326 for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
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 c */
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');
346 } else {
347 if (esc)
348 ptesc();
349 ptchname(k);
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;
362 esc += w;
363 return(outsize);
366 void ptchname(int k)
368 char *chn = chname(k);
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;
386 void ptflush(void) /* get us to a clean output state */
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();
399 void ptps(void)
401 int i, j, k;
403 i = xpts;
404 for (j = 0; i > (k = pstab[j]); j++)
405 if (!k) {
406 k = pstab[--j];
407 break;
409 if (!ascii)
410 OUT "s%d\n", k PUT; /* really should put out string rep of size */
411 mpts = i;
414 void ptfont(void)
416 mfont = xfont;
417 if (ascii)
418 return;
419 if (xfont > nfonts) {
420 ptfpcmd(0, fonts[xfont].longname, 0); /* Put the desired font in 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;
427 void ptfpcmd(int f, char *s, char *longname)
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;
436 /* OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */
437 /* which apparently believes that x font means */
438 /* to set the font, not just the position. */
441 void t_ptlead(void)
443 vpos += lead;
444 if (!ascii)
445 OUT "V%d\n", vpos PUT;
446 lead = 0;
449 void ptesc(void)
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;
465 void ptpage(int n) /* called at end of each output page, we hope */
467 int i;
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].longname, fonts[i].truename PUT;
480 else
481 OUT "x font %d %s\n", i, fonts[i].longname PUT;
483 ptps();
484 ptfont();
487 void pttrailer(void)
489 if (TROFF)
490 OUT "x trailer\n" PUT;
493 void ptstop(void)
495 if (TROFF)
496 OUT "x stop\n" PUT;
499 void t_ptpause(void)
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 */