1 #include "tdef.h"
2 #include "fns.h"
3 #include "ext.h"
4 
5 /*
6  * troff10.c
7  *
8  * typesetter interface
9  */
10 
11 int	vpos	 = 0;	/* absolute vertical position on page */
12 int	hpos	 = 0;	/* ditto horizontal */
13 
14 extern Font fonts[MAXFONTS+1];
15 
16 int	Inch;
17 int	Hor;
18 int	Vert;
19 int	Unitwidth;
20 int	nfonts;
21 
22 
23 
t_ptinit(void)24 void t_ptinit(void)
25 {
26 	int i;
27 	char buf[100], *p;
28 
29 	hmot = t_hmot;
30 	makem = t_makem;
31 	setabs = t_setabs;
32 	setch = t_setch;
33 	sethl = t_sethl;
34 	setht = t_setht;
35 	setslant = t_setslant;
36 	vmot = t_vmot;
37 	xlss = t_xlss;
38 	findft = t_findft;
39 	width = t_width;
40 	mchbits = t_mchbits;
41 	ptlead = t_ptlead;
42 	ptout = t_ptout;
43 	ptpause = t_ptpause;
44 	setfont = t_setfont;
45 	setps = t_setps;
46 	setwd = t_setwd;
47 
48 	/* open table for device, */
49 	/* read in resolution, size info, font info, etc., set params */
50 	if ((p = getenv("TYPESETTER")) != 0)
51 		strcpy(devname, p);
52 	if (termtab[0] == 0)
53 		strcpy(termtab, DWBfontdir);
54 	if (fontdir[0] == 0)
55 		strcpy(fontdir, DWBfontdir);
56 	if (devname[0] == 0)
57 		strcpy(devname, TDEVNAME);
58 	hyf = 1;
59 	lg = 1;
60 
61 	sprintf(buf, "/dev%s/DESC", devname);
62 	strcat(termtab, buf);
63 	if (getdesc(termtab) < 0) {
64 		ERROR "can't open DESC file %s", termtab WARN;
65 		done3(1);
66 	}
67 	if (!ascii) {
68 		OUT "x T %s\n", devname PUT;
69 		OUT "x res %d %d %d\n", Inch, Hor, Vert PUT;
70 		OUT "x init\n" PUT;
71 	}
72 	for (i = 1; i <= nfonts; i++)
73 		setfp(i, fontlab[i], (char *) 0, 0);
74 	sps = EM/3;	/* space size */
75 	ics = EM;	/* insertion character space */
76 	for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++)
77 		tabtab[i] = DTAB * (i + 1);
78 	tabtab[NTAB-1] = 0;
79 	pl = 11 * INCH;			/* paper length */
80 	po = PO;		/* page offset */
81 	spacesz = SS;
82 	lss = lss1 = VS;
83 	ll = ll1 = lt = lt1 = LL;
84 	t_specnames();	/* install names like "hyphen", etc. */
85 }
86 
t_specnames(void)87 void t_specnames(void)
88 {
89 	int	i;
90 
91 	for (i = 0; spnames[i].n; i++)
92 		*spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
93 }
94 
t_ptout(Tchar i)95 void t_ptout(Tchar i)
96 {
97 	int dv;
98 	Tchar *k;
99 	int temp, a, b;
100 	int diff;
101 
102 	if (cbits(i) != '\n') {
103 		if (olinep >= oline + olnsize) {
104 			diff = olinep - oline;
105 			olnsize += OLNSIZE;
106 			if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
107 				if (diff && olinep)
108 					olinep = oline + diff;
109 			} else {
110 				ERROR "Output line overflow." WARN;
111 				done(2);
112 			}
113 		}
114 		*olinep++ = i;
115 		return;
116 	}
117 	if (olinep == oline) {
118 		lead += lss;
119 		return;
120 	}
121 
122 	hpos = po;	/* ??? */
123 	esc = 0;	/* ??? */
124 	ptesc();	/* the problem is to get back to the left end of the line */
125 	dv = 0;
126 	for (k = oline; k < olinep; k++) {
127 		if (ismot(*k) && isvmot(*k)) {
128 			temp = absmot(*k);
129 			if (isnmot(*k))
130 				temp = -temp;
131 			dv += temp;
132 		}
133 	}
134 	if (dv) {
135 		vflag++;
136 		*olinep++ = makem(-dv);
137 		vflag = 0;
138 	}
139 
140 	b = dip->blss + lss;
141 	lead += dip->blss + lss;
142 	dip->blss = 0;
143 	for (k = oline; k < olinep; )
144 		k += ptout0(k);	/* now passing a pointer! */
145 	olinep = oline;
146 	lead += dip->alss;
147 	a = dip->alss;
148 	dip->alss = 0;
149 	/*
150 	OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;
151 */
152 	OUT "n%d %d\n", b, a PUT;	/* be nice to chuck */
153 }
154 
ptout0(Tchar * pi)155 int ptout0(Tchar *pi)
156 {
157 	int j, k, w;
158 	int z, dx, dy, dx2, dy2, n;
159 	Tchar i;
160 	int outsize;	/* size of object being printed */
161 
162 	w = 0;
163 	outsize = 1;	/* default */
164 	i = *pi;
165 	k = cbits(i);
166 	if (ismot(i)) {
167 		j = absmot(i);
168 		if (isnmot(i))
169 			j = -j;
170 		if (isvmot(i))
171 			lead += j;
172 		else
173 			esc += j;
174 		return(outsize);
175 	}
176 	if (k == CHARHT) {
177 		xpts = fbits(i);	/* sneaky, font bits as size bits */
178 		if (xpts != mpts)
179 			ptps();
180 		OUT "x H %ld\n", sbits(i) PUT;
181 		return(outsize);
182 	}
183 	if (k == SLANT) {
184 		OUT "x S %ld\n", sfbits(i)-180 PUT;
185 		return(outsize);
186 	}
187 	if (k == WORDSP) {
188 		oput('w');
189 		return(outsize);
190 	}
191 	if (sfbits(i) == oldbits) {
192 		xfont = pfont;
193 		xpts = ppts;
194 	} else
195 		xbits(i, 2);
196 	if (k == XON) {
197 		extern int xon;
198 		ptflush();	/* guarantee that everything is out */
199 		if (esc)
200 			ptesc();
201 		if (xfont != mfont)
202 			ptfont();
203 		if (xpts != mpts)
204 			ptps();
205 		if (lead)
206 			ptlead();
207 		OUT "x X " PUT;
208 		xon++;
209 		for (j = 1; cbits(pi[j]) != XOFF; j++)
210 			outascii(pi[j]);
211 		oput('\n');
212 		xon--;
213 		return j+1;
214 	}
215 	if (k < 040 && k != DRAWFCN)
216 		return(outsize);
217 	j = z = 0;
218 	if (k != DRAWFCN) {
219 		if (widcache[k].fontpts == (xfont<<8) + xpts  && !setwdf) {
220 			w = widcache[k].width;
221 			bd = 0;
222 			cs = 0;
223 		} else
224 			w = getcw(k);
225 		if (cs) {
226 			if (bd)
227 				w += (bd - 1) * HOR;
228 			j = (cs - w) / 2;
229 			w = cs - j;
230 			if (bd)
231 				w -= (bd - 1) * HOR;
232 		}
233 		if (iszbit(i)) {
234 			if (cs)
235 				w = -j;
236 			else
237 				w = 0;
238 			z = 1;
239 		}
240 	}
241 	esc += j;
242 	if (xfont != mfont)
243 		ptfont();
244 	if (xpts != mpts)
245 		ptps();
246 	if (lead)
247 		ptlead();
248 	/* put out the real character here */
249 	if (k == DRAWFCN) {
250 		if (esc)
251 			ptesc();
252 		w = 0;
253 		dx = absmot(pi[3]);
254 		if (isnmot(pi[3]))
255 			dx = -dx;
256 		dy = absmot(pi[4]);
257 		if (isnmot(pi[4]))
258 			dy = -dy;
259 		switch (cbits(pi[1])) {
260 		case DRAWCIRCLE:	/* circle */
261 			OUT "D%c %d\n", DRAWCIRCLE, dx PUT;	/* dx is diameter */
262 			hpos += dx;
263 			break;
264 		case DRAWELLIPSE:
265 			OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;
266 			hpos += dx;
267 			break;
268 		case DRAWBUILD:
269 			k = cbits(pi[2]);
270 			OUT "D%c %d ", DRAWBUILD, dx PUT;
271 			if (k < ALPHABET)
272 				OUT "%c\n", k PUT;
273 			else
274 				ptchname(k);
275 			hpos += dx;
276 			break;
277 		case DRAWLINE:	/* line */
278 			k = cbits(pi[2]);
279 			OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;
280 			if (k < ALPHABET)
281 				OUT "%c\n", k PUT;
282 			else
283 				ptchname(k);
284 			hpos += dx;
285 			vpos += dy;
286 			break;
287 		case DRAWARC:	/* arc */
288 			dx2 = absmot(pi[5]);
289 			if (isnmot(pi[5]))
290 				dx2 = -dx2;
291 			dy2 = absmot(pi[6]);
292 			if (isnmot(pi[6]))
293 				dy2 = -dy2;
294 			OUT "D%c %d %d %d %d\n", DRAWARC,
295 				dx, dy, dx2, dy2 PUT;
296 			hpos += dx + dx2;
297 			vpos += dy + dy2;
298 			break;
299 
300 		case 's':	/* using 's' internally to avoid .tr ~ */
301 			pi[1] = '~';
302 		case DRAWSPLINE:	/* spline */
303 		default:	/* something else; copy it like spline */
304 			OUT "D%c %d %d", (char)cbits(pi[1]), dx, dy PUT;
305 			hpos += dx;
306 			vpos += dy;
307 			if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
308 				/* it was somehow defective */
309 				OUT "\n" PUT;
310 				break;
311 			}
312 			for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
313 				dx = absmot(pi[n]);
314 				if (isnmot(pi[n]))
315 					dx = -dx;
316 				dy = absmot(pi[n+1]);
317 				if (isnmot(pi[n+1]))
318 					dy = -dy;
319 				OUT " %d %d", dx, dy PUT;
320 				hpos += dx;
321 				vpos += dy;
322 			}
323 			OUT "\n" PUT;
324 			break;
325 		}
326 		for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
327 			;
328 		outsize = n + 1;
329 	} else if (k < ALPHABET) {
330 		/* try to go faster and compress output */
331 		/* by printing nnc for small positive motion followed by c */
332 		/* kludgery; have to make sure set all the vars too */
333 		if (esc > 0 && esc < 100) {
334 			oput(esc / 10 + '0');
335 			oput(esc % 10 + '0');
336 			oput(k);
337 			hpos += esc;
338 			esc = 0;
339 		} else {
340 			if (esc)
341 				ptesc();
342 			oput('c');
343 			oput(k);
344 			oput('\n');
345 		}
346 	} else {
347 		if (esc)
348 			ptesc();
349 		ptchname(k);
350 	}
351 	if (bd) {
352 		bd -= HOR;
353 		if (esc += bd)
354 			ptesc();
355 		if (k < ALPHABET)
356 			OUT "c%c\n", k PUT;
357 		else
358 			ptchname(k);
359 		if (z)
360 			esc -= bd;
361 	}
362 	esc += w;
363 	return(outsize);
364 }
365 
ptchname(int k)366 void ptchname(int k)
367 {
368 	char *chn = chname(k);
369 
370 	switch (chn[0]) {
371 	case MBchar:
372 		OUT "c%s\n", chn+1 PUT;	/* \n not needed? */
373 		break;
374 	case Number:
375 		OUT "N%s\n", chn+1 PUT;
376 		break;
377 	case Troffchar:
378 		OUT "C%s\n", chn+1 PUT;
379 		break;
380 	default:
381 		ERROR "illegal char type %s", chn WARN;
382 		break;
383 	}
384 }
385 
ptflush(void)386 void ptflush(void)	/* get us to a clean output state */
387 {
388 	if (TROFF) {
389 		/* ptesc(); but always H, no h */
390 		hpos += esc;
391 		OUT "\nH%d\n", hpos PUT;
392 		esc = 0;
393 		ptps();
394 		ptfont();
395 		ptlead();
396 	}
397 }
398 
ptps(void)399 void ptps(void)
400 {
401 	int i, j, k;
402 
403 	i = xpts;
404 	for (j = 0; i > (k = pstab[j]); j++)
405 		if (!k) {
406 			k = pstab[--j];
407 			break;
408 		}
409 	if (!ascii)
410 		OUT "s%d\n", k PUT;	/* really should put out string rep of size */
411 	mpts = i;
412 }
413 
ptfont(void)414 void ptfont(void)
415 {
416 	mfont = xfont;
417 	if (ascii)
418 		return;
419 	if (xfont > nfonts) {
420 		ptfpcmd(0, fonts[xfont].longname, 0);	/* Put the desired font in the
421 					 * fontcache of the filter */
422 		OUT "f0\n" PUT;	/* make sure that it gets noticed */
423 	} else
424 		OUT "f%d\n", xfont PUT;
425 }
426 
ptfpcmd(int f,char * s,char * longname)427 void ptfpcmd(int f, char *s, char *longname)
428 {
429 	if (f > nfonts)		/* a bit risky? */
430 		f = 0;
431 	if (longname) {
432 		OUT "x font %d %s %s\n", f, s, longname PUT;
433 	} else {
434 		OUT "x font %d %s\n", f, s PUT;
435 	}
436 /*	OUT "f%d\n", xfont PUT;	/* need this for buggy version of adobe transcript */
437 				/* which apparently believes that x font means */
438 				/* to set the font, not just the position. */
439 }
440 
t_ptlead(void)441 void t_ptlead(void)
442 {
443 	vpos += lead;
444 	if (!ascii)
445 		OUT "V%d\n", vpos PUT;
446 	lead = 0;
447 }
448 
ptesc(void)449 void ptesc(void)
450 {
451 	hpos += esc;
452 	if (!ascii)
453 		if (esc > 0) {
454 			oput('h');
455 			if (esc>=10 && esc<100) {
456 				oput(esc/10 + '0');
457 				oput(esc%10 + '0');
458 			} else
459 				OUT "%d", esc PUT;
460 		} else
461 			OUT "H%d\n", hpos PUT;
462 	esc = 0;
463 }
464 
ptpage(int n)465 void ptpage(int n)	/* called at end of each output page, we hope */
466 {
467 	int i;
468 
469 	if (NROFF)
470 		return;
471 	ptlead();
472 	vpos = 0;
473 	if (ascii)
474 		return;
475 	OUT "p%d\n", n PUT;	/* new page */
476 	for (i = 0; i <= nfonts; i++)
477 		if (fontlab[i]) {
478 			if (fonts[i].truename)
479 				OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;
480 			else
481 				OUT "x font %d %s\n", i, fonts[i].longname PUT;
482 		}
483 	ptps();
484 	ptfont();
485 }
486 
pttrailer(void)487 void pttrailer(void)
488 {
489 	if (TROFF)
490 		OUT "x trailer\n" PUT;
491 }
492 
ptstop(void)493 void ptstop(void)
494 {
495 	if (TROFF)
496 		OUT "x stop\n" PUT;
497 }
498 
t_ptpause(void)499 void t_ptpause(void)
500 {
501 	if (ascii)
502 		return;
503 	ptlead();
504 	vpos = 0;
505 	pttrailer();
506 	ptlead();
507 	OUT "x pause\n" PUT;
508 	flusho();
509 	mpts = mfont = 0;
510 	ptesc();
511 	esc = po;
512 	hpos = vpos = 0;	/* probably in wrong place */
513 }
514