1 #ifndef lint
2 /*
3 static char sccsid[] = "@(#)t10.c 2.4 (CWI) 89/08/14";
4 */
5 static char sccsid[] = "@(#)t10.c 2.7 (Berkeley) 02/25/93";
6 #endif lint
7 #include "tdef.h"
8 #include <sgtty.h>
9 #include <ctype.h>
10 #include "ext.h"
11 /*
12 * troff10.c
13 *
14 * typesetter interface
15 */
16
17 int vpos = 0; /* absolute vertical position on page */
18 int hpos = 0; /* ditto horizontal */
19
20 short *chtab;
21 char *chname;
22 char *fontab[NFONT+1];
23 char *kerntab[NFONT+1];
24 char *fitab[NFONT+1];
25 char *codetab[NFONT+1];
26
27 int Inch;
28 int Hor;
29 int Vert;
30 int Unitwidth;
31 int nfonts; /* highest font num. in fontab */
32 int physfonts; /* highest font num. known to printer */
33 int zfont; /* internal font num. mapped to 0 on printer */
34 int nsizes;
35 int nchtab;
36 int nstips;
37 int xstip = ~STIP;
38 tchar *stiplab;
39
40 /* these characters are used as various signals or values
41 /* in miscellaneous places.
42 /* values are set in specnames in t10.c
43 */
44
45 int c_hyphen;
46 int c_emdash;
47 int c_rule;
48 int c_minus;
49 int c_fi;
50 int c_fl;
51 int c_ff;
52 int c_ffi;
53 int c_ffl;
54 int c_acute;
55 int c_grave;
56 int c_under;
57 int c_rooten;
58 int c_boxrule;
59 int c_lefthand;
60 int c_dagger;
61
62 #include "dev.h"
63 struct dev dev;
64 struct Font *fontbase[NFONT+1];
65
66
ptinit()67 ptinit()
68 {
69 int i, fin, nw;
70 char *filebase, *p;
71
72 /* open table for device,
73 /* read in resolution, size info, font info, etc.
74 /* and set params
75 */
76 strcat(termtab, "/dev");
77 strcat(termtab, devname);
78 strcat(termtab, "/DESC.out"); /* makes "..../devXXX/DESC.out" */
79 if ((fin = open(termtab, 0)) < 0) {
80 errprint("can't open tables for %s", termtab);
81 done3(1);
82 }
83 if (read(fin, (char *) &dev, sizeof(struct dev)) < sizeof(struct dev)) {
84 errprint("short read on %s", termtab);
85 done3(1);
86 }
87 Inch = dev.res;
88 Hor = dev.hor;
89 Vert = dev.vert;
90 Unitwidth = dev.unitwidth;
91 physfonts = nfonts = dev.nfonts;
92 nsizes = dev.nsizes;
93 nchtab = dev.nchtab;
94 nstips = dev.nstip;
95 stiplab = (tchar *) malloc((nstips + 1) * sizeof(tchar));
96 filebase = malloc(dev.filesize + EXTRAFONT);
97 if (read(fin, filebase, dev.filesize) < dev.filesize) {
98 errprint("short read on %s", termtab);
99 done3(1);
100 }
101 pstab = (short *) filebase;
102 chtab = pstab + nsizes + 1;
103 chname = (char *) (chtab + dev.nchtab);
104 p = chname + dev.lchname;
105 for (i = 1; i <= nfonts; i++) {
106 fontbase[i] = (struct Font *) p;
107 nw = *p & BYTEMASK; /* 1st thing is width count */
108 fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]);
109 /* for now, still 2 char names */
110 if (smnt == 0 && fontbase[i]->specfont == 1)
111 smnt = i; /* first special font */
112 p += sizeof(struct Font); /* that's what's on the beginning */
113 fontab[i] = p;
114 kerntab[i] = p + nw;
115 codetab[i] = p + 2 * nw;
116 fitab[i] = p + 3 * nw; /* skip width, kern, code */
117 p += 3 * nw + dev.nchtab + 128 - 32;
118 }
119 for (i = 1; i <= nstips; i++) { /* make stipple names tchars */
120 stiplab[i] = PAIR(*p, *(p+1));
121 while (*(p++));
122 }
123 fontbase[0] = (struct Font *) p; /* the last shall be first */
124 fontbase[0]->nwfont = MAXCHARS;
125 fontab[0] = p + sizeof (struct Font);
126 close(fin);
127 /* there are a lot of things that used to be constant
128 /* that now require code to be executed.
129 */
130 sps = SPS;
131 ics = ICS;
132 for (i = 0; i < 16; i++)
133 tabtab[i] = DTAB * (i + 1);
134 pl = 11 * INCH;
135 po = PO;
136 spacesz = SS;
137 lss = lss1 = VS;
138 ll = ll1 = lt = lt1 = LL;
139 specnames(); /* install names like "hyphen", etc. */
140 if (ascii)
141 return;
142 fdprintf(ptid, "x T %s\n", devname);
143 fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert);
144 fdprintf(ptid, "x init\n"); /* do initialization for particular device */
145 #ifdef notdef
146 for (i = 1; i <= nfonts; i++)
147 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
148 fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth);
149 fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n",
150 dev.nchtab, dev.lchname, dev.nchtab+128-32);
151 fdprintf(ptid, "x xxx sizes:\nx xxx ");
152 for (i = 0; i < nsizes; i++)
153 fdprintf(ptid, " %d", pstab[i]);
154 fdprintf(ptid, "\nx xxx chars:\nx xxx ");
155 for (i = 0; i < dev.nchtab; i++)
156 fdprintf(ptid, " %s", &chname[chtab[i]]);
157 fdprintf(ptid, "\nx xxx\n");
158 #endif
159 }
160
specnames()161 specnames()
162 {
163 static struct {
164 int *n;
165 char *v;
166 } spnames[] = {
167 &c_hyphen, "hy",
168 &c_emdash, "em",
169 &c_rule, "ru",
170 &c_minus, "\\-",
171 &c_fi, "fi",
172 &c_fl, "fl",
173 &c_ff, "ff",
174 &c_ffi, "Fi",
175 &c_ffl, "Fl",
176 &c_acute, "aa",
177 &c_grave, "ga",
178 &c_under, "ul",
179 &c_rooten, "rn",
180 &c_boxrule, "br",
181 &c_lefthand, "lh",
182 &c_dagger, "dg",
183 0, 0
184 };
185 int i;
186
187 for (i = 0; spnames[i].n; i++)
188 *spnames[i].n = findch(spnames[i].v);
189 }
190
findch(s)191 findch(s) /* find char s in chname */
192 register char *s;
193 {
194 register int i;
195
196 for (i = 0; i < nchtab; i++)
197 if (strcmp(s, &chname[chtab[i]]) == 0)
198 return(i + 128);
199 return(0);
200 }
201
ptout(i)202 ptout(i)
203 register tchar i;
204 {
205 register dv;
206 register tchar *k;
207 int temp, a, b;
208
209 if (cbits(i) != '\n') {
210 *olinep++ = i;
211 return;
212 }
213 if (olinep == oline) {
214 lead += lss;
215 return;
216 }
217
218 hpos = po; /* ??? */
219 esc = 0; /* ??? */
220 ptesc(); /* the problem is to get back to the left end of the line */
221 dv = 0;
222 for (k = oline; k < olinep; k++) {
223 if (ismot(*k) && isvmot(*k)) {
224 temp = absmot(*k);
225 if (isnmot(*k))
226 temp = -temp;
227 dv += temp;
228 }
229 }
230 if (dv) {
231 vflag++;
232 *olinep++ = makem(-dv);
233 vflag = 0;
234 }
235
236 b = dip->blss + lss;
237 lead += dip->blss + lss;
238 dip->blss = 0;
239 for (k = oline; k < olinep; )
240 k += ptout0(k); /* now passing a pointer! */
241 olinep = oline;
242 lead += dip->alss;
243 a = dip->alss;
244 dip->alss = 0;
245 /*
246 fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos);
247 */
248 fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */
249 }
250
ptout0(pi)251 ptout0(pi)
252 tchar *pi;
253 {
254 register short j, k, w;
255 short z, dx, dy, dx2, dy2, n;
256 register tchar i;
257 int outsize; /* size of object being printed */
258
259 outsize = 1; /* default */
260 i = *pi;
261 k = cbits(i);
262 if (ismot(i)) {
263 j = absmot(i);
264 if (isnmot(i))
265 j = -j;
266 if (isvmot(i))
267 lead += j;
268 else
269 esc += j;
270 return(outsize);
271 }
272 if (k == XON) {
273 int c;
274 if (xfont != mfont)
275 ptfont();
276 if (xpts != mpts)
277 ptps();
278 if (lead)
279 ptlead();
280 if (esc) /* for psfig ???*/
281 ptesc();
282 fdprintf(ptid, "x X ");
283 for (j = 1; (c=cbits(pi[j])) != XOFF; j++)
284 outascii(pi[j]);
285 oput('\n');
286 return j+1;
287 }
288 ;
289 if (k == CHARHT) {
290 if (xpts != mpts)
291 ptps();
292 fdprintf(ptid, "x H %d\n", sbits(i));
293 return(outsize);
294 }
295 if (k == SLANT) {
296 fdprintf(ptid, "x S %d\n", sfbits(i)-180);
297 return(outsize);
298 }
299 if (k == WORDSP) {
300 oput('w');
301 return(outsize);
302 }
303 if (sfbits(i) == oldbits) {
304 xfont = pfont;
305 xpts = ppts;
306 } else
307 xbits(i, 2);
308 if (k < 040 && k != DRAWFCN)
309 return(outsize);
310 /*
311 * Bug fix, if k == DRAWFCN, thewidcache gets a negative index.
312 * This worked by magic on the vax and tahoe, but caused somtimes
313 * a segment violaton on the suns.
314 *
315 * The code was plainly wrong (jna).
316 */
317 if ( k != DRAWFCN) {
318 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) {
319 w = widcache[k-32].width;
320 bd = 0;
321 cs = 0;
322 } else
323 w = getcw(k-32);
324 }
325 j = z = 0;
326 if (k != DRAWFCN) {
327 if (cs) {
328 if (bd)
329 w += (bd - 1) * HOR;
330 j = (cs - w) / 2;
331 w = cs - j;
332 if (bd)
333 w -= (bd - 1) * HOR;
334 }
335 if (iszbit(i)) {
336 if (cs)
337 w = -j;
338 else
339 w = 0;
340 z = 1;
341 }
342 }
343 esc += j;
344 if (xfont != mfont)
345 ptfont();
346 if (xpts != mpts)
347 ptps();
348 if (lead)
349 ptlead();
350 /* put out the real character here */
351 if (k == DRAWFCN) {
352 if (esc)
353 ptesc();
354 dx = absmot(pi[2]);
355 if (isnmot(pi[2]))
356 dx = -dx;
357 dy = absmot(pi[3]);
358 if (isnmot(pi[3]))
359 dy = -dy;
360 w = 0;
361 switch (cbits(pi[1])) {
362 case DRAWCIRCLE: /* circle */
363 hpos += dx;
364 /* FALLTHROUGH */
365 case DRAWTHICK:
366 case DRAWSTYLE:
367 fdprintf(ptid, "D%c %d\n", cbits(pi[1]), dx); /* dx is diameter */
368 break;
369 case DRAWELLIPSE:
370 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
371 hpos += dx;
372 break;
373 case DRAWLINE: /* line */
374 fdprintf(ptid, "D%c %d %d\n", DRAWLINE, dx, dy);
375 hpos += dx;
376 vpos += dy;
377 break;
378 case DRAWARC: /* arc */
379 dx2 = absmot(pi[4]);
380 if (isnmot(pi[4]))
381 dx2 = -dx2;
382 dy2 = absmot(pi[5]);
383 if (isnmot(pi[5]))
384 dy2 = -dy2;
385 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
386 dx, dy, dx2, dy2);
387 hpos += dx + dx2;
388 vpos += dy + dy2;
389 break;
390 case DRAWSPLINE: /* spline */
391 /* case DRAWWIG: /* wiggly line */
392 case DRAWCURVE: /* gremlin-style curve */
393 default: /* something else; copy it like spline */
394 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
395 hpos += dx;
396 vpos += dy;
397 writecoords:
398 for (n = 4; cbits(pi[n]) != '.'; n += 2) {
399 dx = absmot(pi[n]);
400 if (isnmot(pi[n]))
401 dx = -dx;
402 dy = absmot(pi[n+1]);
403 if (isnmot(pi[n+1]))
404 dy = -dy;
405 fdprintf(ptid, " %d %d", dx, dy);
406 hpos += dx;
407 vpos += dy;
408 }
409 fdprintf(ptid, "\n");
410 break;
411
412 case DRAWPOLY: /* polygon with stipple */
413 case DRAWUBPOLY:/* polygon, stipple, no border */
414 if (xstip != stip) ptstip();
415 fdprintf(ptid, "D%c %d", cbits(pi[1]), dx);
416 goto writecoords;
417 }
418 for (n = 2; cbits(pi[n]) != '.'; n++)
419 ;
420 outsize = n + 1;
421 } else if (k < 128) {
422 /* try to go faster and compress output */
423 /* by printing nnc for small positive motion followed by c */
424 /* kludgery; have to make sure set all the vars too */
425 if (esc > 0 && esc < 100) {
426 oput(esc / 10 + '0');
427 oput(esc % 10 + '0');
428 oput(k);
429 hpos += esc;
430 esc = 0;
431 } else {
432 if (esc)
433 ptesc();
434 oput('c');
435 oput(k);
436 oput('\n');
437 }
438 } else {
439 if (esc)
440 ptesc();
441 if (k >= nchtab + 128)
442 fdprintf(ptid, "N%d\n", k - (nchtab+128));
443 else
444 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
445 }
446 if (bd) {
447 bd -= HOR;
448 if (esc += bd)
449 ptesc();
450 if (k < 128) {
451 fdprintf(ptid, "c%c\n", k);
452 } else if (k >= nchtab + 128) {
453 fdprintf(ptid, "N%d\n", k - (nchtab+128));
454 } else
455 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
456 if (z)
457 esc -= bd;
458 }
459 esc += w;
460 return(outsize);
461 }
462
ptps()463 ptps()
464 {
465 register i, j, k;
466
467 i = xpts;
468 for (j = 0; i > (k = pstab[j]); j++)
469 if (!k) {
470 k = pstab[--j];
471 break;
472 }
473 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */
474 mpts = i;
475 }
476
ptstip()477 ptstip()
478 {
479 xstip = stip;
480 fdprintf(ptid, "i%d\n", xstip);
481 }
482
483
ptfont()484 ptfont()
485 {
486 extern char *unpair();
487 mfont = xfont;
488 if( xfont > physfonts) {
489 if (xfont != zfont) {
490 register char *temp = unpair(fontlab[xfont]);
491 ptfpcmd(0, temp); /* Put the desired font in the
492 * fontcache of the filter */
493 }
494 fdprintf(ptid, "f0\n"); /* make sure that it gets noticed */
495 zfont = xfont;
496 } else
497 fdprintf(ptid, "f%d\n", xfont);
498 }
499
ptfpcmd(f,s)500 ptfpcmd(f, s)
501 int f;
502 char *s;
503 {
504 if (ascii)
505 return;
506 fdprintf(ptid, "x font %d %s\n", f, s);
507 }
508
ptlead()509 ptlead()
510 {
511 vpos += lead;
512 if (!ascii)
513 fdprintf(ptid, "V%d\n", vpos);
514 lead = 0;
515 }
516
ptesc()517 ptesc()
518 {
519 hpos += esc;
520 if (esc > 0) {
521 oput('h');
522 if (esc>=10 && esc<100) {
523 oput(esc/10 + '0');
524 oput(esc%10 + '0');
525 } else
526 fdprintf(ptid, "%d", esc);
527 } else
528 fdprintf(ptid, "H%d\n", hpos);
529 esc = 0;
530 }
531
newpage(n)532 newpage(n) /* called at end of each output page (we hope) */
533 {
534 int i;
535
536 ptlead();
537 vpos = 0;
538 if (ascii)
539 return;
540 fdprintf(ptid, "p%d\n", n); /* new page */
541 if (fontbase[zfont]->namefont && fontbase[zfont]->namefont[0])
542 fdprintf(ptid, "x font 0 %s\n", fontbase[zfont]->namefont);
543 for (i = 1; i <= physfonts; i++)
544 if (fontbase[i]->namefont && fontbase[i]->namefont[0])
545 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
546 ptps();
547 ptfont();
548 }
549
pttrailer()550 pttrailer()
551 {
552 fdprintf(ptid, "x trailer\n");
553 }
554
ptstop()555 ptstop()
556 {
557 fdprintf(ptid, "x stop\n");
558 }
559
dostop()560 dostop()
561 {
562 if (ascii)
563 return;
564 ptlead();
565 vpos = 0;
566 /* fdprintf(ptid, "x xxx end of page\n");*/
567 if (!nofeed)
568 pttrailer();
569 ptlead();
570 fdprintf(ptid, "x pause\n");
571 flusho();
572 mpts = mfont = 0;
573 ptesc();
574 esc = po;
575 hpos = vpos = 0; /* probably in wrong place */
576 }
577