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