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