1*1a4ecc79Sslatteng /*	dvar.c	1.2	83/07/09
2f92359bfSslatteng  *
3f92359bfSslatteng  * Varian driver for the new troff
4f92359bfSslatteng  *
5f92359bfSslatteng  * Authors:	BWK(BELL)
6f92359bfSslatteng  *		VCAT(berkley)
7f92359bfSslatteng  *		Richard L. Hyde, Perdue University
8f92359bfSslatteng  *		and David Slattengren, Berkeley
9f92359bfSslatteng  */
10f92359bfSslatteng 
11f92359bfSslatteng 
12f92359bfSslatteng /*******************************************************************************
13f92359bfSslatteng 
14f92359bfSslatteng     output language from troff:
15f92359bfSslatteng     all numbers are character strings
16f92359bfSslatteng 
17f92359bfSslatteng #..\n	comment
18f92359bfSslatteng sn	size in points
19f92359bfSslatteng fn	font as number from 1 to n
20f92359bfSslatteng cx	ascii character x
21f92359bfSslatteng Cxyz	funny char \(xyz. terminated by white space
22f92359bfSslatteng Hn	go to absolute horizontal position n
23f92359bfSslatteng Vn	go to absolute vertical position n (down is positive)
24f92359bfSslatteng hn	go n units horizontally (relative)
25f92359bfSslatteng vn	ditto vertically
26f92359bfSslatteng nnc	move right nn, then print c (exactly 2 digits!)
27f92359bfSslatteng 		(this wart is an optimization that shrinks output file size
28f92359bfSslatteng 		 about 35% and run-time about 15% while preserving ascii-ness)
29f92359bfSslatteng p	new page begins -- set v to 0
30f92359bfSslatteng nb a	end of line (information only -- no action needed)
31f92359bfSslatteng 	b = space before line, a = after
32f92359bfSslatteng w	paddable word space -- no action needed
33f92359bfSslatteng 
34f92359bfSslatteng Dt ..\n	draw operation 't':
35f92359bfSslatteng 	Dl x y		line from here by x,y
36f92359bfSslatteng 	Dc d		circle of diameter d with left side here
37f92359bfSslatteng 	De x y		ellipse of axes x,y with left side here
38f92359bfSslatteng 	Da x y r	arc counter-clockwise by x,y of radius r
39f92359bfSslatteng 	D~ x y x y ...	B-spline curve by x,y then x,y ...
40f92359bfSslatteng 
41f92359bfSslatteng x ..\n	device control functions:
42f92359bfSslatteng      x i	init
43f92359bfSslatteng      x T s	name of device is s
44f92359bfSslatteng      x r n h v	resolution is n/inch h = min horizontal motion, v = min vert
45f92359bfSslatteng      x p	pause (can restart)
46f92359bfSslatteng      x s	stop -- done for ever
47f92359bfSslatteng      x t	generate trailer
48f92359bfSslatteng      x f n s	font position n contains font s
49f92359bfSslatteng      x H n	set character height to n
50f92359bfSslatteng      x S n	set slant to N
51f92359bfSslatteng 
52f92359bfSslatteng 	Subcommands like "i" are often spelled out like "init".
53f92359bfSslatteng 
54f92359bfSslatteng *******************************************************************************/
55f92359bfSslatteng 
56f92359bfSslatteng 
57f92359bfSslatteng #include <stdio.h>
58f92359bfSslatteng #include <ctype.h>
59f92359bfSslatteng #include <sys/vcmd.h>
60f92359bfSslatteng #include "dev.h"
61f92359bfSslatteng 
62f92359bfSslatteng 
63f92359bfSslatteng #define DEBUGABLE		/* Yes, debugable... */
64f92359bfSslatteng #define	NFONTS	25		/* total number of fonts useable */
65f92359bfSslatteng #define	MAXSTATE 6		/* number of environments rememberable */
66f92359bfSslatteng #define OPENREAD 0		/* mode for openning files */
67f92359bfSslatteng #define RESTART	1		/* upon exit, return either RESTART */
68f92359bfSslatteng #define ABORT	2		/*     or ABORT */
69f92359bfSslatteng #define	FATAL	1		/* type of error */
70f92359bfSslatteng #define	BMASK	0377		/* byte grabber */
71f92359bfSslatteng #define FONTDIR	"/usr/lib/font"	/* default place to look for fonts */
72f92359bfSslatteng #define MAXWRIT 4096		/* max characters allowed to write at once */
73f92359bfSslatteng 
74f92359bfSslatteng #define  hmot(n)	hpos += n
75f92359bfSslatteng #define  hgoto(n)	hpos = n
76f92359bfSslatteng #define  vmot(n)	vgoto(vpos + n)
77f92359bfSslatteng 
78f92359bfSslatteng 
79*1a4ecc79Sslatteng char	SccsId[]= "dvar.c	1.2	83/07/09";
80f92359bfSslatteng 
81f92359bfSslatteng int	output	= 0;	/* do we do output at all? */
82f92359bfSslatteng int	nolist	= 0;	/* output page list if > 0 */
83f92359bfSslatteng int	olist[20];	/* pairs of page numbers */
84f92359bfSslatteng int	spage	= 9999;	/* stop every spage pages */
85f92359bfSslatteng int	scount	= 0;
86f92359bfSslatteng struct	dev	dev;
87f92359bfSslatteng struct	font	*fontbase[NFONTS+1];
88f92359bfSslatteng short	*pstab;		/* point size table pointer */
89f92359bfSslatteng int	res;		/* input was computed according to this resolution */
90f92359bfSslatteng int	nsizes;		/* number of sizes device is capable of printing */
91f92359bfSslatteng int	nfonts;		/* number of fonts device is capable of printing */
92f92359bfSslatteng int	smnt;		/* index of first special font */
93f92359bfSslatteng int	nchtab;
94f92359bfSslatteng char	*chname;
95f92359bfSslatteng short	*chtab;
96f92359bfSslatteng char	*fitab[NFONTS+1];
97f92359bfSslatteng char	*widtab[NFONTS+1];
98f92359bfSslatteng char	*codetab[NFONTS+1];	/* device codes */
99f92359bfSslatteng char	*fontdir = FONTDIR;
100f92359bfSslatteng struct {			/* table of what font */
101f92359bfSslatteng 	char *name;		/*   name is on what */
102f92359bfSslatteng 	int number;		/*   position in font tables */
103f92359bfSslatteng } fontname[NFONTS+1];
104f92359bfSslatteng 
105f92359bfSslatteng #ifdef DEBUGABLE
106f92359bfSslatteng int	dbg	= 0;
107f92359bfSslatteng #endif
108f92359bfSslatteng int	maxH;		/* farthest down we've been on the current page */
109f92359bfSslatteng int	size	= -1;	/* current point size being use */
110f92359bfSslatteng int	font	= -1;	/* current font - not using any to start with */
111f92359bfSslatteng int	hpos;		/* horizontal position we are to be at next; left = 0 */
112f92359bfSslatteng int	vpos;		/* current vertical position (down positive) */
113f92359bfSslatteng int	horig;		/* h origin of current block (just a marker) */
114f92359bfSslatteng int	vorig;		/* v origin of current block (just a marker) */
115f92359bfSslatteng int	lastw;		/* width of last character printed */
116f92359bfSslatteng 
117f92359bfSslatteng 
118f92359bfSslatteng #define DISPATCHSIZE	256		/* must be a power of two */
119f92359bfSslatteng #define CHARMASK	(DISPATCHSIZE-1)
120f92359bfSslatteng #define DSIZ		((sizeof *dispatch)*DISPATCHSIZE)
121f92359bfSslatteng #define OUTFILE 	fileno (stdout)
122f92359bfSslatteng #define	RES		200		/* resolution of the device */
123f92359bfSslatteng #define	TRAILER		(10 * RES)	/* position of trailer */
124f92359bfSslatteng 
125*1a4ecc79Sslatteng #define RASTER_LENGTH	2112			/* device line length */
126f92359bfSslatteng #define BYTES_PER_LINE	(RASTER_LENGTH/8)
127*1a4ecc79Sslatteng #define NLINES		1600			/* device page width */
128f92359bfSslatteng #define BUFFER_SIZE	(NLINES*BYTES_PER_LINE)	/* number of chars in picture */
129f92359bfSslatteng 
130f92359bfSslatteng 
131f92359bfSslatteng int	pltmode[] = { VPLOT };
132f92359bfSslatteng int	prtmode[] = { VPRINT };
133f92359bfSslatteng char	buffer[BUFFER_SIZE];	/* Big line buffers  */
134f92359bfSslatteng char	*buf0p = &buffer[0];	/* Zero origin in circular buffer  */
135f92359bfSslatteng 
136f92359bfSslatteng char	*calloc();
137f92359bfSslatteng char	*nalloc();
138f92359bfSslatteng char	*allpanic();
139f92359bfSslatteng 
140f92359bfSslatteng struct header {
141f92359bfSslatteng 	short	magic;
142f92359bfSslatteng 	unsigned short	size;
143f92359bfSslatteng 	short	maxx;
144f92359bfSslatteng 	short	maxy;
145f92359bfSslatteng 	short	xtnd;
146f92359bfSslatteng } header;
147f92359bfSslatteng 
148f92359bfSslatteng struct	dispatch{
149f92359bfSslatteng 	unsigned short	addr;
150f92359bfSslatteng 	short	nbytes;
151f92359bfSslatteng 	char	up;
152f92359bfSslatteng 	char	down;
153f92359bfSslatteng 	char	left;
154f92359bfSslatteng 	char	right;
155f92359bfSslatteng 	short	width;
156f92359bfSslatteng };
157f92359bfSslatteng 
158f92359bfSslatteng struct	fontdes {
159f92359bfSslatteng 	int	fnum;
160f92359bfSslatteng 	int	psize;
161f92359bfSslatteng 	struct	dispatch *disp;
162f92359bfSslatteng 	char	*bits;
163f92359bfSslatteng } fontdes[NFONTS] = {
164f92359bfSslatteng 	-1,
165f92359bfSslatteng 	-1
166f92359bfSslatteng };
167f92359bfSslatteng 
168f92359bfSslatteng struct dispatch *dispatch;
169f92359bfSslatteng int	cfnum = -1;
170f92359bfSslatteng int	cpsize = 10;
171f92359bfSslatteng int	cfont = 1;
172f92359bfSslatteng char	*bits;
173f92359bfSslatteng int	fontwanted = 1;		/* flag:  "has a new font been requested?" */
174f92359bfSslatteng int	nfontnum = -1;
175f92359bfSslatteng int	npsize = 10;
176f92359bfSslatteng 
177f92359bfSslatteng 
178f92359bfSslatteng 
179f92359bfSslatteng main(argc, argv)
180f92359bfSslatteng char *argv[];
181f92359bfSslatteng {
182f92359bfSslatteng 	FILE *fp;
183f92359bfSslatteng 	int done();
184f92359bfSslatteng 
185f92359bfSslatteng 	while (argc > 1 && argv[1][0] == '-') {
186f92359bfSslatteng 		switch (argv[1][1]) {
187f92359bfSslatteng 		case 'f':
188f92359bfSslatteng 		case 'F':
189f92359bfSslatteng 			fontdir = argv[2];
190f92359bfSslatteng 			argv++;
191f92359bfSslatteng 			argc--;
192f92359bfSslatteng 			break;
193f92359bfSslatteng 		case 'o':
194f92359bfSslatteng 			outlist(&argv[1][2]);
195f92359bfSslatteng 			break;
196f92359bfSslatteng #ifdef DEBUGABLE
197f92359bfSslatteng 		case 'd':
198f92359bfSslatteng 			dbg = atoi(&argv[1][2]);
199f92359bfSslatteng 			if (dbg == 0) dbg = 1;
200f92359bfSslatteng 			break;
201f92359bfSslatteng #endif
202f92359bfSslatteng 		case 's':
203f92359bfSslatteng 			spage = atoi(&argv[1][2]);
204f92359bfSslatteng 			if (spage <= 0)
205f92359bfSslatteng 				spage = 9999;
206f92359bfSslatteng 			break;
207f92359bfSslatteng 		}
208f92359bfSslatteng 		argc--;
209f92359bfSslatteng 		argv++;
210f92359bfSslatteng 	}
211f92359bfSslatteng 
212f92359bfSslatteng /* noversatec
213f92359bfSslatteng 	ioctl(OUTFILE, VSETSTATE, pltmode);
214f92359bfSslatteng noversatec */
215f92359bfSslatteng 
216f92359bfSslatteng 	if (argc <= 1)
217f92359bfSslatteng 		conv(stdin);
218f92359bfSslatteng 	else
219f92359bfSslatteng 		while (--argc > 0) {
220f92359bfSslatteng 			if (strcmp(*++argv, "-") == 0)
221f92359bfSslatteng 				fp = stdin;
222f92359bfSslatteng 			else if ((fp = fopen(*argv, "r")) == NULL)
223f92359bfSslatteng 				error(FATAL, "can't open %s", *argv);
224f92359bfSslatteng 			conv(fp);
225f92359bfSslatteng 			fclose(fp);
226f92359bfSslatteng 		}
227f92359bfSslatteng 	done();
228f92359bfSslatteng 	exit(0);
229f92359bfSslatteng }
230f92359bfSslatteng 
231f92359bfSslatteng outlist(s)	/* process list of page numbers to be printed */
232f92359bfSslatteng char *s;
233f92359bfSslatteng {
234f92359bfSslatteng 	int n1, n2, i;
235f92359bfSslatteng 
236f92359bfSslatteng 	nolist = 0;
237f92359bfSslatteng 	while (*s) {
238f92359bfSslatteng 		n1 = 0;
239f92359bfSslatteng 		if (isdigit(*s))
240f92359bfSslatteng 			do
241f92359bfSslatteng 				n1 = 10 * n1 + *s++ - '0';
242f92359bfSslatteng 			while (isdigit(*s));
243f92359bfSslatteng 		else
244f92359bfSslatteng 			n1 = -9999;
245f92359bfSslatteng 		n2 = n1;
246f92359bfSslatteng 		if (*s == '-') {
247f92359bfSslatteng 			s++;
248f92359bfSslatteng 			n2 = 0;
249f92359bfSslatteng 			if (isdigit(*s))
250f92359bfSslatteng 				do
251f92359bfSslatteng 					n2 = 10 * n2 + *s++ - '0';
252f92359bfSslatteng 				while (isdigit(*s));
253f92359bfSslatteng 			else
254f92359bfSslatteng 				n2 = 9999;
255f92359bfSslatteng 		}
256f92359bfSslatteng 		olist[nolist++] = n1;
257f92359bfSslatteng 		olist[nolist++] = n2;
258f92359bfSslatteng 		if (*s != '\0')
259f92359bfSslatteng 			s++;
260f92359bfSslatteng 	}
261f92359bfSslatteng 	olist[nolist] = 0;
262f92359bfSslatteng #ifdef DEBUGABLE
263f92359bfSslatteng 	if (dbg)
264f92359bfSslatteng 		for (i=0; i<nolist; i += 2)
265f92359bfSslatteng 			fprintf(stderr,"%3d %3d\n", olist[i], olist[i+1]);
266f92359bfSslatteng #endif
267f92359bfSslatteng }
268f92359bfSslatteng 
269f92359bfSslatteng conv(fp)
270f92359bfSslatteng register FILE *fp;
271f92359bfSslatteng {
272f92359bfSslatteng 	register int c, k;
273f92359bfSslatteng 	int m, n, n1, m1;
274f92359bfSslatteng 	char str[100], buf[300];
275f92359bfSslatteng 
276f92359bfSslatteng 	while ((c = getc(fp)) != EOF) {
277f92359bfSslatteng 		switch (c) {
278f92359bfSslatteng 		case '\n':	/* when input is text */
279f92359bfSslatteng 		case ' ':
280f92359bfSslatteng 		case 0:		/* occasional noise creeps in */
281f92359bfSslatteng 			break;
282f92359bfSslatteng 		case '{':	/* push down current environment */
283f92359bfSslatteng 			t_push();
284f92359bfSslatteng 			break;
285f92359bfSslatteng 		case '}':
286f92359bfSslatteng 			t_pop();
287f92359bfSslatteng 			break;
288f92359bfSslatteng 		case '0': case '1': case '2': case '3': case '4':
289f92359bfSslatteng 		case '5': case '6': case '7': case '8': case '9':
290f92359bfSslatteng 			/* two motion digits plus a character */
291f92359bfSslatteng 			hmot((c-'0')*10 + getc(fp)-'0');
292f92359bfSslatteng 			put1(getc(fp));
293f92359bfSslatteng 			break;
294f92359bfSslatteng 		case 'c':	/* single ascii character */
295f92359bfSslatteng 			put1(getc(fp));
296f92359bfSslatteng 			break;
297f92359bfSslatteng 		case 'C':
298f92359bfSslatteng 			fscanf(fp, "%s", str);
299f92359bfSslatteng 			put1s(str);
300f92359bfSslatteng 			break;
301f92359bfSslatteng 		case 't':	/* straight text */
302f92359bfSslatteng 			fgets(buf, sizeof(buf), fp);
303f92359bfSslatteng 			t_text(buf);
304f92359bfSslatteng 			break;
305f92359bfSslatteng 		case 'D':	/* draw function */
306f92359bfSslatteng 			fgets(buf, sizeof(buf), fp);
307f92359bfSslatteng 			switch (buf[0]) {
308f92359bfSslatteng 			case 'l':	/* draw a line */
309f92359bfSslatteng 			    sscanf(buf+1, "%d %d", &n, &m);
310f92359bfSslatteng 			    drawline(n, m);
311f92359bfSslatteng 			    break;
312f92359bfSslatteng 			case 'c':	/* circle */
313f92359bfSslatteng 			    sscanf(buf+1, "%d", &n);
314f92359bfSslatteng 			    drawcirc(n);
315f92359bfSslatteng 			    break;
316f92359bfSslatteng 			case 'e':	/* ellipse */
317f92359bfSslatteng 			    sscanf(buf+1, "%d %d", &m, &n);
318f92359bfSslatteng 			    drawellip(m, n);
319f92359bfSslatteng 			    break;
320f92359bfSslatteng 			case 'a':	/* arc */
321f92359bfSslatteng 			    sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
322f92359bfSslatteng 			    drawarc(n, m, n1, m1);
323f92359bfSslatteng 			    break;
324f92359bfSslatteng 			case '~':	/* wiggly line */
325*1a4ecc79Sslatteng 			case 'g':	/* gremlin spline */
326*1a4ecc79Sslatteng 			    drawwig(buf+1, fp, buf[0] == '~');
327*1a4ecc79Sslatteng 			    break;
328*1a4ecc79Sslatteng 			case 't':	/* line thickness */
329*1a4ecc79Sslatteng 			    sscanf(buf+1, "%d", &n);
330*1a4ecc79Sslatteng 			    drawthick(n);
331*1a4ecc79Sslatteng 			    break;
332*1a4ecc79Sslatteng 			case 's':	/* line style */
333*1a4ecc79Sslatteng 			    sscanf(buf+1, "%d", &n);
334*1a4ecc79Sslatteng 			    drawstyle(n);
335f92359bfSslatteng 			    break;
336f92359bfSslatteng 			default:
337f92359bfSslatteng 			    error(FATAL, "unknown drawing function %s\n", buf);
338f92359bfSslatteng 			    break;
339f92359bfSslatteng 			}
340f92359bfSslatteng 			break;
341f92359bfSslatteng 		case 's':
342f92359bfSslatteng 			fscanf(fp, "%d", &n);	/* ignore fractional sizes */
343f92359bfSslatteng 			setsize(t_size(n));
344f92359bfSslatteng 			break;
345f92359bfSslatteng 		case 'f':
346f92359bfSslatteng 			fscanf(fp, "%s", str);
347f92359bfSslatteng 			setfont(t_font(str));
348f92359bfSslatteng 			break;
349f92359bfSslatteng 		case 'H':	/* absolute horizontal motion */
350f92359bfSslatteng 			/* fscanf(fp, "%d", &n); */
351f92359bfSslatteng 			while ((c = getc(fp)) == ' ')
352f92359bfSslatteng 				;
353f92359bfSslatteng 			k = 0;
354f92359bfSslatteng 			do {
355f92359bfSslatteng 				k = 10 * k + c - '0';
356f92359bfSslatteng 			} while (isdigit(c = getc(fp)));
357f92359bfSslatteng 			ungetc(c, fp);
358f92359bfSslatteng 			hgoto(k);
359f92359bfSslatteng 			break;
360f92359bfSslatteng 		case 'h':	/* relative horizontal motion */
361f92359bfSslatteng 			while ((c = getc(fp)) == ' ')
362f92359bfSslatteng 				;
363f92359bfSslatteng 			k = 0;
364f92359bfSslatteng 			do {
365f92359bfSslatteng 				k = 10 * k + c - '0';
366f92359bfSslatteng 			} while (isdigit(c = getc(fp)));
367f92359bfSslatteng 			ungetc(c, fp);
368f92359bfSslatteng 			hmot(k);
369f92359bfSslatteng 			break;
370f92359bfSslatteng 		case 'w':	/* word space */
371f92359bfSslatteng 			break;
372f92359bfSslatteng 		case 'V':
373f92359bfSslatteng 			fscanf(fp, "%d", &n);
374f92359bfSslatteng 			vgoto(n);
375f92359bfSslatteng 			break;
376f92359bfSslatteng 		case 'v':
377f92359bfSslatteng 			fscanf(fp, "%d", &n);
378f92359bfSslatteng 			vmot(n);
379f92359bfSslatteng 			break;
380f92359bfSslatteng 		case 'p':	/* new page */
381f92359bfSslatteng 			fscanf(fp, "%d", &n);
382f92359bfSslatteng 			t_page(n);
383f92359bfSslatteng 			break;
384f92359bfSslatteng 		case 'n':	/* end of line */
385f92359bfSslatteng 			while (getc(fp) != '\n')
386f92359bfSslatteng 				;
387f92359bfSslatteng 			t_newline();
388f92359bfSslatteng 			break;
389f92359bfSslatteng 		case '#':	/* comment */
390f92359bfSslatteng 			while (getc(fp) != '\n')
391f92359bfSslatteng 				;
392f92359bfSslatteng 			break;
393f92359bfSslatteng 		case 'x':	/* device control */
394f92359bfSslatteng 			devcntrl(fp);
395f92359bfSslatteng 			break;
396f92359bfSslatteng 		default:
397f92359bfSslatteng 			error(!FATAL, "unknown input character %o %c\n", c, c);
398f92359bfSslatteng 			done();
399f92359bfSslatteng 		}
400f92359bfSslatteng 	}
401f92359bfSslatteng }
402f92359bfSslatteng 
403f92359bfSslatteng devcntrl(fp)	/* interpret device control functions */
404f92359bfSslatteng FILE *fp;
405f92359bfSslatteng {
406f92359bfSslatteng         char str[20], str1[50], buf[50];
407f92359bfSslatteng 	int c, n;
408f92359bfSslatteng 
409f92359bfSslatteng 	fscanf(fp, "%s", str);
410f92359bfSslatteng 	switch (str[0]) {	/* crude for now */
411f92359bfSslatteng 	case 'i':	/* initialize */
412f92359bfSslatteng 		fileinit();
413f92359bfSslatteng 		t_init();
414f92359bfSslatteng 		break;
415f92359bfSslatteng 	case 't':	/* trailer */
416f92359bfSslatteng 		t_trailer();
417f92359bfSslatteng 		break;
418f92359bfSslatteng 	case 'p':	/* pause -- can restart */
419f92359bfSslatteng 		t_reset('p');
420f92359bfSslatteng 		break;
421f92359bfSslatteng 	case 's':	/* stop */
422f92359bfSslatteng 		t_reset('s');
423f92359bfSslatteng 		break;
424f92359bfSslatteng 	case 'r':	/* resolution assumed when prepared */
425f92359bfSslatteng 		fscanf(fp, "%d", &res);
426f92359bfSslatteng 		break;
427f92359bfSslatteng 	case 'f':	/* font used */
428f92359bfSslatteng 		fscanf(fp, "%d %s", &n, str);
429f92359bfSslatteng 		fgets(buf, sizeof buf, fp);	/* in case there's a filename */
430f92359bfSslatteng 		ungetc('\n', fp);		/* fgets goes too far */
431f92359bfSslatteng 		str1[0] = 0;			/* in case nothing comes in */
432f92359bfSslatteng 		sscanf(buf, "%s", str1);
433f92359bfSslatteng 		loadfont(n, str, str1);
434f92359bfSslatteng 		break;
435f92359bfSslatteng 						/* these don't belong here... */
436f92359bfSslatteng 	case 'H':	/* char height */
437f92359bfSslatteng 		fscanf(fp, "%d", &n);
438f92359bfSslatteng 		t_charht(n);
439f92359bfSslatteng 		break;
440f92359bfSslatteng 	case 'S':	/* slant */
441f92359bfSslatteng 		fscanf(fp, "%d", &n);
442f92359bfSslatteng 		t_slant(n);
443f92359bfSslatteng 		break;
444f92359bfSslatteng 	}
445f92359bfSslatteng 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
446f92359bfSslatteng 		if (c == EOF)
447f92359bfSslatteng 			break;
448f92359bfSslatteng }
449f92359bfSslatteng 
450f92359bfSslatteng /* fileinit:	read in font and code files, etc.
451f92359bfSslatteng 		Must open table for device, read in resolution,
452f92359bfSslatteng 		size info, font info, etc. and set params
453f92359bfSslatteng */
454f92359bfSslatteng fileinit()
455f92359bfSslatteng {
456f92359bfSslatteng 	int i, fin, nw;
457f92359bfSslatteng 	char	*filebase, *p;
458f92359bfSslatteng 	char	temp[60];
459f92359bfSslatteng 
460f92359bfSslatteng 	sprintf(temp, "%s/devver/DESC.out", fontdir);
461f92359bfSslatteng 	if ((fin = open(temp, 0)) < 0)
462f92359bfSslatteng 		error(FATAL, "can't open tables for %s\n", temp);
463f92359bfSslatteng 	read(fin, &dev, sizeof(struct dev));
464f92359bfSslatteng 	nfonts = dev.nfonts;
465f92359bfSslatteng 	nsizes = dev.nsizes;
466f92359bfSslatteng 	nchtab = dev.nchtab;
467f92359bfSslatteng 	filebase = calloc(1,dev.filesize);	/* enough room for whole file */
468f92359bfSslatteng 	read(fin, filebase, dev.filesize);	/* all at once */
469f92359bfSslatteng 	pstab = (short *) filebase;
470f92359bfSslatteng 	chtab = pstab + nsizes + 1;
471f92359bfSslatteng 	chname = (char *) (chtab + dev.nchtab);
472f92359bfSslatteng 	p = chname + dev.lchname;
473f92359bfSslatteng 	for (i = 1; i <= nfonts; i++) {
474f92359bfSslatteng 		fontbase[i] = (struct font *) p;
475f92359bfSslatteng 		nw = *p & BMASK;		/* 1st thing is width count */
476f92359bfSslatteng 		if (smnt == 0 && fontbase[i]->specfont == 1)
477f92359bfSslatteng 			smnt = i;		/* first special font */
478f92359bfSslatteng 		p += sizeof(struct font);	/* that is on the beginning */
479f92359bfSslatteng 		widtab[i] = p;
480f92359bfSslatteng 		codetab[i] = p + 2 * nw;
481f92359bfSslatteng 		fitab[i] = p + 3 * nw;
482f92359bfSslatteng 		p += 3 * nw + dev.nchtab + 128 - 32;
483f92359bfSslatteng 		t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
484f92359bfSslatteng #ifdef DEBUGABLE
485f92359bfSslatteng 		if (dbg > 1) fontprint(i);
486f92359bfSslatteng #endif
487f92359bfSslatteng 	}
488f92359bfSslatteng 	fontbase[0] = (struct font *)
489f92359bfSslatteng 		calloc(1,3*255 + dev.nchtab + (128-32) + sizeof (struct font));
490f92359bfSslatteng 	widtab[0] = (char *) fontbase[0] + sizeof (struct font);
491f92359bfSslatteng 	fontbase[0]->nwfont = 255;
492f92359bfSslatteng 	close(fin);
493f92359bfSslatteng }
494f92359bfSslatteng 
495f92359bfSslatteng fontprint(i)	/* debugging print of font i (0,...) */
496f92359bfSslatteng {
497f92359bfSslatteng 	int j, n;
498f92359bfSslatteng 	char *p;
499f92359bfSslatteng 
500f92359bfSslatteng 	fprintf(stderr,"font %d:\n", i);
501f92359bfSslatteng 	p = (char *) fontbase[i];
502f92359bfSslatteng 	n = fontbase[i]->nwfont & BMASK;
503f92359bfSslatteng 	fprintf(stderr,
504f92359bfSslatteng 	    "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",p,
505f92359bfSslatteng 	    n,fontbase[i]->specfont,fontbase[i]->namefont,widtab[i],fitab[i]);
506f92359bfSslatteng 	fprintf(stderr,"widths:\n");
507f92359bfSslatteng 	for (j=0; j <= n; j++) {
508f92359bfSslatteng 		fprintf(stderr," %2d", widtab[i][j] & BMASK);
509f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
510f92359bfSslatteng 	}
511f92359bfSslatteng 	fprintf(stderr,"\ncodetab:\n");
512f92359bfSslatteng 	for (j=0; j <= n; j++) {
513f92359bfSslatteng 		fprintf(stderr," %2d", codetab[i][j] & BMASK);
514f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
515f92359bfSslatteng 	}
516f92359bfSslatteng 	fprintf(stderr,"\nfitab:\n");
517f92359bfSslatteng 	for (j=0; j <= dev.nchtab + 128-32; j++) {
518f92359bfSslatteng 		fprintf(stderr," %2d", fitab[i][j] & BMASK);
519f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
520f92359bfSslatteng 	}
521f92359bfSslatteng 	fprintf(stderr,"\n");
522f92359bfSslatteng }
523f92359bfSslatteng 
524f92359bfSslatteng loadfont(n, s, s1)	/* load font info for font s on position n (0...) */
525f92359bfSslatteng int n;
526f92359bfSslatteng char *s, *s1;
527f92359bfSslatteng {
528f92359bfSslatteng 	char temp[60];
529f92359bfSslatteng 	int fin, nw, norig;
530f92359bfSslatteng 
531f92359bfSslatteng 	if (n < 0 || n > NFONTS)
532f92359bfSslatteng 		error(FATAL, "illegal fp command %d %s", n, s);
533f92359bfSslatteng 	if (strcmp(s, fontbase[n]->namefont) == 0)
534f92359bfSslatteng 		return;
535f92359bfSslatteng 	if (s1 == NULL || s1[0] == '\0')
536f92359bfSslatteng 		sprintf(temp, "%s/devver/%s.out", fontdir, s);
537f92359bfSslatteng 	else
538f92359bfSslatteng 		sprintf(temp, "%s/%s.out", s1, s);
539f92359bfSslatteng 	if ((fin = open(temp, 0)) < 0)
540f92359bfSslatteng 		error(FATAL, "can't open font table %s", temp);
541f92359bfSslatteng 	norig = fontbase[n]->nwfont & BMASK;
542f92359bfSslatteng 	read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font));
543f92359bfSslatteng 	if ((fontbase[n]->nwfont & BMASK) > norig)
544f92359bfSslatteng 		error(FATAL, "Font %s too big for position %d\n", s, n);
545f92359bfSslatteng 	close(fin);
546f92359bfSslatteng 	nw = fontbase[n]->nwfont & BMASK;
547f92359bfSslatteng 	widtab[n] = (char *) fontbase[n] + sizeof(struct font);
548f92359bfSslatteng 	codetab[n] = (char *) widtab[n] + 2 * nw;
549f92359bfSslatteng 	fitab[n] = (char *) widtab[n] + 3 * nw;
550f92359bfSslatteng 	t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
551f92359bfSslatteng 	fontbase[n]->nwfont = norig;	/* to later use full original size */
552f92359bfSslatteng #ifdef DEBUGABLE
553f92359bfSslatteng 	if (dbg > 1) fontprint(n);
554f92359bfSslatteng #endif
555f92359bfSslatteng }
556f92359bfSslatteng 
557f92359bfSslatteng done()
558f92359bfSslatteng {
559f92359bfSslatteng 	t_reset('s');
560f92359bfSslatteng 	exit(0);
561f92359bfSslatteng }
562f92359bfSslatteng /*VARARGS1*/
563f92359bfSslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) {
564f92359bfSslatteng 	fprintf(stderr, "dver: ");
565f92359bfSslatteng 	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
566f92359bfSslatteng 	fprintf(stderr, "\n");
567f92359bfSslatteng 	if (f)
568f92359bfSslatteng 		done();
569f92359bfSslatteng }
570f92359bfSslatteng 
571f92359bfSslatteng 
572f92359bfSslatteng /*******************************************************************************
573f92359bfSslatteng  * Routine:
574f92359bfSslatteng  * Results:
575f92359bfSslatteng  * Side Efct:
576f92359bfSslatteng  ******************************************************************************/
577f92359bfSslatteng 
578f92359bfSslatteng t_init()	/* initialize device */
579f92359bfSslatteng {
580f92359bfSslatteng 	int i;
581f92359bfSslatteng 
582f92359bfSslatteng 	hpos = vpos = 0;
583f92359bfSslatteng 
584f92359bfSslatteng 	setsize(t_size(10));	/* start somewhere */
585f92359bfSslatteng 	setfont(1);
586f92359bfSslatteng }
587f92359bfSslatteng 
588f92359bfSslatteng 
589f92359bfSslatteng struct state {
590f92359bfSslatteng 	int	ssize;
591f92359bfSslatteng 	int	sfont;
592f92359bfSslatteng 	int	shpos;
593f92359bfSslatteng 	int	svpos;
594f92359bfSslatteng 	int	shorig;
595f92359bfSslatteng 	int	svorig;
596f92359bfSslatteng };
597f92359bfSslatteng struct	state	state[MAXSTATE];
598f92359bfSslatteng struct	state	*statep = state;
599f92359bfSslatteng 
600f92359bfSslatteng t_push()	/* begin a new block */
601f92359bfSslatteng {
602f92359bfSslatteng 	statep->ssize = size;
603f92359bfSslatteng 	statep->sfont = font;
604f92359bfSslatteng 	statep->shorig = horig;
605f92359bfSslatteng 	statep->svorig = vorig;
606f92359bfSslatteng 	statep->shpos = hpos;
607f92359bfSslatteng 	statep->svpos = vpos;
608f92359bfSslatteng 	horig = hpos;
609f92359bfSslatteng 	vorig = vpos;
610f92359bfSslatteng 	hpos = vpos = 0;
611f92359bfSslatteng 	if (statep++ >= state+MAXSTATE)
612f92359bfSslatteng 		error(FATAL, "{ nested too deep");
613f92359bfSslatteng 	hpos = vpos = 0;
614f92359bfSslatteng }
615f92359bfSslatteng 
616f92359bfSslatteng t_pop()	/* pop to previous state */
617f92359bfSslatteng {
618f92359bfSslatteng 	if (--statep < state)
619f92359bfSslatteng 		error(FATAL, "extra }");
620f92359bfSslatteng 	size = statep->ssize;
621f92359bfSslatteng 	font = statep->sfont;
622f92359bfSslatteng 	hpos = statep->shpos;
623f92359bfSslatteng 	vpos = statep->svpos;
624f92359bfSslatteng 	horig = statep->shorig;
625f92359bfSslatteng 	vorig = statep->svorig;
626f92359bfSslatteng }
627f92359bfSslatteng 
628f92359bfSslatteng t_page(n)	/* do whatever new page functions */
629f92359bfSslatteng {
630f92359bfSslatteng 	int i;
631f92359bfSslatteng 
632f92359bfSslatteng 
633f92359bfSslatteng 	if (output) {
634f92359bfSslatteng 		if (++scount >= spage) {
635f92359bfSslatteng 			t_reset('p');
636f92359bfSslatteng 			scount = 0;
637f92359bfSslatteng 		}
638f92359bfSslatteng 		slop_lines(maxH);
639f92359bfSslatteng /* noversatec
640f92359bfSslatteng 		ioctl(OUTFILE, VSETSTATE, prtmode);
641f92359bfSslatteng 		if (write(OUTFILE, "\f", 2) != 2)
642f92359bfSslatteng 			exit(RESTART);
643f92359bfSslatteng 		ioctl(OUTFILE, VSETSTATE, pltmode);
644f92359bfSslatteng noversatec */
645f92359bfSslatteng 		size = BYTES_PER_LINE * maxH;
646f92359bfSslatteng 		vclear(buf0p, size);
647f92359bfSslatteng 		buf0p = buffer;
648f92359bfSslatteng 	}
649f92359bfSslatteng 
650f92359bfSslatteng 	maxH = 0;
651f92359bfSslatteng 
652f92359bfSslatteng 	vpos = 0;
653f92359bfSslatteng 	output = 1;
654f92359bfSslatteng 	if (nolist == 0)
655f92359bfSslatteng 		return;	/* no -o specified */
656f92359bfSslatteng 	output = 0;
657f92359bfSslatteng 	for (i = 0; i < nolist; i += 2)
658f92359bfSslatteng 		if (n >= olist[i] && n <= olist[i+1]) {
659f92359bfSslatteng 			output = 1;
660f92359bfSslatteng 			break;
661f92359bfSslatteng 		}
662f92359bfSslatteng }
663f92359bfSslatteng 
664f92359bfSslatteng t_newline()	/* do whatever for the end of a line */
665f92359bfSslatteng {
666f92359bfSslatteng 	hpos = 0;	/* because we're now back at the left margin */
667f92359bfSslatteng }
668f92359bfSslatteng 
669f92359bfSslatteng t_size(n)	/* convert integer to internal size number*/
670f92359bfSslatteng int n;
671f92359bfSslatteng {
672f92359bfSslatteng 	int i;
673f92359bfSslatteng 
674f92359bfSslatteng 	if (n <= pstab[0])
675f92359bfSslatteng 		return(1);
676f92359bfSslatteng 	else if (n >= pstab[nsizes-1])
677f92359bfSslatteng 		return(nsizes);
678f92359bfSslatteng 	for (i = 0; n > pstab[i]; i++)
679f92359bfSslatteng 		;
680f92359bfSslatteng 	return(i+1);
681f92359bfSslatteng }
682f92359bfSslatteng 
683f92359bfSslatteng t_charht(n)	/* set character height to n */
684f92359bfSslatteng int n;
685f92359bfSslatteng {
686f92359bfSslatteng #ifdef DEBUGABLE
687f92359bfSslatteng 	if (dbg)fprintf(stderr,"can't set height on versatec yet\n");
688f92359bfSslatteng #endif
689f92359bfSslatteng }
690f92359bfSslatteng 
691f92359bfSslatteng t_slant(n)	/* set slant to n */
692f92359bfSslatteng int n;
693f92359bfSslatteng {
694f92359bfSslatteng #ifdef DEBUGABLE
695f92359bfSslatteng 	if (dbg)fprintf(stderr,"can't set slant on versatec yet\n");
696f92359bfSslatteng #endif
697f92359bfSslatteng }
698f92359bfSslatteng 
699f92359bfSslatteng t_font(s)	/* convert string to internal font number */
700f92359bfSslatteng char *s;
701f92359bfSslatteng {
702f92359bfSslatteng 	int n;
703f92359bfSslatteng 
704f92359bfSslatteng 	n = atoi(s);
705f92359bfSslatteng 	if (n < 0 || n > nfonts)
706f92359bfSslatteng 		n = 1;
707f92359bfSslatteng 	return(n);
708f92359bfSslatteng }
709f92359bfSslatteng 
710f92359bfSslatteng t_text(s)	/* print string s as text */
711f92359bfSslatteng char *s;
712f92359bfSslatteng {
713f92359bfSslatteng 	int c;
714f92359bfSslatteng 	char str[100];
715f92359bfSslatteng 
716f92359bfSslatteng 	if (!output)
717f92359bfSslatteng 		return;
718f92359bfSslatteng 	while (c = *s++) {
719f92359bfSslatteng 		if (c == '\\') {
720f92359bfSslatteng 			switch (c = *s++) {
721f92359bfSslatteng 			case '\\':
722f92359bfSslatteng 			case 'e':
723f92359bfSslatteng 				put1('\\');
724f92359bfSslatteng 				break;
725f92359bfSslatteng 			case '(':
726f92359bfSslatteng 				str[0] = *s++;
727f92359bfSslatteng 				str[1] = *s++;
728f92359bfSslatteng 				str[2] = '\0';
729f92359bfSslatteng 				put1s(str);
730f92359bfSslatteng 				break;
731f92359bfSslatteng 			}
732f92359bfSslatteng 		} else {
733f92359bfSslatteng 			put1(c);
734f92359bfSslatteng 		}
735f92359bfSslatteng 		hmot(lastw);
736f92359bfSslatteng #ifdef DEBUGABLE
737f92359bfSslatteng 		if (dbg) fprintf(stderr,"width = %d\n", lastw);
738f92359bfSslatteng #endif
739f92359bfSslatteng 	}
740f92359bfSslatteng }
741f92359bfSslatteng 
742f92359bfSslatteng t_reset(c)
743f92359bfSslatteng {
744f92359bfSslatteng 
745f92359bfSslatteng 
746f92359bfSslatteng 	output = 1;
747f92359bfSslatteng 	switch(c){
748f92359bfSslatteng 	case 'p':
749f92359bfSslatteng 		slop_lines(maxH);
750f92359bfSslatteng 		maxH = 0;
751f92359bfSslatteng 		buf0p = buffer;
752f92359bfSslatteng 		break;
753f92359bfSslatteng 	case 's':
754f92359bfSslatteng 		slop_lines(maxH);
755f92359bfSslatteng 		t_done();
756f92359bfSslatteng 		break; /* no Return */
757f92359bfSslatteng 	}
758f92359bfSslatteng }
759f92359bfSslatteng 
760f92359bfSslatteng t_done()	/* clean up and get ready to die */
761f92359bfSslatteng {
762f92359bfSslatteng /* noversatec
763f92359bfSslatteng 	ioctl(OUTFILE, VSETSTATE, prtmode);
764f92359bfSslatteng 	if (write(OUTFILE, "\f", 2) != 2)
765f92359bfSslatteng 		exit(RESTART);
766f92359bfSslatteng noversatec */
767f92359bfSslatteng }
768f92359bfSslatteng 
769f92359bfSslatteng t_trailer()
770f92359bfSslatteng {
771f92359bfSslatteng 	vpos = 0;
772f92359bfSslatteng 	vgoto(TRAILER);
773f92359bfSslatteng 	vpos = 0;
774f92359bfSslatteng }
775f92359bfSslatteng 
776f92359bfSslatteng vgoto(n)
777f92359bfSslatteng {
778f92359bfSslatteng 			/* check to see if n would move use past buf0p */
779f92359bfSslatteng     if (n < 0) {
780f92359bfSslatteng 	fprintf (stderr, "ERROR vgoto past the beginning");
781f92359bfSslatteng 	done();
782f92359bfSslatteng     }
783f92359bfSslatteng 					/* check for end of page */
784f92359bfSslatteng     if (n > RES * 11) n -= RES * 11;	/* wrap around on to the top */
785f92359bfSslatteng     vpos = n;
786f92359bfSslatteng }
787f92359bfSslatteng 
788f92359bfSslatteng put1s(s)	/* s is a funny char name */
789f92359bfSslatteng char *s;
790f92359bfSslatteng {
791f92359bfSslatteng 	int i;
792f92359bfSslatteng 
793f92359bfSslatteng 	if (!output)
794f92359bfSslatteng 		return;
795f92359bfSslatteng #ifdef DEBUGABLE
796f92359bfSslatteng 	if (dbg) fprintf(stderr,"%s ", s);
797f92359bfSslatteng #endif
798f92359bfSslatteng 	for (i = 0; i < nchtab; i++)
799f92359bfSslatteng 		if (strcmp(&chname[chtab[i]], s) == 0)
800f92359bfSslatteng 			break;
801f92359bfSslatteng 	if (i < nchtab)
802f92359bfSslatteng 		put1(i + 128);
803f92359bfSslatteng }
804f92359bfSslatteng 
805f92359bfSslatteng put1(c)	/* output char c */
806f92359bfSslatteng int c;
807f92359bfSslatteng {
808f92359bfSslatteng 	char *pw;
809f92359bfSslatteng 	register char *p;
810f92359bfSslatteng 	register int i, k;
811f92359bfSslatteng 	int j, ofont, code;
812f92359bfSslatteng 
813f92359bfSslatteng 	if (!output)
814f92359bfSslatteng 		return;
815f92359bfSslatteng 	c -= 32;
816f92359bfSslatteng 	if (c <= 0) {
817f92359bfSslatteng #ifdef DEBUGABLE
818f92359bfSslatteng 		if (dbg) fprintf(stderr,"non-exist 0%o\n", c + 32);
819f92359bfSslatteng #endif
820f92359bfSslatteng  		lastw = (widtab[font][0] * pstab[size-1] + dev.unitwidth/2)
821f92359bfSslatteng 								/ dev.unitwidth;
822f92359bfSslatteng 		return;
823f92359bfSslatteng 	}
824f92359bfSslatteng 	k = ofont = font;
825f92359bfSslatteng 	i = fitab[font][c] & BMASK;
826f92359bfSslatteng 	if (i != 0) {			/* it's on this font */
827f92359bfSslatteng 		p = codetab[font];	/* get the printing value of ch */
828f92359bfSslatteng 		pw = widtab[font];	/* get the width */
829f92359bfSslatteng 	} else if (smnt > 0) {		/* on special (we hope) */
830f92359bfSslatteng 		for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)){
831f92359bfSslatteng 			if (fitab[k] == 0)
832f92359bfSslatteng 				continue;
833f92359bfSslatteng 			if ((i = fitab[k][c] & BMASK) != 0) {
834f92359bfSslatteng 				p = codetab[k];
835f92359bfSslatteng 				pw = widtab[k];
836f92359bfSslatteng 				setfont(k);
837f92359bfSslatteng 				break;
838f92359bfSslatteng 			}
839f92359bfSslatteng 		}
840f92359bfSslatteng 	}
841f92359bfSslatteng 	if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
842f92359bfSslatteng #ifdef DEBUGABLE
843f92359bfSslatteng 		if (dbg) fprintf(stderr,"not found 0%o\n", c+32);
844f92359bfSslatteng #endif
845f92359bfSslatteng 		return;
846f92359bfSslatteng 	}
847f92359bfSslatteng #ifdef DEBUGABLE
848f92359bfSslatteng 	if (dbg) {
849f92359bfSslatteng 		if (isprint(c+32))
850f92359bfSslatteng 			fprintf(stderr,"%c %d\n", c+32, code);
851f92359bfSslatteng 		else
852f92359bfSslatteng 			fprintf(stderr,"%03o %d\n", c+32, code);
853f92359bfSslatteng 	}
854f92359bfSslatteng #endif
855f92359bfSslatteng 	outc(code);	/* character is < 254 */
856f92359bfSslatteng 	if (font != ofont)
857f92359bfSslatteng 		setfont(ofont);
858f92359bfSslatteng 	lastw = ((pw[i]&077) * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth;
859f92359bfSslatteng }
860f92359bfSslatteng 
861f92359bfSslatteng 
862f92359bfSslatteng 
863f92359bfSslatteng setsize(n)	/* set point size to n (internal) */
864f92359bfSslatteng int n;
865f92359bfSslatteng {
866f92359bfSslatteng 
867f92359bfSslatteng 	if (n == size)
868f92359bfSslatteng 		return;	/* already there */
869f92359bfSslatteng 	if (vloadfont(font,pstab[n-1]) != -1)
870f92359bfSslatteng 		size = n;
871f92359bfSslatteng }
872f92359bfSslatteng 
873f92359bfSslatteng t_fp(n, s, si)	/* font position n now contains font s, intname si */
874f92359bfSslatteng int n;
875f92359bfSslatteng char *s, *si;
876f92359bfSslatteng {
877f92359bfSslatteng 	register	i;
878f92359bfSslatteng 
879f92359bfSslatteng 	fontname[n].name = s;
880f92359bfSslatteng 	fontname[n].number = atoi(si);
881f92359bfSslatteng 	for(i = 0;i < NFONTS;i++)/* free the bits of that font */
882f92359bfSslatteng 		if (fontdes[i].fnum == n){
883f92359bfSslatteng 			nfree(fontdes[i].bits);
884f92359bfSslatteng 			fontdes[i].bits = 0;
885f92359bfSslatteng 			fontdes[i].fnum = -1;
886f92359bfSslatteng 		}
887f92359bfSslatteng }
888f92359bfSslatteng 
889f92359bfSslatteng setfont(n)	/* set font to n */
890f92359bfSslatteng int n;
891f92359bfSslatteng {
892f92359bfSslatteng 	if (n < 0 || n > NFONTS)
893f92359bfSslatteng 		error(FATAL, "illegal font %d\n", n);
894f92359bfSslatteng 	if (vloadfont(n,pstab[size - 1]) != -1)
895f92359bfSslatteng 		font = n;
896f92359bfSslatteng }
897f92359bfSslatteng 
898f92359bfSslatteng vloadfont(fnum, fsize)
899f92359bfSslatteng register int fnum;
900f92359bfSslatteng register int fsize;
901f92359bfSslatteng {
902f92359bfSslatteng 	register int i;
903f92359bfSslatteng 
904f92359bfSslatteng 	fontwanted = 0;
905f92359bfSslatteng 	if (fnum == cfnum && fsize == cpsize)
906f92359bfSslatteng 		return(0);
907f92359bfSslatteng 	for (i = 0; i < NFONTS; i++) {
908f92359bfSslatteng 		if (fontdes[i].fnum == fnum && fontdes[i].psize == fsize) {
909f92359bfSslatteng 			cfnum = fontdes[i].fnum;
910f92359bfSslatteng 			cpsize = fontdes[i].psize;
911f92359bfSslatteng 			dispatch = &fontdes[i].disp[0];
912f92359bfSslatteng 			bits = fontdes[i].bits;
913f92359bfSslatteng 			cfont = i;
914f92359bfSslatteng 			return (0);
915f92359bfSslatteng 		}
916f92359bfSslatteng 	}
917f92359bfSslatteng 		/* this is a new font */
918f92359bfSslatteng 	if (fnum < 0 || fnum > NFONTS || fontname[fnum].name == 0) {
919f92359bfSslatteng 	    fprintf(stderr, "Internal error: illegal font %d name %s size\n",
920f92359bfSslatteng 			    fontname[fnum].name,fnum,fsize);
921f92359bfSslatteng 	    return(-1);
922f92359bfSslatteng 	}
923f92359bfSslatteng 		/* Need to verify the existance of that font/size here*/
924f92359bfSslatteng 	nfontnum = fnum;
925f92359bfSslatteng 	npsize = fsize;
926f92359bfSslatteng 	fontwanted++;
927f92359bfSslatteng 	return (0);
928f92359bfSslatteng }
929f92359bfSslatteng 
930f92359bfSslatteng 
931f92359bfSslatteng getfont()
932f92359bfSslatteng {
933f92359bfSslatteng 	register int fnum, fsize, fontd;
934f92359bfSslatteng 	int d;
935f92359bfSslatteng 	char cbuf[BUFSIZ];
936f92359bfSslatteng 
937f92359bfSslatteng 	fnum = nfontnum;
938f92359bfSslatteng 	fsize = npsize;
939*1a4ecc79Sslatteng 	sprintf(cbuf, "/usr/lib/vfont/%s.%dr",fontname[fnum].name, fsize);
940f92359bfSslatteng 	fontd = open(cbuf, OPENREAD);
941f92359bfSslatteng 	if (fontd == -1) {
942f92359bfSslatteng 		perror(cbuf);
943f92359bfSslatteng 		error(0,"fnum = %d size = %d name = %s\n",
944f92359bfSslatteng 			fnum,fsize,fontname[fnum]);
945f92359bfSslatteng 		fontwanted = 0;
946f92359bfSslatteng 		return (-1);
947f92359bfSslatteng 	}
948f92359bfSslatteng 	if (read(fontd, &header, sizeof  (header)) != sizeof (header)
949f92359bfSslatteng 						|| header.magic != 0436)
950f92359bfSslatteng 		fprintf(stderr, "%s: Bad font file", cbuf);
951f92359bfSslatteng 	else {
952f92359bfSslatteng 		cfont = relfont();
953f92359bfSslatteng 		if ((bits=nalloc(header.size+DSIZ+1,1))== NULL)
954f92359bfSslatteng 			if ((bits=allpanic(header.size+DSIZ+1))== NULL) {
955f92359bfSslatteng 				fprintf(stderr,"%s: ran out of memory\n", cbuf);
956f92359bfSslatteng 				exit(ABORT);
957f92359bfSslatteng 			}
958f92359bfSslatteng 
959f92359bfSslatteng 			/*
960f92359bfSslatteng 			 * have allocated one chunk of mem for font, dispatch.
961f92359bfSslatteng 			 * get the dispatch addr, align to word boundary.
962f92359bfSslatteng 			 */
963f92359bfSslatteng 
964f92359bfSslatteng 		d = (int) bits+header.size;
965f92359bfSslatteng 		d += 1;
966f92359bfSslatteng 		d &= ~1;
967f92359bfSslatteng 		if (read (fontd, d, DSIZ) != DSIZ
968f92359bfSslatteng 			    || read (fontd, bits, header.size) != header.size)
969f92359bfSslatteng 			fprintf(stderr, "bad font header");
970f92359bfSslatteng 		else {
971f92359bfSslatteng 			close(fontd);
972f92359bfSslatteng 			cfnum = fontdes[cfont].fnum = fnum;
973f92359bfSslatteng 			cpsize = fontdes[cfont].psize = fsize;
974f92359bfSslatteng 			fontdes [cfont].bits = bits;
975f92359bfSslatteng 			fontdes [cfont].disp = (struct dispatch *) d;
976f92359bfSslatteng 			dispatch = &fontdes[cfont].disp[0];
977f92359bfSslatteng 			fontwanted = 0;
978f92359bfSslatteng 			return (0);
979f92359bfSslatteng 		}
980f92359bfSslatteng 	}
981f92359bfSslatteng 	close(fontd);
982f92359bfSslatteng 	fontwanted = 0;
983f92359bfSslatteng 	return(-1);
984f92359bfSslatteng }
985f92359bfSslatteng 
986f92359bfSslatteng /*
987f92359bfSslatteng  * "release" a font position - find an empty one, if possible
988f92359bfSslatteng  */
989f92359bfSslatteng 
990f92359bfSslatteng relfont()
991f92359bfSslatteng {
992f92359bfSslatteng     register int newfont;
993f92359bfSslatteng 
994f92359bfSslatteng     for (newfont = 0; newfont < NFONTS; newfont++)
995f92359bfSslatteng 	if (fontdes [newfont].bits == (char *) -1  ||  !fontdes [newfont].bits)
996f92359bfSslatteng 	    break;
997f92359bfSslatteng     if (fontdes [newfont].bits != (char *) -1  &&  fontdes [newfont].bits) {
998f92359bfSslatteng 	nfree (fontdes [newfont].bits);
999f92359bfSslatteng 	fontdes [newfont].bits = (char *)0;
1000f92359bfSslatteng #ifdef DEBUGABLE
1001f92359bfSslatteng 	if (dbg) fprintf (stderr, "freeing position %d\n", newfont);
1002f92359bfSslatteng     } else {
1003f92359bfSslatteng 	if (dbg)
1004f92359bfSslatteng 	    fprintf (stderr, "taking, not freeing, position %d\n", newfont);
1005f92359bfSslatteng #endif
1006f92359bfSslatteng     }
1007f92359bfSslatteng     fontdes[newfont].bits = 0;
1008f92359bfSslatteng     return (newfont);
1009f92359bfSslatteng }
1010f92359bfSslatteng 
1011f92359bfSslatteng char *allpanic (nbytes)
1012f92359bfSslatteng int nbytes;
1013f92359bfSslatteng {
1014f92359bfSslatteng 	register int i;
1015f92359bfSslatteng 
1016f92359bfSslatteng 	for (i = 0; i <= NFONTS; i++)
1017f92359bfSslatteng 	    if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
1018f92359bfSslatteng 		nfree(fontdes[i].bits);
1019f92359bfSslatteng 	for (i = 0; i <= NFONTS; i++) {
1020f92359bfSslatteng 		fontdes[i].fnum = fontdes[i].psize = -1;
1021f92359bfSslatteng 		fontdes[i].bits = 0;
1022f92359bfSslatteng 		cfnum = cpsize = -1;
1023f92359bfSslatteng 	}
1024f92359bfSslatteng 	return(nalloc(nbytes,1));
1025f92359bfSslatteng }
1026f92359bfSslatteng 
1027f92359bfSslatteng int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
1028f92359bfSslatteng 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
1029f92359bfSslatteng int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
1030f92359bfSslatteng 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
1031f92359bfSslatteng int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
1032f92359bfSslatteng 
1033f92359bfSslatteng outc(code)
1034f92359bfSslatteng int code;		/* character to print */
1035f92359bfSslatteng {
1036f92359bfSslatteng     register struct dispatch *dis; /* ptr to character font record */
1037f92359bfSslatteng     register char *addr;	/* addr of font data */
1038f92359bfSslatteng     int llen;			/* length of each font line */
1039f92359bfSslatteng     int nlines;			/* number of font lines */
1040f92359bfSslatteng     register char *scanp;	/* ptr to output buffer */
1041f92359bfSslatteng     int scanp_inc;		/* increment to start of next buffer */
1042f92359bfSslatteng     int offset;			/* bit offset to start of font data */
1043f92359bfSslatteng     int i;			/* loop counter */
1044f92359bfSslatteng     register int count;		/* font data ptr */
1045f92359bfSslatteng     register unsigned fontdata;	/* font data temporary */
1046f92359bfSslatteng     register int off8;		/* offset + 8 */
1047f92359bfSslatteng 
1048f92359bfSslatteng     if (fontwanted)
1049f92359bfSslatteng 	getfont();
1050f92359bfSslatteng     dis = dispatch + code;
1051f92359bfSslatteng     if (dis->nbytes) {
1052f92359bfSslatteng 	addr = bits + dis->addr;
1053*1a4ecc79Sslatteng 	llen = (dis->up + dis->down + 7) >> 3;
1054*1a4ecc79Sslatteng 	nlines = dis->right + dis->left;
1055*1a4ecc79Sslatteng 	if ((i = hpos + dis->right) > maxH) maxH = i;	/* remember page len */
1056*1a4ecc79Sslatteng 	scanp = buf0p + (hpos - dis->left) * BYTES_PER_LINE
1057*1a4ecc79Sslatteng 			- (1 + ((dis->down + vpos) >> 3));
1058f92359bfSslatteng 	if (scanp < &buffer[0])
1059f92359bfSslatteng 	    scanp += sizeof buffer;
1060f92359bfSslatteng 	scanp_inc = BYTES_PER_LINE - llen;
1061*1a4ecc79Sslatteng 	off8 = ((dis->down + vpos) &07);
1062*1a4ecc79Sslatteng 	offset = off8 - 8;
1063f92359bfSslatteng 	for (i = 0; i < nlines; i++) {
1064f92359bfSslatteng 	    if (scanp >= &buffer[BUFFER_SIZE])
1065f92359bfSslatteng 		scanp -= sizeof buffer;
1066f92359bfSslatteng 	    count = llen;
1067f92359bfSslatteng 	    if (scanp + count <= &buffer[BUFFER_SIZE]) {
1068f92359bfSslatteng 		do {
1069f92359bfSslatteng 		    fontdata = *(unsigned *)addr;
1070f92359bfSslatteng 		    addr += 4;
1071f92359bfSslatteng 		    if (count < 4)
1072f92359bfSslatteng 			fontdata &= ~strim[count];
1073f92359bfSslatteng 		    *(unsigned*)scanp |=(fontdata << offset) & ~M[off8];
1074f92359bfSslatteng 		    scanp++;
1075f92359bfSslatteng 		    *(unsigned*)scanp |=(fontdata << off8) & ~N[off8];
1076f92359bfSslatteng 		    scanp += 3;
1077f92359bfSslatteng 		    count -= 4;
1078f92359bfSslatteng 		} while (count > 0);
1079f92359bfSslatteng 	    }
1080f92359bfSslatteng 	    scanp += scanp_inc+count;
1081f92359bfSslatteng 	    addr += count;
1082f92359bfSslatteng 	}
1083f92359bfSslatteng 	return;
1084f92359bfSslatteng     }
1085f92359bfSslatteng     return;
1086f92359bfSslatteng }
1087f92359bfSslatteng 
1088f92359bfSslatteng slop_lines(nlines)
1089f92359bfSslatteng int nlines;
1090f92359bfSslatteng 
1091f92359bfSslatteng /* Output "nlines" lines from the buffer, and clear that section of the  */
1092f92359bfSslatteng /* buffer.	*/
1093f92359bfSslatteng 
1094f92359bfSslatteng {
1095f92359bfSslatteng 	unsigned usize;
1096f92359bfSslatteng 
1097f92359bfSslatteng 	usize = BYTES_PER_LINE * nlines;
1098f92359bfSslatteng 	writev(buf0p,usize);
1099f92359bfSslatteng 	vclear(buf0p, usize);
1100f92359bfSslatteng /* noversatec
1101f92359bfSslatteng 	ioctl(OUTFILE, VSETSTATE, pltmode);
1102f92359bfSslatteng noversatec */
1103f92359bfSslatteng }
1104f92359bfSslatteng 
1105f92359bfSslatteng writev(buf,usize)
1106f92359bfSslatteng char *buf;
1107f92359bfSslatteng unsigned usize;
1108f92359bfSslatteng {
1109f92359bfSslatteng 	register int tsize = 0;
1110f92359bfSslatteng 
1111f92359bfSslatteng 	while (usize){
1112f92359bfSslatteng 		buf += tsize;
1113f92359bfSslatteng 		tsize = usize > MAXWRIT ? MAXWRIT : usize;
1114f92359bfSslatteng #ifdef DEBUGABLE
1115f92359bfSslatteng 		if (dbg)fprintf(stderr,"buf = %d size = %d\n",buf,tsize);
1116f92359bfSslatteng #endif
1117f92359bfSslatteng 		if ((tsize = write(OUTFILE, buf, tsize)) < 0) {
1118f92359bfSslatteng 			perror("dver: write failed");
1119f92359bfSslatteng 			exit(RESTART);
1120f92359bfSslatteng 		}
1121f92359bfSslatteng 		usize -= tsize;
1122f92359bfSslatteng 	}
1123f92359bfSslatteng }
1124f92359bfSslatteng 
1125f92359bfSslatteng vclear (ptr, nbytes)
1126f92359bfSslatteng char	*ptr;
1127f92359bfSslatteng unsigned nbytes;
1128f92359bfSslatteng {
1129f92359bfSslatteng     register tsize = 0;
1130f92359bfSslatteng 
1131f92359bfSslatteng     while (nbytes){
1132f92359bfSslatteng 	if ((unsigned)(16*1024) < nbytes) {
1133f92359bfSslatteng 	    tsize = 16 * 1024;
1134f92359bfSslatteng 	} else
1135f92359bfSslatteng 	    tsize = nbytes;
1136f92359bfSslatteng 	nbytes -= tsize;
1137f92359bfSslatteng #ifdef DEBUGABLE
1138f92359bfSslatteng 	if (dbg) fprintf(stderr,"clearing ptr = %d size = %d\n",ptr,tsize);
1139f92359bfSslatteng #endif
1140f92359bfSslatteng 	clear(ptr,tsize);
1141f92359bfSslatteng 	ptr += tsize;
1142f92359bfSslatteng     }
1143f92359bfSslatteng }
1144f92359bfSslatteng 
1145f92359bfSslatteng /*ARGSUSED*/
1146f92359bfSslatteng clear(lp, nbytes)
1147f92359bfSslatteng int *lp;
1148f92359bfSslatteng int nbytes;
1149f92359bfSslatteng {
1150f92359bfSslatteng 	asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
1151f92359bfSslatteng }
1152f92359bfSslatteng 
1153f92359bfSslatteng char *
1154f92359bfSslatteng nalloc(i, j)
1155f92359bfSslatteng int i, j;
1156f92359bfSslatteng {
1157f92359bfSslatteng 	register char *cp;
1158f92359bfSslatteng 
1159f92359bfSslatteng 	cp = calloc(i, j);
1160f92359bfSslatteng #ifdef DEBUGABLE
1161f92359bfSslatteng 	if (dbg) fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp);
1162f92359bfSslatteng #endif
1163f92359bfSslatteng 	return(cp);
1164f92359bfSslatteng }
1165f92359bfSslatteng 
1166f92359bfSslatteng nfree(cp)
1167f92359bfSslatteng char *cp;
1168f92359bfSslatteng {
1169f92359bfSslatteng #ifdef DEBUGABLE
1170f92359bfSslatteng 	if (dbg) fprintf(stderr, "freeing at %x\n", cp);
1171f92359bfSslatteng #endif
1172f92359bfSslatteng 	free(cp);
1173f92359bfSslatteng }
1174f92359bfSslatteng 
1175f92359bfSslatteng 
1176f92359bfSslatteng /*
1177f92359bfSslatteng  * Points should be in the range 0 <= x < RASTER_LENGTH, 0 <= y < NLINES.
1178f92359bfSslatteng  * The origin is the top left-hand corner with increasing x towards the
1179f92359bfSslatteng  * right and increasing y going down.
1180f92359bfSslatteng  * The output array is NLINES x BYTES_PER_LINE pixels.
1181f92359bfSslatteng  */
1182f92359bfSslatteng point(x, y)
1183*1a4ecc79Sslatteng register int x;
1184*1a4ecc79Sslatteng register int y;
1185f92359bfSslatteng {
1186*1a4ecc79Sslatteng     if ((unsigned)(y=RASTER_LENGTH-y) < RASTER_LENGTH && (unsigned)x < NLINES) {
1187*1a4ecc79Sslatteng 	buffer [x * BYTES_PER_LINE + (y >> 3)] |= 1 << (7 - (y & 07));
1188f92359bfSslatteng     }
1189f92359bfSslatteng }
1190