1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 #pragma ident "%Z%%M% %I% %E% SMI"
41
42 #include "tdef.h"
43 #include <ctype.h>
44 #include "ext.h"
45 /*
46 * troff10.c
47 *
48 * typesetter interface
49 */
50
51 int vpos = 0; /* absolute vertical position on page */
52 int hpos = 0; /* ditto horizontal */
53
54 short *chtab;
55 char *chname;
56 char *fontab[NFONT+1];
57 char *kerntab[NFONT+1];
58 char *fitab[NFONT+1];
59 char *codetab[NFONT+1];
60
61 int Inch;
62 int Hor;
63 int Vert;
64 int Unitwidth;
65 int nfonts;
66 int nsizes;
67 int nchtab;
68
69 /* these characters are used as various signals or values
70 * in miscellaneous places.
71 * values are set in specnames in t10.c
72 */
73
74 int c_hyphen;
75 int c_emdash;
76 int c_rule;
77 int c_minus;
78 int c_fi;
79 int c_fl;
80 int c_ff;
81 int c_ffi;
82 int c_ffl;
83 int c_acute;
84 int c_grave;
85 int c_under;
86 int c_rooten;
87 int c_boxrule;
88 int c_lefthand;
89 int c_dagger;
90
91 #include "dev.h"
92 struct dev dev;
93 struct Font *fontbase[NFONT+1];
94
95 tchar *ptout0();
96
97
98 int
ptinit()99 ptinit()
100 {
101 int i, fin, nw;
102 char *setbrk(), *filebase, *p;
103
104 /* open table for device,
105 * read in resolution, size info, font info, etc.
106 * and set params
107 */
108 strcat(termtab, "/dev");
109 strcat(termtab, devname);
110 strcat(termtab, "/DESC.out"); /* makes "..../devXXX/DESC.out" */
111 if ((fin = open(termtab, 0)) < 0) {
112 errprint(gettext("can't open tables for %s"), termtab);
113 done3(1);
114 }
115 read(fin, (char *) &dev, sizeof(struct dev ));
116 Inch = dev.res;
117 Hor = dev.hor;
118 Vert = dev.vert;
119 Unitwidth = dev.unitwidth;
120 nfonts = dev.nfonts;
121 nsizes = dev.nsizes;
122 nchtab = dev.nchtab;
123 if (nchtab >= NCHARS - 128) {
124 errprint(gettext("too many special characters in file %s"),
125 termtab);
126 done3(1);
127 }
128 filebase = setbrk(dev.filesize + 2*EXTRAFONT); /* enough room for whole file */
129 read(fin, filebase, dev.filesize); /* all at once */
130 pstab = (short *) filebase;
131 chtab = pstab + nsizes + 1;
132 chname = (char *) (chtab + dev.nchtab);
133 p = chname + dev.lchname;
134 for (i = 1; i <= nfonts; i++) {
135 fontbase[i] = (struct Font *) p;
136 nw = *p & BYTEMASK; /* 1st thing is width count */
137 fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]);
138 /* for now, still 2 char names */
139 if (smnt == 0 && fontbase[i]->specfont == 1)
140 smnt = i; /* first special font */
141 p += sizeof(struct Font); /* that's what's on the beginning */
142 fontab[i] = p;
143 kerntab[i] = p + nw;
144 codetab[i] = p + 2 * nw;
145 fitab[i] = p + 3 * nw; /* skip width, kern, code */
146 p += 3 * nw + dev.nchtab + 128 - 32;
147 }
148 fontbase[0] = (struct Font *) p; /* the last shall be first */
149 fontbase[0]->nwfont = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct Font);
150 fontab[0] = p + sizeof (struct Font);
151 close(fin);
152 /* there are a lot of things that used to be constant
153 * that now require code to be executed.
154 */
155 sps = SPS;
156 ics = ICS;
157 for (i = 0; i < 16; i++)
158 tabtab[i] = DTAB * (i + 1);
159 pl = 11 * INCH;
160 po = PO;
161 spacesz = SS;
162 lss = lss1 = VS;
163 ll = ll1 = lt = lt1 = LL;
164 specnames(); /* install names like "hyphen", etc. */
165 if (ascii)
166 return (0);
167 fdprintf(ptid, "x T %s\n", devname);
168 fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert);
169 fdprintf(ptid, "x init\n"); /* do initialization for particular device */
170 /*
171 for (i = 1; i <= nfonts; i++)
172 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
173 fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth);
174 fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n",
175 dev.nchtab, dev.lchname, dev.nchtab+128-32);
176 fdprintf(ptid, "x xxx sizes:\nx xxx ");
177 for (i = 0; i < nsizes; i++)
178 fdprintf(ptid, " %d", pstab[i]);
179 fdprintf(ptid, "\nx xxx chars:\nx xxx ");
180 for (i = 0; i < dev.nchtab; i++)
181 fdprintf(ptid, " %s", &chname[chtab[i]]);
182 fdprintf(ptid, "\nx xxx\n");
183 */
184
185 return (0);
186 }
187
188 int
specnames()189 specnames()
190 {
191 static struct {
192 int *n;
193 char *v;
194 } spnames[] = {
195 &c_hyphen, "hy",
196 &c_emdash, "em",
197 &c_rule, "ru",
198 &c_minus, "\\-",
199 &c_fi, "fi",
200 &c_fl, "fl",
201 &c_ff, "ff",
202 &c_ffi, "Fi",
203 &c_ffl, "Fl",
204 &c_acute, "aa",
205 &c_grave, "ga",
206 &c_under, "ul",
207 &c_rooten, "rn",
208 &c_boxrule, "br",
209 &c_lefthand, "lh",
210 &c_dagger, "dg",
211 0, 0
212 };
213 int i;
214
215 for (i = 0; spnames[i].n; i++)
216 *spnames[i].n = findch(spnames[i].v);
217
218 return (0);
219 }
220
221 int
findch(s)222 findch(s) /* find char s in chname */
223 char *s;
224 {
225 int i;
226
227 for (i = 0; i < nchtab; i++)
228 if (strcmp(s, &chname[chtab[i]]) == 0)
229 return(i + 128);
230 return(0);
231 }
232
233 int
ptout(i)234 ptout(i)
235 tchar i;
236 {
237 int dv;
238 tchar *k;
239 int temp, a, b;
240
241 if (cbits(i) != '\n') {
242 *olinep++ = i;
243 return (0);
244 }
245 if (olinep == oline) {
246 lead += lss;
247 return (0);
248 }
249
250 hpos = po; /* ??? */
251 esc = 0; /* ??? */
252 ptesc(); /* the problem is to get back to the left end of the line */
253 dv = 0;
254 for (k = oline; k < olinep; k++) {
255 if (ismot(*k) && isvmot(*k)) {
256 temp = absmot(*k);
257 if (isnmot(*k))
258 temp = -temp;
259 dv += temp;
260 }
261 }
262 if (dv) {
263 vflag++;
264 *olinep++ = makem(-dv);
265 vflag = 0;
266 }
267
268 b = dip->blss + lss;
269 lead += dip->blss + lss;
270 dip->blss = 0;
271 for (k = oline; k < olinep; )
272 k = ptout0(k); /* now passing a pointer! */
273 olinep = oline;
274 lead += dip->alss;
275 a = dip->alss;
276 dip->alss = 0;
277 /*
278 fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos);
279 */
280 fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */
281
282 return (0);
283 }
284
285 tchar *
ptout0(pi)286 ptout0(pi)
287 tchar *pi;
288 {
289 short j, k, w;
290 short z, dx, dy, dx2, dy2, n;
291 tchar i;
292 int outsize; /* size of object being printed */
293
294 outsize = 1; /* default */
295 i = *pi;
296 k = cbits(i);
297 if (ismot(i)) {
298 j = absmot(i);
299 if (isnmot(i))
300 j = -j;
301 if (isvmot(i))
302 lead += j;
303 else
304 esc += j;
305 return(pi+outsize);
306 }
307 if (k == XON) {
308 if (xfont != mfont)
309 ptfont();
310 if (xpts != mpts)
311 ptps();
312 if (lead)
313 ptlead();
314 fdprintf(ptid, "x X ");
315 /*
316 * not guaranteed of finding a XOFF if a word overflow
317 * error occured, so also bound this loop by olinep
318 */
319 pi++;
320 while( cbits(*pi) != XOFF && pi < olinep )
321 outascii(*pi++);
322 oput('\n');
323 if ( cbits(*pi) == XOFF )
324 pi++;
325 return pi;
326 }
327 ;
328 if (k == CHARHT) {
329 if (xpts != mpts)
330 ptps();
331 fdprintf(ptid, "x H %d\n", sbits(i));
332 return(pi+outsize);
333 }
334 if (k == SLANT) {
335 fdprintf(ptid, "x S %d\n", sfbits(i)-180);
336 return(pi+outsize);
337 }
338 if (k == WORDSP) {
339 oput('w');
340 return(pi+outsize);
341 }
342 if (k == FONTPOS) {
343 char temp[3];
344 n = i >> 16;
345 temp[0] = n & BYTEMASK;
346 temp[1] = n >> BYTE;
347 temp[2] = 0;
348 ptfpcmd(0, temp);
349 return(pi+outsize);
350 }
351 if (sfbits(i) == oldbits) {
352 xfont = pfont;
353 xpts = ppts;
354 } else
355 xbits(i, 2);
356 if (k < 040 && k != DRAWFCN)
357 return(pi+outsize);
358 if (k >= 32) {
359 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) {
360 w = widcache[k-32].width;
361 bd = 0;
362 cs = 0;
363 } else
364 w = getcw(k-32);
365 }
366 j = z = 0;
367 if (k != DRAWFCN) {
368 if (cs) {
369 if (bd)
370 w += (bd - 1) * HOR;
371 j = (cs - w) / 2;
372 w = cs - j;
373 if (bd)
374 w -= (bd - 1) * HOR;
375 }
376 if (iszbit(i)) {
377 if (cs)
378 w = -j;
379 else
380 w = 0;
381 z = 1;
382 }
383 }
384 esc += j;
385 if (xfont != mfont)
386 ptfont();
387 if (xpts != mpts)
388 ptps();
389 if (lead)
390 ptlead();
391 /* put out the real character here */
392 if (k == DRAWFCN) {
393 if (esc)
394 ptesc();
395 dx = absmot(pi[3]);
396 if (isnmot(pi[3]))
397 dx = -dx;
398 dy = absmot(pi[4]);
399 if (isnmot(pi[4]))
400 dy = -dy;
401 switch (cbits(pi[1])) {
402 case DRAWCIRCLE: /* circle */
403 fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */
404 w = 0;
405 hpos += dx;
406 break;
407 case DRAWELLIPSE:
408 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
409 w = 0;
410 hpos += dx;
411 break;
412 case DRAWLINE: /* line */
413 k = cbits(pi[2]);
414 fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy);
415 if (k < 128)
416 fdprintf(ptid, "%c\n", k);
417 else
418 fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]);
419 w = 0;
420 hpos += dx;
421 vpos += dy;
422 break;
423 case DRAWARC: /* arc */
424 dx2 = absmot(pi[5]);
425 if (isnmot(pi[5]))
426 dx2 = -dx2;
427 dy2 = absmot(pi[6]);
428 if (isnmot(pi[6]))
429 dy2 = -dy2;
430 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
431 dx, dy, dx2, dy2);
432 w = 0;
433 hpos += dx + dx2;
434 vpos += dy + dy2;
435 break;
436 case DRAWSPLINE: /* spline */
437 default: /* something else; copy it like spline */
438 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
439 w = 0;
440 hpos += dx;
441 vpos += dy;
442 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
443 /* it was somehow defective */
444 fdprintf(ptid, "\n");
445 break;
446 }
447 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
448 dx = absmot(pi[n]);
449 if (isnmot(pi[n]))
450 dx = -dx;
451 dy = absmot(pi[n+1]);
452 if (isnmot(pi[n+1]))
453 dy = -dy;
454 fdprintf(ptid, " %d %d", dx, dy);
455 hpos += dx;
456 vpos += dy;
457 }
458 fdprintf(ptid, "\n");
459 break;
460 }
461 for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
462 ;
463 outsize = n + 1;
464 } else if (k < 128) {
465 /* try to go faster and compress output */
466 /* by printing nnc for small positive motion followed by c */
467 /* kludgery; have to make sure set all the vars too */
468 if (esc > 0 && esc < 100) {
469 oput(esc / 10 + '0');
470 oput(esc % 10 + '0');
471 oput(k);
472 hpos += esc;
473 esc = 0;
474 } else {
475 if (esc)
476 ptesc();
477 oput('c');
478 oput(k);
479 oput('\n');
480 }
481 } else {
482 if (esc)
483 ptesc();
484 if (k >= nchtab + 128)
485 fdprintf(ptid, "N%d\n", k - (nchtab+128));
486 else
487 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
488 }
489 if (bd) {
490 bd -= HOR;
491 if (esc += bd)
492 ptesc();
493 if (k < 128) {
494 fdprintf(ptid, "c%c\n", k);
495 } else if (k >= nchtab + 128) {
496 fdprintf(ptid, "N%d\n", k - (nchtab+128));
497 } else
498 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
499 if (z)
500 esc -= bd;
501 }
502 esc += w;
503 return(pi+outsize);
504 }
505
506 int
ptps()507 ptps()
508 {
509 int i, j, k;
510
511 i = xpts;
512 for (j = 0; i > (k = pstab[j]); j++)
513 if (!k) {
514 k = pstab[--j];
515 break;
516 }
517 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */
518 mpts = i;
519
520 return (0);
521 }
522
523 int
ptfont()524 ptfont()
525 {
526 mfont = xfont;
527 fdprintf(ptid, "f%d\n", xfont);
528
529 return (0);
530 }
531
532 int
ptfpcmd(f,s)533 ptfpcmd(f, s)
534 int f;
535 char *s;
536 {
537 if (ascii)
538 return (0);
539 fdprintf(ptid, "x font %d %s\n", f, s);
540 ptfont(); /* make sure that it gets noticed */
541
542 return (0);
543 }
544
545 int
ptlead()546 ptlead()
547 {
548 vpos += lead;
549 if (!ascii)
550 fdprintf(ptid, "V%d\n", vpos);
551 lead = 0;
552
553 return (0);
554 }
555
556
557 int
ptesc()558 ptesc()
559 {
560 hpos += esc;
561 if (esc > 0) {
562 oput('h');
563 if (esc>=10 && esc<100) {
564 oput(esc/10 + '0');
565 oput(esc%10 + '0');
566 } else
567 fdprintf(ptid, "%d", esc);
568 } else
569 fdprintf(ptid, "H%d\n", hpos);
570 esc = 0;
571
572 return (0);
573 }
574
575
576 int
newpage(n)577 newpage(n) /* called at end of each output page (we hope) */
578 {
579 int i;
580
581 ptlead();
582 vpos = 0;
583 if (ascii)
584 return (0);
585 fdprintf(ptid, "p%d\n", n); /* new page */
586 for (i = 0; i <= nfonts; i++)
587 if (fontbase[i]->namefont && fontbase[i]->namefont[0])
588 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
589 ptps();
590 ptfont();
591
592 return (0);
593 }
594
595 int
pttrailer()596 pttrailer()
597 {
598 fdprintf(ptid, "x trailer\n");
599
600 return (0);
601 }
602
603 int
ptstop()604 ptstop()
605 {
606 fdprintf(ptid, "x stop\n");
607
608 return (0);
609 }
610
611 int
dostop()612 dostop()
613 {
614 if (ascii)
615 return (0);
616 ptlead();
617 vpos = 0;
618 /* fdprintf(ptid, "x xxx end of page\n");*/
619 if (!nofeed)
620 pttrailer();
621 ptlead();
622 fdprintf(ptid, "x pause\n");
623 flusho();
624 mpts = mfont = 0;
625 ptesc();
626 esc = po;
627 hpos = vpos = 0; /* probably in wrong place */
628
629 return (0);
630 }
631