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