xref: /titanic_41/usr/src/cmd/troff/troff.d/t10.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*
34  * University Copyright- Copyright (c) 1982, 1986, 1988
35  * The Regents of the University of California
36  * All Rights Reserved
37  *
38  * University Acknowledgment- Portions of this document are derived from
39  * software developed by the University of California, Berkeley, and its
40  * contributors.
41  */
42 
43 #include "tdef.h"
44 #include <ctype.h>
45 #include "ext.h"
46 /*
47  * troff10.c
48  *
49  * typesetter interface
50  */
51 
52 int	vpos	 = 0;	/* absolute vertical position on page */
53 int	hpos	 = 0;	/* ditto horizontal */
54 
55 short	*chtab;
56 char	*chname;
57 char	*fontab[NFONT+1];
58 char	*kerntab[NFONT+1];
59 char	*fitab[NFONT+1];
60 char	*codetab[NFONT+1];
61 
62 int	Inch;
63 int	Hor;
64 int	Vert;
65 int	Unitwidth;
66 int	nfonts;
67 int	nsizes;
68 int	nchtab;
69 
70 /* these characters are used as various signals or values
71  * in miscellaneous places.
72  * values are set in specnames in t10.c
73  */
74 
75 int	c_hyphen;
76 int	c_emdash;
77 int	c_rule;
78 int	c_minus;
79 int	c_fi;
80 int	c_fl;
81 int	c_ff;
82 int	c_ffi;
83 int	c_ffl;
84 int	c_acute;
85 int	c_grave;
86 int	c_under;
87 int	c_rooten;
88 int	c_boxrule;
89 int	c_lefthand;
90 int	c_dagger;
91 
92 #include "dev.h"
93 struct dev dev;
94 struct Font *fontbase[NFONT+1];
95 
96 tchar *ptout0();
97 
98 
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;
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 
186 specnames()
187 {
188 	static struct {
189 		int	*n;
190 		char	*v;
191 	} spnames[] = {
192 		&c_hyphen, "hy",
193 		&c_emdash, "em",
194 		&c_rule, "ru",
195 		&c_minus, "\\-",
196 		&c_fi, "fi",
197 		&c_fl, "fl",
198 		&c_ff, "ff",
199 		&c_ffi, "Fi",
200 		&c_ffl, "Fl",
201 		&c_acute, "aa",
202 		&c_grave, "ga",
203 		&c_under, "ul",
204 		&c_rooten, "rn",
205 		&c_boxrule, "br",
206 		&c_lefthand, "lh",
207 		&c_dagger, "dg",
208 		0, 0
209 	};
210 	int	i;
211 
212 	for (i = 0; spnames[i].n; i++)
213 		*spnames[i].n = findch(spnames[i].v);
214 }
215 
216 findch(s)	/* find char s in chname */
217 register char	*s;
218 {
219 	register int	i;
220 
221 	for (i = 0; i < nchtab; i++)
222 		if (strcmp(s, &chname[chtab[i]]) == 0)
223 			return(i + 128);
224 	return(0);
225 }
226 
227 ptout(i)
228 register tchar	i;
229 {
230 	register dv;
231 	register tchar	*k;
232 	int temp, a, b;
233 
234 	if (cbits(i) != '\n') {
235 		*olinep++ = i;
236 		return;
237 	}
238 	if (olinep == oline) {
239 		lead += lss;
240 		return;
241 	}
242 
243 	hpos = po;	/* ??? */
244 	esc = 0;	/* ??? */
245 	ptesc();	/* the problem is to get back to the left end of the line */
246 	dv = 0;
247 	for (k = oline; k < olinep; k++) {
248 		if (ismot(*k) && isvmot(*k)) {
249 			temp = absmot(*k);
250 			if (isnmot(*k))
251 				temp = -temp;
252 			dv += temp;
253 		}
254 	}
255 	if (dv) {
256 		vflag++;
257 		*olinep++ = makem(-dv);
258 		vflag = 0;
259 	}
260 
261 	b = dip->blss + lss;
262 	lead += dip->blss + lss;
263 	dip->blss = 0;
264 	for (k = oline; k < olinep; )
265 		k = ptout0(k);	/* now passing a pointer! */
266 	olinep = oline;
267 	lead += dip->alss;
268 	a = dip->alss;
269 	dip->alss = 0;
270 	/*
271 	fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos);
272 */
273 	fdprintf(ptid, "n%d %d\n", b, a);	/* be nice to chuck */
274 }
275 
276 tchar *
277 ptout0(pi)
278 tchar	*pi;
279 {
280 	register short j, k, w;
281 	short	z, dx, dy, dx2, dy2, n;
282 	register tchar	i;
283 	int outsize;	/* size of object being printed */
284 
285 	outsize = 1;	/* default */
286 	i = *pi;
287 	k = cbits(i);
288 	if (ismot(i)) {
289 		j = absmot(i);
290 		if (isnmot(i))
291 			j = -j;
292 		if (isvmot(i))
293 			lead += j;
294 		else
295 			esc += j;
296 		return(pi+outsize);
297 	}
298 	if (k == XON) {
299 		if (xfont != mfont)
300 			ptfont();
301 		if (xpts != mpts)
302 			ptps();
303 		if (lead)
304 			ptlead();
305 		fdprintf(ptid, "x X ");
306 		/*
307 	     * not guaranteed of finding a XOFF if a word overflow
308 		 * error occured, so also bound this loop by olinep
309 		 */
310 		pi++;
311 		while( cbits(*pi) != XOFF && pi < olinep )
312 			outascii(*pi++);
313 		oput('\n');
314 		if ( cbits(*pi) == XOFF )
315 			pi++;
316 		return pi;
317 	}
318 			;
319 	if (k == CHARHT) {
320 		if (xpts != mpts)
321 			ptps();
322 		fdprintf(ptid, "x H %d\n", sbits(i));
323 		return(pi+outsize);
324 	}
325 	if (k == SLANT) {
326 		fdprintf(ptid, "x S %d\n", sfbits(i)-180);
327 		return(pi+outsize);
328 	}
329 	if (k == WORDSP) {
330 		oput('w');
331 		return(pi+outsize);
332 	}
333 	if (k == FONTPOS) {
334 		char temp[3];
335 		n = i >> 16;
336 		temp[0] = n & BYTEMASK;
337 		temp[1] = n >> BYTE;
338 		temp[2] = 0;
339 		ptfpcmd(0, temp);
340 		return(pi+outsize);
341 	}
342 	if (sfbits(i) == oldbits) {
343 		xfont = pfont;
344 		xpts = ppts;
345 	} else
346 		xbits(i, 2);
347 	if (k < 040 && k != DRAWFCN)
348 		return(pi+outsize);
349 	if (k >= 32) {
350 		if (widcache[k-32].fontpts == (xfont<<8) + xpts  && !setwdf) {
351 			w = widcache[k-32].width;
352 			bd = 0;
353 			cs = 0;
354 		} else
355 			w = getcw(k-32);
356 	}
357 	j = z = 0;
358 	if (k != DRAWFCN) {
359 		if (cs) {
360 			if (bd)
361 				w += (bd - 1) * HOR;
362 			j = (cs - w) / 2;
363 			w = cs - j;
364 			if (bd)
365 				w -= (bd - 1) * HOR;
366 		}
367 		if (iszbit(i)) {
368 			if (cs)
369 				w = -j;
370 			else
371 				w = 0;
372 			z = 1;
373 		}
374 	}
375 	esc += j;
376 	if (xfont != mfont)
377 		ptfont();
378 	if (xpts != mpts)
379 		ptps();
380 	if (lead)
381 		ptlead();
382 	/* put out the real character here */
383 	if (k == DRAWFCN) {
384 		if (esc)
385 			ptesc();
386 		dx = absmot(pi[3]);
387 		if (isnmot(pi[3]))
388 			dx = -dx;
389 		dy = absmot(pi[4]);
390 		if (isnmot(pi[4]))
391 			dy = -dy;
392 		switch (cbits(pi[1])) {
393 		case DRAWCIRCLE:	/* circle */
394 			fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx);	/* dx is diameter */
395 			w = 0;
396 			hpos += dx;
397 			break;
398 		case DRAWELLIPSE:
399 			fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
400 			w = 0;
401 			hpos += dx;
402 			break;
403 		case DRAWLINE:	/* line */
404 			k = cbits(pi[2]);
405 			fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy);
406 			if (k < 128)
407 				fdprintf(ptid, "%c\n", k);
408 			else
409 				fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]);
410 			w = 0;
411 			hpos += dx;
412 			vpos += dy;
413 			break;
414 		case DRAWARC:	/* arc */
415 			dx2 = absmot(pi[5]);
416 			if (isnmot(pi[5]))
417 				dx2 = -dx2;
418 			dy2 = absmot(pi[6]);
419 			if (isnmot(pi[6]))
420 				dy2 = -dy2;
421 			fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
422 				dx, dy, dx2, dy2);
423 			w = 0;
424 			hpos += dx + dx2;
425 			vpos += dy + dy2;
426 			break;
427 		case DRAWSPLINE:	/* spline */
428 		default:	/* something else; copy it like spline */
429 			fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
430 			w = 0;
431 			hpos += dx;
432 			vpos += dy;
433 			if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
434 				/* it was somehow defective */
435 				fdprintf(ptid, "\n");
436 				break;
437 			}
438 			for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
439 				dx = absmot(pi[n]);
440 				if (isnmot(pi[n]))
441 					dx = -dx;
442 				dy = absmot(pi[n+1]);
443 				if (isnmot(pi[n+1]))
444 					dy = -dy;
445 				fdprintf(ptid, " %d %d", dx, dy);
446 				hpos += dx;
447 				vpos += dy;
448 			}
449 			fdprintf(ptid, "\n");
450 			break;
451 		}
452 		for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
453 			;
454 		outsize = n + 1;
455 	} else if (k < 128) {
456 		/* try to go faster and compress output */
457 		/* by printing nnc for small positive motion followed by c */
458 		/* kludgery; have to make sure set all the vars too */
459 		if (esc > 0 && esc < 100) {
460 			oput(esc / 10 + '0');
461 			oput(esc % 10 + '0');
462 			oput(k);
463 			hpos += esc;
464 			esc = 0;
465 		} else {
466 			if (esc)
467 				ptesc();
468 			oput('c');
469 			oput(k);
470 			oput('\n');
471 		}
472 	} else {
473 		if (esc)
474 			ptesc();
475 		if (k >= nchtab + 128)
476 			fdprintf(ptid, "N%d\n", k - (nchtab+128));
477 		else
478 			fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
479 	}
480 	if (bd) {
481 		bd -= HOR;
482 		if (esc += bd)
483 			ptesc();
484 		if (k < 128) {
485 			fdprintf(ptid, "c%c\n", k);
486 		} else if (k >= nchtab + 128) {
487 			fdprintf(ptid, "N%d\n", k - (nchtab+128));
488 		} else
489 			fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
490 		if (z)
491 			esc -= bd;
492 	}
493 	esc += w;
494 	return(pi+outsize);
495 }
496 
497 ptps()
498 {
499 	register i, j, k;
500 
501 	i = xpts;
502 	for (j = 0; i > (k = pstab[j]); j++)
503 		if (!k) {
504 			k = pstab[--j];
505 			break;
506 		}
507 	fdprintf(ptid, "s%d\n", k);	/* really should put out string rep of size */
508 	mpts = i;
509 }
510 
511 ptfont()
512 {
513 	mfont = xfont;
514 	fdprintf(ptid, "f%d\n", xfont);
515 }
516 
517 ptfpcmd(f, s)
518 int	f;
519 char	*s;
520 {
521 	if (ascii)
522 		return;
523 	fdprintf(ptid, "x font %d %s\n", f, s);
524 	ptfont();	/* make sure that it gets noticed */
525 }
526 
527 ptlead()
528 {
529 	vpos += lead;
530 	if (!ascii)
531 		fdprintf(ptid, "V%d\n", vpos);
532 	lead = 0;
533 }
534 
535 ptesc()
536 {
537 	hpos += esc;
538 	if (esc > 0) {
539 		oput('h');
540 		if (esc>=10 && esc<100) {
541 			oput(esc/10 + '0');
542 			oput(esc%10 + '0');
543 		} else
544 			fdprintf(ptid, "%d", esc);
545 	} else
546 		fdprintf(ptid, "H%d\n", hpos);
547 	esc = 0;
548 }
549 
550 newpage(n)	/* called at end of each output page (we hope) */
551 {
552 	int i;
553 
554 	ptlead();
555 	vpos = 0;
556 	if (ascii)
557 		return;
558 	fdprintf(ptid, "p%d\n", n);	/* new page */
559 	for (i = 0; i <= nfonts; i++)
560 		if (fontbase[i]->namefont && fontbase[i]->namefont[0])
561 			fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
562 	ptps();
563 	ptfont();
564 }
565 
566 pttrailer()
567 {
568 	fdprintf(ptid, "x trailer\n");
569 }
570 
571 ptstop()
572 {
573 	fdprintf(ptid, "x stop\n");
574 }
575 
576 dostop()
577 {
578 	if (ascii)
579 		return;
580 	ptlead();
581 	vpos = 0;
582 	/* fdprintf(ptid, "x xxx end of page\n");*/
583 	if (!nofeed)
584 		pttrailer();
585 	ptlead();
586 	fdprintf(ptid, "x pause\n");
587 	flusho();
588 	mpts = mfont = 0;
589 	ptesc();
590 	esc = po;
591 	hpos = vpos = 0;	/* probably in wrong place */
592 }
593