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