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