1 #include "tdef.h"
2 extern
3 #include "d.h"
4 extern
5 #include "v.h"
6 /*
7 troff10.c
8 
9 CAT interface
10 */
11 
12 #include <sgtty.h>
13 #include "ext.h"
14 int	vpos	 = 0;	/* absolute vertical position on page */
15 int	hpos	 = 0;	/* ditto horizontal */
16 
17 #define	T_IESC	16
18 
19 short	*chtab;
20 char	*chname;
21 char	*fontab[NFONT+1];
22 char	*kerntab[NFONT+1];
23 char	*fitab[NFONT+1];
24 
25 int	Inch;
26 int	Hor;
27 int	Vert;
28 int	Unitwidth;
29 int	nfonts;
30 int	nsizes;
31 int	nchtab;
32 int	nstips;
33 int	xstip	= ~ST;
34 tchar *	stiplab;
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_narsp;
46 int	c_hnarsp;
47 int	c_fi;
48 int	c_fl;
49 int	c_ff;
50 int	c_ffi;
51 int	c_ffl;
52 int	c_acute;
53 int	c_grave;
54 int	c_under;
55 int	c_rooten;
56 int	c_boxrule;
57 int	c_lefthand;
58 
59 #include "dev.h"
60 struct dev dev;
61 struct font *fontbase[NFONT+1];
62 
63 
64 ptinit()
65 {
66 	int	i, fin, nw;
67 	char	*setbrk(), *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 		fprintf(stderr, "troff: can't open tables for %s\n", termtab);
78 		done3(1);
79 	}
80 	read(fin, &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.nstips;
89 			/* "unsigned" so very large files will work properly */
90 	stiplab = (tchar *) setbrk((nstips + 1) * sizeof(tchar));
91 	filebase = setbrk((unsigned short) dev.filesize + 2*EXTRAFONT);
92 						/* 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 & BMASK;	/* 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 		p += sizeof(struct font);	/* that's what's on the beginning */
104 		fontab[i] = p;
105 		kerntab[i] = p + nw;
106 		fitab[i] = p + 3 * nw;	/* skip width, kern, code */
107 		p += 3 * nw + dev.nchtab + 128 - 32;
108 	}
109 	for (i = 1; i <= nstips; i++) {		/* make stipple names tchars */
110 		stiplab[i] = PAIR(*p, *(p+1));
111 		while (*(p++));
112 	}
113 	fontbase[0] = (struct font *) p;	/* the last shall be first */
114 	fontbase[0]->nwfont = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct font);
115 	fontab[0] = p + sizeof (struct font);
116 	close(fin);
117 	/* there are a lot of things that used to be constant
118 	/* that now require code to be executed.
119 	*/
120 	sps = SPS;
121 	ics = ICS;
122 	for (i = 0; i < 16; i++)
123 		tabtab[i] = DTAB * (i + 1);
124 	pl = 11 * INCH;
125 	po = PO;
126 	spacesz = SS;
127 	lss = lss1 = VS;
128 	ll = ll1 = lt = lt1 = LL;
129 	specnames();	/* install names like "hyphen", etc. */
130 	if (ascii)
131 		return;
132 	fprintf(ptid, "x T %s\n", devname);
133 	fprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert);
134 	fprintf(ptid, "x init\n");	/* do initialization for particular device */
135 	for (i = 1; i <= nfonts; i++)
136 		fprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont);
137   /*
138 	fprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth);
139 	fprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n",
140 		dev.nchtab, dev.lchname, dev.nchtab+128-32);
141 	fprintf(ptid, "x xxx sizes:\nx xxx ");
142 	for (i = 0; i < nsizes; i++)
143 		fprintf(ptid, " %d", pstab[i]);
144 	fprintf(ptid, "\nx xxx chars:\nx xxx ");
145 	for (i = 0; i < dev.nchtab; i++)
146 		fprintf(ptid, " %s", &chname[chtab[i]]);
147 	fprintf(ptid, "\nx xxx\n");
148   */
149 }
150 
151 specnames()
152 {
153 	static struct {
154 		int	*n;
155 		char	*v;
156 	} spnames[] = {
157 		&c_hyphen, "hy",
158 		&c_emdash, "em",
159 		&c_rule, "ru",
160 		&c_minus, "\\-",
161 		&c_narsp, "\\|",
162 		&c_hnarsp, "\\^",
163 		&c_fi, "fi",
164 		&c_fl, "fl",
165 		&c_ff, "ff",
166 		&c_ffi, "Fi",
167 		&c_ffl, "Fl",
168 		&c_acute, "aa",
169 		&c_grave, "ga",
170 		&c_under, "ul",
171 		&c_rooten, "rn",
172 		&c_boxrule, "br",
173 		&c_lefthand, "lh",
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 
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 
193 ptout(i)
194 tchar	i;
195 {
196 	register dv, ik;
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 	fprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos);
238 */
239 	fprintf(ptid, "n%d %d\n", b, a);	/* be nice to chuck */
240 }
241 
242 ptout0(pi)
243 tchar	*pi;
244 {
245 	register short j, k, w;
246 	short	z, dx, dy, dx2, dy2, n;
247 	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 == CHARHT) {
264 		fprintf(ptid, "x H %d\n", sbits(i));
265 		return(outsize);
266 	}
267 	if (k == SLANT) {
268 		fprintf(ptid, "x S %d\n", sfbits(i)-180);
269 		return(outsize);
270 	}
271 	if (k == WORDSP) {
272 		oput('w');
273 		return(outsize);
274 	}
275 	if (k == FONTPOS) {
276 		char temp[3];
277 		n = i >> 16;
278 		temp[0] = n & BMASK;
279 		temp[1] = n >> BYTE;
280 		temp[2] = 0;
281 		ptfpcmd(0, temp);
282 		return(outsize);
283 	}
284 	xbitf = 2;
285 	if (sfbits(i) == oldbits) {
286 		xfont = pfont;
287 		xpts = ppts;
288 		xbitf = 0;
289 	} else
290 		xbits(i);
291 	if (k < 040 && k != DRAWFCN)
292 		return(outsize);
293 	w = getcw(k - 32);
294 	j = z = 0;
295 	if (k != DRAWFCN) {
296 		if (cs) {
297 			if (bd)
298 				w += (bd - 1) * HOR;
299 			j = (cs - w) / 2;
300 			w = cs - j;
301 			if (bd)
302 				w -= (bd - 1) * HOR;
303 		}
304 		if (iszbit(i)) {
305 			if (cs)
306 				w = -j;
307 			else
308 				w = 0;
309 			z = 1;
310 		}
311 	}
312 	esc += j;
313 	if (xfont != mfont)
314 		ptfont();
315 	if (xpts != mpts)
316 		ptps();
317 	if (lead)
318 		ptlead();
319 	/* put out the real character here */
320 	if (k == DRAWFCN) {
321 		if (esc)
322 			ptesc();
323 		dx = absmot(pi[2]);
324 		if (isnmot(pi[2]))
325 			dx = -dx;
326 		dy = absmot(pi[3]);
327 		if (isnmot(pi[3]))
328 			dy = -dy;
329 		switch (cbits(pi[1])) {
330 		case DRAWCIRCLE:	/* circle */
331 			fprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx);	/* dx is diameter */
332 			hpos += dx;
333 			break;
334 		case DRAWSTYLE:
335 			fprintf(ptid, "D%c %d\n", DRAWSTYLE, dx);
336 			break;
337 		case DRAWTHICK:
338 			fprintf(ptid, "D%c %d\n", DRAWTHICK, dx);
339 			break;
340 		case DRAWELLIPSE:
341 			fprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy);
342 			hpos += dx;
343 			break;
344 		case DRAWLINE:	/* line */
345 			fprintf(ptid, "D%c %d %d\n", DRAWLINE, dx, dy);
346 			hpos += dx;
347 			vpos += dy;
348 			break;
349 		case DRAWARC:	/* arc */
350 			dx2 = absmot(pi[4]);
351 			if (isnmot(pi[4]))
352 				dx2 = -dx2;
353 			dy2 = absmot(pi[5]);
354 			if (isnmot(pi[5]))
355 				dy2 = -dy2;
356 			fprintf(ptid, "D%c %d %d %d %d\n", DRAWARC,
357 				dx, dy, dx2, dy2);
358 			hpos += dx + dx2;
359 			vpos += dy + dy2;
360 			break;
361 		case DRAWWIG:	/* wiggly line  -or- */
362 		case DRAWCURVE:	/* gremlin-style curve */
363 			fprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy);
364 			hpos += dx;
365 			vpos += dy;
366 writecoords:
367 			for (n = 4; cbits(pi[n]) != '.'; n += 2) {
368 				dx = absmot(pi[n]);
369 				if (isnmot(pi[n]))
370 					dx = -dx;
371 				dy = absmot(pi[n+1]);
372 				if (isnmot(pi[n+1]))
373 					dy = -dy;
374 				fprintf(ptid, " %d %d", dx, dy);
375 				hpos += dx;
376 				vpos += dy;
377 			}
378 			fprintf(ptid, "\n");
379 			break;
380 
381 		case DRAWPOLY:	/* polygon with stipple */
382 		case DRAWUBPOLY:/* polygon, stipple, no border */
383 			if (xstip != stip) ptstip();
384 			fprintf(ptid, "D%c %d", cbits(pi[1]), dx);
385 			goto writecoords;
386 		}
387 		for (n = 2; cbits(pi[n]) != '.'; n++)
388 			;
389 		return(n + 1);		/* leave here so the emboldening */
390 	} else if (k < 128) {		/* doesn't screw up the graphics */
391 		/* try to go faster and compress output */
392 		/* by printing nnc for small positive motion followed by c */
393 		/* kludgery; have to make sure set all the vars too */
394 		if (esc > 0 && esc < 100) {
395 			oput(esc / 10 + '0');
396 			oput(esc % 10 + '0');
397 			oput(k);
398 			hpos += esc;
399 			esc = 0;
400 		} else {
401 			if (esc)
402 				ptesc();
403 			fprintf(ptid, "c%c\n", k);
404 		}
405 	} else {
406 		if (esc)
407 			ptesc();
408 		fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
409 	}
410 	if (bd) {
411 		bd -= HOR;
412 		if (esc += bd)
413 			ptesc();
414 		if (k < 128) {
415 			fprintf(ptid, "c%c\n", k);
416 		} else
417 			fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]);
418 		if (z)
419 			esc -= bd;
420 	}
421 	esc += w;
422 	return(outsize);
423 }
424 
425 ptps()
426 {
427 	register i, j, k;
428 
429 	i = xpts;
430 	for (j = 0; i > (k = pstab[j]); j++)
431 		if (!k) {
432 			k = pstab[--j];
433 			break;
434 		}
435 	fprintf(ptid, "s%d\n", k);	/* really should put out string rep of size */
436 	mpts = i;
437 }
438 
439 ptstip()
440 {
441 	xstip = stip;
442 	fprintf(ptid, "i%d\n", xstip);
443 }
444 
445 
446 ptfont()
447 {
448 	mfont = xfont;
449 	fprintf(ptid, "f%d\n", xfont);
450 }
451 
452 ptfpcmd(f, s)
453 int	f;
454 char	*s;
455 {
456 	if (ascii)
457 		return;
458 	fprintf(ptid, "x font %d %s\n", f, s);
459 	ptfont();	/* make sure that it gets noticed */
460 }
461 
462 ptlead()
463 {
464 	vpos += lead;
465 	if (!ascii)
466 		fprintf(ptid, "V%d\n", vpos);
467 	lead = 0;
468 }
469 
470 ptesc()
471 {
472 	hpos += esc;
473 	if (esc > 0)
474 		fprintf(ptid, "h%d", esc);
475 	else
476 		fprintf(ptid, "H%d\n", hpos);
477 	esc = 0;
478 }
479 
480 newpage(n)	/* called at end of each output page (we hope) */
481 {
482 	ptlead();
483 	vpos = 0;
484 	if (ascii)
485 		return;
486 	flusho();
487 	fprintf(ptid, "p%d\n", n);	/* new page */
488 	ptps();
489 	ptfont();
490 }
491 
492 pttrailer()
493 {
494 	fprintf(ptid, "x trailer\n");
495 }
496 
497 ptstop()
498 {
499 	fprintf(ptid, "x stop\n");
500 }
501 
502 dostop()
503 {
504 	if (ascii)
505 		return;
506 	ptlead();
507 	vpos = 0;
508 	/*	fprintf(ptid, "x xxx end of page\n");*/
509 	if (!nofeed)
510 		pttrailer();
511 	ptlead();
512 	fprintf(ptid, "x pause\n");
513 	flusho();
514 	mpts = mfont = 0;
515 	paper = 0;
516 	esc = T_IESC;	/* this is a dreg */
517 	ptesc();
518 	esc = po;
519 	hpos = vpos = 0;	/* probably in wrong place */
520 }
521