1 #ifndef lint
2 static char sccsid[] = "@(#)t10.c	2.1 (CWI) 85/07/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 		fdprintf(ptid, "x X ");
269 		for (j = 1; (c=cbits(pi[j])) != XOFF; j++)
270 			outascii(pi[j]);
271 		oput('\n');
272 		return j+1;
273 	}
274 			;
275 	if (k == CHARHT) {
276 		if (xpts != mpts)
277 			ptps();
278 		fdprintf(ptid, "x H %d\n", sbits(i));
279 		return(outsize);
280 	}
281 	if (k == SLANT) {
282 		fdprintf(ptid, "x S %d\n", sfbits(i)-180);
283 		return(outsize);
284 	}
285 	if (k == WORDSP) {
286 		oput('w');
287 		return(outsize);
288 	}
289 	if (sfbits(i) == oldbits) {
290 		xfont = pfont;
291 		xpts = ppts;
292 	} else
293 		xbits(i, 2);
294 	if (k < 040 && k != DRAWFCN)
295 		return(outsize);
296 	if (widcache[k-32].fontpts == (xfont<<8) + xpts  && !setwdf) {
297 		w = widcache[k-32].width;
298 		bd = 0;
299 		cs = 0;
300 	} else
301 		w = getcw(k-32);
302 	j = z = 0;
303 	if (k != DRAWFCN) {
304 		if (cs) {
305 			if (bd)
306 				w += (bd - 1) * HOR;
307 			j = (cs - w) / 2;
308 			w = cs - j;
309 			if (bd)
310 				w -= (bd - 1) * HOR;
311 		}
312 		if (iszbit(i)) {
313 			if (cs)
314 				w = -j;
315 			else
316 				w = 0;
317 			z = 1;
318 		}
319 	}
320 	esc += j;
321 	if (xfont != mfont)
322 		ptfont();
323 	if (xpts != mpts)
324 		ptps();
325 	if (lead)
326 		ptlead();
327 	/* put out the real character here */
328 	if (k == DRAWFCN) {
329 		if (esc)
330 			ptesc();
331 		dx = absmot(pi[3]);
332 		if (isnmot(pi[3]))
333 			dx = -dx;
334 		dy = absmot(pi[4]);
335 		if (isnmot(pi[4]))
336 			dy = -dy;
337 		switch (cbits(pi[1])) {
338 		case DRAWCIRCLE:	/* circle */
339 			fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx);	/* dx is diameter */
340 			w = 0;
341 			hpos += dx;
342 			break;
343 		case DRAWELLIPSE:
344 			fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
345 			w = 0;
346 			hpos += dx;
347 			break;
348 		case DRAWLINE:	/* line */
349 			k = cbits(pi[2]);
350 			fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy);
351 			if (k < 128)
352 				fdprintf(ptid, "%c\n", k);
353 			else
354 				fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]);
355 			w = 0;
356 			hpos += dx;
357 			vpos += dy;
358 			break;
359 		case DRAWARC:	/* arc */
360 			dx2 = absmot(pi[5]);
361 			if (isnmot(pi[5]))
362 				dx2 = -dx2;
363 			dy2 = absmot(pi[6]);
364 			if (isnmot(pi[6]))
365 				dy2 = -dy2;
366 			fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
367 				dx, dy, dx2, dy2);
368 			w = 0;
369 			hpos += dx + dx2;
370 			vpos += dy + dy2;
371 			break;
372 		case DRAWSPLINE:	/* spline */
373 		default:	/* something else; copy it like spline */
374 			fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
375 			w = 0;
376 			hpos += dx;
377 			vpos += dy;
378 			if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
379 				/* it was somehow defective */
380 				fdprintf(ptid, "\n");
381 				break;
382 			}
383 			for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
384 				dx = absmot(pi[n]);
385 				if (isnmot(pi[n]))
386 					dx = -dx;
387 				dy = absmot(pi[n+1]);
388 				if (isnmot(pi[n+1]))
389 					dy = -dy;
390 				fdprintf(ptid, " %d %d", dx, dy);
391 				hpos += dx;
392 				vpos += dy;
393 			}
394 			fdprintf(ptid, "\n");
395 			break;
396 		}
397 		for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
398 			;
399 		outsize = n + 1;
400 	} else if (k < 128) {
401 		/* try to go faster and compress output */
402 		/* by printing nnc for small positive motion followed by c */
403 		/* kludgery; have to make sure set all the vars too */
404 		if (esc > 0 && esc < 100) {
405 			oput(esc / 10 + '0');
406 			oput(esc % 10 + '0');
407 			oput(k);
408 			hpos += esc;
409 			esc = 0;
410 		} else {
411 			if (esc)
412 				ptesc();
413 			oput('c');
414 			oput(k);
415 			oput('\n');
416 		}
417 	} else {
418 		if (esc)
419 			ptesc();
420 		if (k >= nchtab + 128)
421 			fdprintf(ptid, "N%d\n", k - (nchtab+128));
422 		else
423 			fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
424 	}
425 	if (bd) {
426 		bd -= HOR;
427 		if (esc += bd)
428 			ptesc();
429 		if (k < 128) {
430 			fdprintf(ptid, "c%c\n", k);
431 		} else 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 		if (z)
436 			esc -= bd;
437 	}
438 	esc += w;
439 	return(outsize);
440 }
441 
442 ptps()
443 {
444 	register i, j, k;
445 
446 	i = xpts;
447 	for (j = 0; i > (k = pstab[j]); j++)
448 		if (!k) {
449 			k = pstab[--j];
450 			break;
451 		}
452 	fdprintf(ptid, "s%d\n", k);	/* really should put out string rep of size */
453 	mpts = i;
454 }
455 
456 ptfont()
457 {
458 	extern char *unpair();
459 	mfont = xfont;
460 	if( xfont > nfonts) {
461 		register char *temp = unpair(fontlab[xfont]);
462 		ptfpcmd(0, temp);	/* Put the desired font in the
463 					 * fontcache of the filter */
464 		fdprintf(ptid, "f0\n");	/* make sure that it gets noticed */
465 	} else
466 		fdprintf(ptid, "f%d\n", xfont);
467 }
468 
469 ptfpcmd(f, s)
470 int	f;
471 char	*s;
472 {
473 	if (ascii)
474 		return;
475 	fdprintf(ptid, "x font %d %s\n", f, s);
476 }
477 
478 ptlead()
479 {
480 	vpos += lead;
481 	if (!ascii)
482 		fdprintf(ptid, "V%d\n", vpos);
483 	lead = 0;
484 }
485 
486 ptesc()
487 {
488 	hpos += esc;
489 	if (esc > 0) {
490 		oput('h');
491 		if (esc>=10 && esc<100) {
492 			oput(esc/10 + '0');
493 			oput(esc%10 + '0');
494 		} else
495 			fdprintf(ptid, "%d", esc);
496 	} else
497 		fdprintf(ptid, "H%d\n", hpos);
498 	esc = 0;
499 }
500 
501 newpage(n)	/* called at end of each output page (we hope) */
502 {
503 	int i;
504 
505 	ptlead();
506 	vpos = 0;
507 	if (ascii)
508 		return;
509 	fdprintf(ptid, "p%d\n", n);	/* new page */
510 	for (i = 0; i <= nfonts; i++)
511 		if (fontbase[i]->namefont && fontbase[i]->namefont[0])
512 			fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
513 	ptps();
514 	ptfont();
515 }
516 
517 pttrailer()
518 {
519 	fdprintf(ptid, "x trailer\n");
520 }
521 
522 ptstop()
523 {
524 	fdprintf(ptid, "x stop\n");
525 }
526 
527 dostop()
528 {
529 	if (ascii)
530 		return;
531 	ptlead();
532 	vpos = 0;
533 	/* fdprintf(ptid, "x xxx end of page\n");*/
534 	if (!nofeed)
535 		pttrailer();
536 	ptlead();
537 	fdprintf(ptid, "x pause\n");
538 	flusho();
539 	mpts = mfont = 0;
540 	ptesc();
541 	esc = po;
542 	hpos = vpos = 0;	/* probably in wrong place */
543 }
544