1 #include "tdef.h"
2 extern
3 #include "d.h"
4 extern
5 #include "v.h"
6 /*
7 troff10.c
8
9 CAT interface
10 */
11
12 #include <sgtty.h>
13 #include "ext.h"
14 int vpos = 0; /* absolute vertical position on page */
15 int hpos = 0; /* ditto horizontal */
16
17 #define T_IESC 16
18
19 short *chtab;
20 char *chname;
21 char *fontab[NFONT+1];
22 char *kerntab[NFONT+1];
23 char *fitab[NFONT+1];
24
25 int Inch;
26 int Hor;
27 int Vert;
28 int Unitwidth;
29 int nfonts;
30 int nsizes;
31 int nchtab;
32 int nstips;
33 int xstip = ~ST;
34 tchar * stiplab;
35
36 /* these characters are used as various signals or values
37 /* in miscellaneous places.
38 /* values are set in specnames in t10.c
39 */
40
41 int c_hyphen;
42 int c_emdash;
43 int c_rule;
44 int c_minus;
45 int c_narsp;
46 int c_hnarsp;
47 int c_fi;
48 int c_fl;
49 int c_ff;
50 int c_ffi;
51 int c_ffl;
52 int c_acute;
53 int c_grave;
54 int c_under;
55 int c_rooten;
56 int c_boxrule;
57 int c_lefthand;
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 *setbrk(), *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 fprintf(stderr, "troff: can't open tables for %s\n", termtab);
78 done3(1);
79 }
80 read(fin, &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.nstips;
89 /* "unsigned" so very large files will work properly */
90 stiplab = (tchar *) setbrk((nstips + 1) * sizeof(tchar));
91 filebase = setbrk((unsigned short) dev.filesize + 2*EXTRAFONT);
92 /* enough room for whole file */
93 read(fin, filebase, dev.filesize); /* all at once */
94 pstab = (short *) filebase;
95 chtab = pstab + nsizes + 1;
96 chname = (char *) (chtab + dev.nchtab);
97 p = chname + dev.lchname;
98 for (i = 1; i <= nfonts; i++) {
99 fontbase[i] = (struct font *) p;
100 nw = *p & BMASK; /* 1st thing is width count */
101 fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]);
102 /* for now, still 2 char names */
103 p += sizeof(struct font); /* that's what's on the beginning */
104 fontab[i] = p;
105 kerntab[i] = p + nw;
106 fitab[i] = p + 3 * nw; /* skip width, kern, code */
107 p += 3 * nw + dev.nchtab + 128 - 32;
108 }
109 for (i = 1; i <= nstips; i++) { /* make stipple names tchars */
110 stiplab[i] = PAIR(*p, *(p+1));
111 while (*(p++));
112 }
113 fontbase[0] = (struct font *) p; /* the last shall be first */
114 fontbase[0]->nwfont = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct font);
115 fontab[0] = p + sizeof (struct font);
116 close(fin);
117 /* there are a lot of things that used to be constant
118 /* that now require code to be executed.
119 */
120 sps = SPS;
121 ics = ICS;
122 for (i = 0; i < 16; i++)
123 tabtab[i] = DTAB * (i + 1);
124 pl = 11 * INCH;
125 po = PO;
126 spacesz = SS;
127 lss = lss1 = VS;
128 ll = ll1 = lt = lt1 = LL;
129 specnames(); /* install names like "hyphen", etc. */
130 if (ascii)
131 return;
132 fprintf(ptid, "x T %s\n", devname);
133 fprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert);
134 fprintf(ptid, "x init\n"); /* do initialization for particular device */
135 for (i = 1; i <= nfonts; i++)
136 fprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
137 /*
138 fprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth);
139 fprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n",
140 dev.nchtab, dev.lchname, dev.nchtab+128-32);
141 fprintf(ptid, "x xxx sizes:\nx xxx ");
142 for (i = 0; i < nsizes; i++)
143 fprintf(ptid, " %d", pstab[i]);
144 fprintf(ptid, "\nx xxx chars:\nx xxx ");
145 for (i = 0; i < dev.nchtab; i++)
146 fprintf(ptid, " %s", &chname[chtab[i]]);
147 fprintf(ptid, "\nx xxx\n");
148 */
149 }
150
specnames()151 specnames()
152 {
153 static struct {
154 int *n;
155 char *v;
156 } spnames[] = {
157 &c_hyphen, "hy",
158 &c_emdash, "em",
159 &c_rule, "ru",
160 &c_minus, "\\-",
161 &c_narsp, "\\|",
162 &c_hnarsp, "\\^",
163 &c_fi, "fi",
164 &c_fl, "fl",
165 &c_ff, "ff",
166 &c_ffi, "Fi",
167 &c_ffl, "Fl",
168 &c_acute, "aa",
169 &c_grave, "ga",
170 &c_under, "ul",
171 &c_rooten, "rn",
172 &c_boxrule, "br",
173 &c_lefthand, "lh",
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 tchar i;
195 {
196 register dv, ik;
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 fprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos);
238 */
239 fprintf(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 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 == CHARHT) {
264 fprintf(ptid, "x H %d\n", sbits(i));
265 return(outsize);
266 }
267 if (k == SLANT) {
268 fprintf(ptid, "x S %d\n", sfbits(i)-180);
269 return(outsize);
270 }
271 if (k == WORDSP) {
272 oput('w');
273 return(outsize);
274 }
275 if (k == FONTPOS) {
276 char temp[3];
277 n = i >> 16;
278 temp[0] = n & BMASK;
279 temp[1] = n >> BYTE;
280 temp[2] = 0;
281 ptfpcmd(0, temp);
282 return(outsize);
283 }
284 xbitf = 2;
285 if (sfbits(i) == oldbits) {
286 xfont = pfont;
287 xpts = ppts;
288 xbitf = 0;
289 } else
290 xbits(i);
291 if (k < 040 && k != DRAWFCN)
292 return(outsize);
293 w = getcw(k - 32);
294 j = z = 0;
295 if (k != DRAWFCN) {
296 if (cs) {
297 if (bd)
298 w += (bd - 1) * HOR;
299 j = (cs - w) / 2;
300 w = cs - j;
301 if (bd)
302 w -= (bd - 1) * HOR;
303 }
304 if (iszbit(i)) {
305 if (cs)
306 w = -j;
307 else
308 w = 0;
309 z = 1;
310 }
311 }
312 esc += j;
313 if (xfont != mfont)
314 ptfont();
315 if (xpts != mpts)
316 ptps();
317 if (lead)
318 ptlead();
319 /* put out the real character here */
320 if (k == DRAWFCN) {
321 if (esc)
322 ptesc();
323 dx = absmot(pi[2]);
324 if (isnmot(pi[2]))
325 dx = -dx;
326 dy = absmot(pi[3]);
327 if (isnmot(pi[3]))
328 dy = -dy;
329 switch (cbits(pi[1])) {
330 case DRAWCIRCLE: /* circle */
331 fprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */
332 hpos += dx;
333 break;
334 case DRAWSTYLE:
335 fprintf(ptid, "D%c %d\n", DRAWSTYLE, dx);
336 break;
337 case DRAWTHICK:
338 fprintf(ptid, "D%c %d\n", DRAWTHICK, dx);
339 break;
340 case DRAWELLIPSE:
341 fprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
342 hpos += dx;
343 break;
344 case DRAWLINE: /* line */
345 fprintf(ptid, "D%c %d %d\n", DRAWLINE, dx, dy);
346 hpos += dx;
347 vpos += dy;
348 break;
349 case DRAWARC: /* arc */
350 dx2 = absmot(pi[4]);
351 if (isnmot(pi[4]))
352 dx2 = -dx2;
353 dy2 = absmot(pi[5]);
354 if (isnmot(pi[5]))
355 dy2 = -dy2;
356 fprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
357 dx, dy, dx2, dy2);
358 hpos += dx + dx2;
359 vpos += dy + dy2;
360 break;
361 case DRAWWIG: /* wiggly line -or- */
362 case DRAWCURVE: /* gremlin-style curve */
363 fprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
364 hpos += dx;
365 vpos += dy;
366 writecoords:
367 for (n = 4; cbits(pi[n]) != '.'; n += 2) {
368 dx = absmot(pi[n]);
369 if (isnmot(pi[n]))
370 dx = -dx;
371 dy = absmot(pi[n+1]);
372 if (isnmot(pi[n+1]))
373 dy = -dy;
374 fprintf(ptid, " %d %d", dx, dy);
375 hpos += dx;
376 vpos += dy;
377 }
378 fprintf(ptid, "\n");
379 break;
380
381 case DRAWPOLY: /* polygon with stipple */
382 case DRAWUBPOLY:/* polygon, stipple, no border */
383 if (xstip != stip) ptstip();
384 fprintf(ptid, "D%c %d", cbits(pi[1]), dx);
385 goto writecoords;
386 }
387 for (n = 2; cbits(pi[n]) != '.'; n++)
388 ;
389 return(n + 1); /* leave here so the emboldening */
390 } else if (k < 128) { /* doesn't screw up the graphics */
391 /* try to go faster and compress output */
392 /* by printing nnc for small positive motion followed by c */
393 /* kludgery; have to make sure set all the vars too */
394 if (esc > 0 && esc < 100) {
395 oput(esc / 10 + '0');
396 oput(esc % 10 + '0');
397 oput(k);
398 hpos += esc;
399 esc = 0;
400 } else {
401 if (esc)
402 ptesc();
403 fprintf(ptid, "c%c\n", k);
404 }
405 } else {
406 if (esc)
407 ptesc();
408 fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
409 }
410 if (bd) {
411 bd -= HOR;
412 if (esc += bd)
413 ptesc();
414 if (k < 128) {
415 fprintf(ptid, "c%c\n", k);
416 } else
417 fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
418 if (z)
419 esc -= bd;
420 }
421 esc += w;
422 return(outsize);
423 }
424
ptps()425 ptps()
426 {
427 register i, j, k;
428
429 i = xpts;
430 for (j = 0; i > (k = pstab[j]); j++)
431 if (!k) {
432 k = pstab[--j];
433 break;
434 }
435 fprintf(ptid, "s%d\n", k); /* really should put out string rep of size */
436 mpts = i;
437 }
438
ptstip()439 ptstip()
440 {
441 xstip = stip;
442 fprintf(ptid, "i%d\n", xstip);
443 }
444
445
ptfont()446 ptfont()
447 {
448 mfont = xfont;
449 fprintf(ptid, "f%d\n", xfont);
450 }
451
ptfpcmd(f,s)452 ptfpcmd(f, s)
453 int f;
454 char *s;
455 {
456 if (ascii)
457 return;
458 fprintf(ptid, "x font %d %s\n", f, s);
459 ptfont(); /* make sure that it gets noticed */
460 }
461
ptlead()462 ptlead()
463 {
464 vpos += lead;
465 if (!ascii)
466 fprintf(ptid, "V%d\n", vpos);
467 lead = 0;
468 }
469
ptesc()470 ptesc()
471 {
472 hpos += esc;
473 if (esc > 0)
474 fprintf(ptid, "h%d", esc);
475 else
476 fprintf(ptid, "H%d\n", hpos);
477 esc = 0;
478 }
479
newpage(n)480 newpage(n) /* called at end of each output page (we hope) */
481 {
482 ptlead();
483 vpos = 0;
484 if (ascii)
485 return;
486 flusho();
487 fprintf(ptid, "p%d\n", n); /* new page */
488 ptps();
489 ptfont();
490 }
491
pttrailer()492 pttrailer()
493 {
494 fprintf(ptid, "x trailer\n");
495 }
496
ptstop()497 ptstop()
498 {
499 fprintf(ptid, "x stop\n");
500 }
501
dostop()502 dostop()
503 {
504 if (ascii)
505 return;
506 ptlead();
507 vpos = 0;
508 /* fprintf(ptid, "x xxx end of page\n");*/
509 if (!nofeed)
510 pttrailer();
511 ptlead();
512 fprintf(ptid, "x pause\n");
513 flusho();
514 mpts = mfont = 0;
515 paper = 0;
516 esc = T_IESC; /* this is a dreg */
517 ptesc();
518 esc = po;
519 hpos = vpos = 0; /* probably in wrong place */
520 }
521