xref: /illumos-gate/usr/src/cmd/troff/troff.d/t10.c (revision e4d060fb4c00d44cd578713eb9a921f594b733b8)
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
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
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
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
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 *
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
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
524 ptfont()
525 {
526 	mfont = xfont;
527 	fdprintf(ptid, "f%d\n", xfont);
528 
529 	return (0);
530 }
531 
532 int
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
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
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
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
596 pttrailer()
597 {
598 	fdprintf(ptid, "x trailer\n");
599 
600 	return (0);
601 }
602 
603 int
604 ptstop()
605 {
606 	fdprintf(ptid, "x stop\n");
607 
608 	return (0);
609 }
610 
611 int
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