xref: /illumos-gate/usr/src/cmd/troff/troff.d/t10.c (revision 7a6d80f1660abd4755c68cbd094d4a914681d26e)
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
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
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
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
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 *
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
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
522 ptfont()
523 {
524 	mfont = xfont;
525 	fdprintf(ptid, "f%d\n", xfont);
526 
527 	return (0);
528 }
529 
530 int
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
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
556 ptesc()
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
575 newpage(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 && fontbase[i]->namefont[0])
586 			fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
587 	ptps();
588 	ptfont();
589 
590 	return (0);
591 }
592 
593 int
594 pttrailer()
595 {
596 	fdprintf(ptid, "x trailer\n");
597 
598 	return (0);
599 }
600 
601 int
602 ptstop()
603 {
604 	fdprintf(ptid, "x stop\n");
605 
606 	return (0);
607 }
608 
609 int
610 dostop()
611 {
612 	if (ascii)
613 		return (0);
614 	ptlead();
615 	vpos = 0;
616 	/* fdprintf(ptid, "x xxx end of page\n");*/
617 	if (!nofeed)
618 		pttrailer();
619 	ptlead();
620 	fdprintf(ptid, "x pause\n");
621 	flusho();
622 	mpts = mfont = 0;
623 	ptesc();
624 	esc = po;
625 	hpos = vpos = 0;	/* probably in wrong place */
626 
627 	return (0);
628 }
629