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