1*1c9df754Sslatteng /*	dvar.c	1.6	83/10/06
2f92359bfSslatteng  *
3f92359bfSslatteng  * Varian driver for the new troff
4f92359bfSslatteng  *
5f92359bfSslatteng  * Authors:	BWK(BELL)
6f92359bfSslatteng  *		VCAT(berkley)
7f92359bfSslatteng  *		Richard L. Hyde, Perdue University
84da297a9Sslatteng  *		and David Slattengren, U.C. 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 
63*1c9df754Sslatteng /* #define DEBUGABLE		/* No, not debugable... */
64*1c9df754Sslatteng #define DRIVER  		/* Yes, we're driving directly */
65*1c9df754Sslatteng /* #define FULLPAGE		/* No, don't output full pages */
664da297a9Sslatteng #define	NFONTS	60		/* total number of fonts useable */
67f92359bfSslatteng #define	MAXSTATE 6		/* number of environments rememberable */
68f92359bfSslatteng #define OPENREAD 0		/* mode for openning files */
69f92359bfSslatteng #define RESTART	1		/* upon exit, return either RESTART */
70f92359bfSslatteng #define ABORT	2		/*     or ABORT */
71f92359bfSslatteng #define	FATAL	1		/* type of error */
72f92359bfSslatteng #define	BMASK	0377		/* byte grabber */
734da297a9Sslatteng #define FONTDIR	"/usr/lib/font"	/* default place to find font descriptions */
744da297a9Sslatteng #define BITDIR "/usr/lib/vfont" /* default place to look for font rasters */
75f92359bfSslatteng #define MAXWRIT 4096		/* max characters allowed to write at once */
76f92359bfSslatteng 
77ebd02298Sslatteng #define  hmot(n)	hgoto(hpos + n)
78f92359bfSslatteng #define  vmot(n)	vgoto(vpos + n)
79f92359bfSslatteng 
80f92359bfSslatteng 
81*1c9df754Sslatteng char	SccsId[]= "dvar.c	1.6	83/10/06";
82f92359bfSslatteng 
83f92359bfSslatteng int	output	= 0;	/* do we do output at all? */
84f92359bfSslatteng int	nolist	= 0;	/* output page list if > 0 */
85f92359bfSslatteng int	olist[20];	/* pairs of page numbers */
86f92359bfSslatteng int	spage	= 9999;	/* stop every spage pages */
87f92359bfSslatteng int	scount	= 0;
88f92359bfSslatteng struct	dev	dev;
89f92359bfSslatteng struct	font	*fontbase[NFONTS+1];
90f92359bfSslatteng short *	pstab;		/* point size table pointer */
91f92359bfSslatteng int	nsizes;		/* number of sizes device is capable of printing */
92f92359bfSslatteng int	nfonts;		/* number of fonts device is capable of printing */
93f92359bfSslatteng int	nchtab;
94f92359bfSslatteng char *	chname;
95f92359bfSslatteng short *	chtab;
964da297a9Sslatteng char *	fitab[NFONTS+1];	/* font inclusion table - maps ascii to ch # */
974da297a9Sslatteng char *	widtab[NFONTS+1];	/* width table for each font */
98f92359bfSslatteng char *	codetab[NFONTS+1];	/* device codes */
994da297a9Sslatteng char *	fontdir = FONTDIR;	/* place to find devxxx directories */
1004da297a9Sslatteng char *	bitdir = BITDIR;	/* place to find raster fonts and fontmap */
101*1c9df754Sslatteng char *	fontname[NFONTS+1];	/* table of what font is on what position */
1024da297a9Sslatteng struct {			/* table of what font */
1034da297a9Sslatteng 	char fname[3];		/*   name maps to what */
1044da297a9Sslatteng 	char *ffile;		/*   filename in bitdirectory */
1054da297a9Sslatteng } fontmap[NFONTS+1];
1064da297a9Sslatteng 
107f92359bfSslatteng 
108f92359bfSslatteng #ifdef DEBUGABLE
109f92359bfSslatteng int	dbg	= 0;
110f92359bfSslatteng #endif
1114da297a9Sslatteng int	size	= -1;	/* current point size (internal pstable index) */
112f92359bfSslatteng int	font	= -1;	/* current font - not using any to start with */
113f92359bfSslatteng int	hpos;		/* horizontal position we are to be at next; left = 0 */
114f92359bfSslatteng int	vpos;		/* current vertical position (down positive) */
1154da297a9Sslatteng extern	linethickness;	/* thickness (in pixels) of any drawn object */
116ebd02298Sslatteng extern	linmod;		/* line style (a bit mask - dotted, etc.) of objects */
117f92359bfSslatteng int	lastw;		/* width of last character printed */
118f92359bfSslatteng 
119f92359bfSslatteng 
120f92359bfSslatteng #define DISPATCHSIZE	256		/* must be a power of two */
121f92359bfSslatteng #define CHARMASK	(DISPATCHSIZE-1)
122f92359bfSslatteng #define DSIZ		((sizeof *dispatch)*DISPATCHSIZE)
123f92359bfSslatteng #define OUTFILE 	fileno (stdout)
1244da297a9Sslatteng #define	RES		200		/* resolution of the device (dots/in) */
125f92359bfSslatteng 
1261a4ecc79Sslatteng #define RASTER_LENGTH	2112			/* device line length */
127f92359bfSslatteng #define BYTES_PER_LINE	(RASTER_LENGTH/8)
128*1c9df754Sslatteng #ifndef FULLPAGE
129*1c9df754Sslatteng #	define NLINES	1600			/* page width, 8 inches */
130*1c9df754Sslatteng #endif
131*1c9df754Sslatteng #ifdef FULLPAGE
132ebd02298Sslatteng #	define NLINES	1700			/* page width, 8.5 inches */
133*1c9df754Sslatteng #endif
134f92359bfSslatteng #define BUFFER_SIZE	(NLINES*BYTES_PER_LINE)	/* number of chars in picture */
135f92359bfSslatteng 
136f92359bfSslatteng 
137f92359bfSslatteng int	pltmode[] = { VPLOT };
138f92359bfSslatteng int	prtmode[] = { VPRINT };
139f92359bfSslatteng char	buffer[BUFFER_SIZE];	/* Big line buffers  */
140f92359bfSslatteng char *	buf0p = &buffer[0];	/* Zero origin in circular buffer  */
141f92359bfSslatteng 
142f92359bfSslatteng char *	calloc();
143f92359bfSslatteng char *	nalloc();
144f92359bfSslatteng char *	allpanic();
1454dabf413Sslatteng char *	operand();
146f92359bfSslatteng 
147f92359bfSslatteng struct header {
148f92359bfSslatteng 	short	magic;
149f92359bfSslatteng 	unsigned short	size;
150f92359bfSslatteng 	short	maxx;
151f92359bfSslatteng 	short	maxy;
152f92359bfSslatteng 	short	xtnd;
153f92359bfSslatteng } header;
154f92359bfSslatteng 
155f92359bfSslatteng struct	dispatch{
156f92359bfSslatteng 	unsigned short	addr;
157f92359bfSslatteng 	short	nbytes;
158f92359bfSslatteng 	char	up;
159f92359bfSslatteng 	char	down;
160f92359bfSslatteng 	char	left;
161f92359bfSslatteng 	char	right;
162f92359bfSslatteng 	short	width;
163f92359bfSslatteng };
164f92359bfSslatteng 
165f92359bfSslatteng struct	fontdes {
166f92359bfSslatteng 	int	fnum;
167f92359bfSslatteng 	int	psize;
168f92359bfSslatteng 	struct	dispatch *disp;
169f92359bfSslatteng 	char	*bits;
170f92359bfSslatteng } fontdes[NFONTS] = {
171f92359bfSslatteng 	-1,
172f92359bfSslatteng 	-1
173f92359bfSslatteng };
174f92359bfSslatteng 
175f92359bfSslatteng struct dispatch *dispatch;
176f92359bfSslatteng int	cfnum = -1;
177f92359bfSslatteng int	cpsize = 10;
178f92359bfSslatteng int	cfont = 1;
179f92359bfSslatteng char	*bits;
180f92359bfSslatteng int	fontwanted = 1;		/* flag:  "has a new font been requested?" */
181f92359bfSslatteng int	nfontnum = -1;
182f92359bfSslatteng int	npsize = 10;
183f92359bfSslatteng 
184f92359bfSslatteng 
185f92359bfSslatteng 
186f92359bfSslatteng main(argc, argv)
187f92359bfSslatteng char *argv[];
188f92359bfSslatteng {
189f92359bfSslatteng 	FILE *fp;
190f92359bfSslatteng 
1914dabf413Sslatteng 	while (--argc > 0 && **++argv == '-') {
1924dabf413Sslatteng 		switch ((*argv)[1]) {
193f92359bfSslatteng 		case 'F':
194*1c9df754Sslatteng 			bitdir = operand(&argc, &argv);
1954da297a9Sslatteng 			break;
1964da297a9Sslatteng 		case 'f':
197*1c9df754Sslatteng 			fontdir = operand(&argc, &argv);
198f92359bfSslatteng 			break;
199f92359bfSslatteng 		case 'o':
2004dabf413Sslatteng 			outlist(operand(&argc, &argv));
201f92359bfSslatteng 			break;
202f92359bfSslatteng #ifdef DEBUGABLE
203f92359bfSslatteng 		case 'd':
2044dabf413Sslatteng 			dbg = atoi(operand(&argc, &argv));
205f92359bfSslatteng 			if (dbg == 0) dbg = 1;
206f92359bfSslatteng 			break;
207f92359bfSslatteng #endif
208f92359bfSslatteng 		case 's':
2094dabf413Sslatteng 			spage = atoi(operand(&argc, &argv));
210f92359bfSslatteng 			if (spage <= 0)
211f92359bfSslatteng 				spage = 9999;
212f92359bfSslatteng 			break;
213f92359bfSslatteng 		}
214f92359bfSslatteng 	}
215f92359bfSslatteng 
216*1c9df754Sslatteng #ifdef DRIVER
217f92359bfSslatteng 	ioctl(OUTFILE, VSETSTATE, pltmode);
218*1c9df754Sslatteng #endif
219f92359bfSslatteng 
2204dabf413Sslatteng 	if (argc < 1)
221f92359bfSslatteng 		conv(stdin);
222f92359bfSslatteng 	else
2234dabf413Sslatteng 		while (argc--) {
2244dabf413Sslatteng 			if (strcmp(*argv, "-") == 0)
225f92359bfSslatteng 				fp = stdin;
226f92359bfSslatteng 			else if ((fp = fopen(*argv, "r")) == NULL)
227f92359bfSslatteng 				error(FATAL, "can't open %s", *argv);
228f92359bfSslatteng 			conv(fp);
229f92359bfSslatteng 			fclose(fp);
2304dabf413Sslatteng 			argv++;
231f92359bfSslatteng 		}
232f92359bfSslatteng 	exit(0);
233f92359bfSslatteng }
234f92359bfSslatteng 
2354dabf413Sslatteng 
2364dabf413Sslatteng /*----------------------------------------------------------------------------*
2374dabf413Sslatteng  | Routine:	char  * operand (& argc,  & argv)
2384dabf413Sslatteng  |
2394dabf413Sslatteng  | Results:	returns address of the operand given with a command-line
2404dabf413Sslatteng  |		option.  It uses either "-Xoperand" or "-X operand", whichever
2414dabf413Sslatteng  |		is present.  The program is terminated if no option is present.
2424dabf413Sslatteng  |
2434dabf413Sslatteng  | Side Efct:	argc and argv are updated as necessary.
2444dabf413Sslatteng  *----------------------------------------------------------------------------*/
2454dabf413Sslatteng 
2464dabf413Sslatteng char *operand(argcp, argvp)
2474dabf413Sslatteng int * argcp;
2484dabf413Sslatteng char ***argvp;
2494dabf413Sslatteng {
2504dabf413Sslatteng 	if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
2514dabf413Sslatteng 	if ((--*argcp) <= 0)			/* no operand */
2524dabf413Sslatteng 	    error (FATAL, "command-line option operand missing.\n");
2534dabf413Sslatteng 	return(*(++(*argvp)));			/* operand next word */
2544dabf413Sslatteng }
2554dabf413Sslatteng 
2564dabf413Sslatteng 
257f92359bfSslatteng outlist(s)	/* process list of page numbers to be printed */
258f92359bfSslatteng char *s;
259f92359bfSslatteng {
260f92359bfSslatteng 	int n1, n2, i;
261f92359bfSslatteng 
262f92359bfSslatteng 	nolist = 0;
263f92359bfSslatteng 	while (*s) {
264f92359bfSslatteng 		n1 = 0;
265f92359bfSslatteng 		if (isdigit(*s))
266f92359bfSslatteng 			do
267f92359bfSslatteng 				n1 = 10 * n1 + *s++ - '0';
268f92359bfSslatteng 			while (isdigit(*s));
269f92359bfSslatteng 		else
270f92359bfSslatteng 			n1 = -9999;
271f92359bfSslatteng 		n2 = n1;
272f92359bfSslatteng 		if (*s == '-') {
273f92359bfSslatteng 			s++;
274f92359bfSslatteng 			n2 = 0;
275f92359bfSslatteng 			if (isdigit(*s))
276f92359bfSslatteng 				do
277f92359bfSslatteng 					n2 = 10 * n2 + *s++ - '0';
278f92359bfSslatteng 				while (isdigit(*s));
279f92359bfSslatteng 			else
280f92359bfSslatteng 				n2 = 9999;
281f92359bfSslatteng 		}
282f92359bfSslatteng 		olist[nolist++] = n1;
283f92359bfSslatteng 		olist[nolist++] = n2;
284f92359bfSslatteng 		if (*s != '\0')
285f92359bfSslatteng 			s++;
286f92359bfSslatteng 	}
287f92359bfSslatteng 	olist[nolist] = 0;
288f92359bfSslatteng #ifdef DEBUGABLE
289f92359bfSslatteng 	if (dbg)
290f92359bfSslatteng 		for (i=0; i<nolist; i += 2)
291f92359bfSslatteng 			fprintf(stderr,"%3d %3d\n", olist[i], olist[i+1]);
292f92359bfSslatteng #endif
293f92359bfSslatteng }
294f92359bfSslatteng 
295f92359bfSslatteng conv(fp)
296f92359bfSslatteng register FILE *fp;
297f92359bfSslatteng {
298f92359bfSslatteng 	register int c, k;
299f92359bfSslatteng 	int m, n, n1, m1;
300f92359bfSslatteng 	char str[100], buf[300];
301f92359bfSslatteng 
302f92359bfSslatteng 	while ((c = getc(fp)) != EOF) {
303f92359bfSslatteng 		switch (c) {
304f92359bfSslatteng 		case '\n':	/* when input is text */
305f92359bfSslatteng 		case ' ':
306f92359bfSslatteng 		case 0:		/* occasional noise creeps in */
307f92359bfSslatteng 			break;
308f92359bfSslatteng 		case '{':	/* push down current environment */
309f92359bfSslatteng 			t_push();
310f92359bfSslatteng 			break;
311f92359bfSslatteng 		case '}':
312f92359bfSslatteng 			t_pop();
313f92359bfSslatteng 			break;
314f92359bfSslatteng 		case '0': case '1': case '2': case '3': case '4':
315f92359bfSslatteng 		case '5': case '6': case '7': case '8': case '9':
316f92359bfSslatteng 			/* two motion digits plus a character */
317f92359bfSslatteng 			hmot((c-'0')*10 + getc(fp)-'0');
318f92359bfSslatteng 			put1(getc(fp));
319f92359bfSslatteng 			break;
320f92359bfSslatteng 		case 'c':	/* single ascii character */
321f92359bfSslatteng 			put1(getc(fp));
322f92359bfSslatteng 			break;
323f92359bfSslatteng 		case 'C':
324f92359bfSslatteng 			fscanf(fp, "%s", str);
325f92359bfSslatteng 			put1s(str);
326f92359bfSslatteng 			break;
327f92359bfSslatteng 		case 't':	/* straight text */
328f92359bfSslatteng 			fgets(buf, sizeof(buf), fp);
329f92359bfSslatteng 			t_text(buf);
330f92359bfSslatteng 			break;
331f92359bfSslatteng 		case 'D':	/* draw function */
332f92359bfSslatteng 			fgets(buf, sizeof(buf), fp);
333f92359bfSslatteng 			switch (buf[0]) {
334f92359bfSslatteng 			case 'l':	/* draw a line */
335f92359bfSslatteng 			    sscanf(buf+1, "%d %d", &n, &m);
336f92359bfSslatteng 			    drawline(n, m);
337f92359bfSslatteng 			    break;
338f92359bfSslatteng 			case 'c':	/* circle */
339f92359bfSslatteng 			    sscanf(buf+1, "%d", &n);
340f92359bfSslatteng 			    drawcirc(n);
341f92359bfSslatteng 			    break;
342f92359bfSslatteng 			case 'e':	/* ellipse */
343f92359bfSslatteng 			    sscanf(buf+1, "%d %d", &m, &n);
344f92359bfSslatteng 			    drawellip(m, n);
345f92359bfSslatteng 			    break;
346f92359bfSslatteng 			case 'a':	/* arc */
347f92359bfSslatteng 			    sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
348f92359bfSslatteng 			    drawarc(n, m, n1, m1);
349f92359bfSslatteng 			    break;
350f92359bfSslatteng 			case '~':	/* wiggly line */
3511a4ecc79Sslatteng 			case 'g':	/* gremlin spline */
3521a4ecc79Sslatteng 			    drawwig(buf+1, fp, buf[0] == '~');
3531a4ecc79Sslatteng 			    break;
3541a4ecc79Sslatteng 			case 't':	/* line thickness */
3551a4ecc79Sslatteng 			    sscanf(buf+1, "%d", &n);
3561a4ecc79Sslatteng 			    drawthick(n);
3571a4ecc79Sslatteng 			    break;
3581a4ecc79Sslatteng 			case 's':	/* line style */
3591a4ecc79Sslatteng 			    sscanf(buf+1, "%d", &n);
3601a4ecc79Sslatteng 			    drawstyle(n);
361f92359bfSslatteng 			    break;
362f92359bfSslatteng 			default:
363ebd02298Sslatteng 			    error(FATAL, "unknown drawing function %s", buf);
364f92359bfSslatteng 			    break;
365f92359bfSslatteng 			}
366f92359bfSslatteng 			break;
367f92359bfSslatteng 		case 's':
368f92359bfSslatteng 			fscanf(fp, "%d", &n);	/* ignore fractional sizes */
369f92359bfSslatteng 			setsize(t_size(n));
370f92359bfSslatteng 			break;
371f92359bfSslatteng 		case 'f':
372f92359bfSslatteng 			fscanf(fp, "%s", str);
373f92359bfSslatteng 			setfont(t_font(str));
374f92359bfSslatteng 			break;
375f92359bfSslatteng 		case 'H':	/* absolute horizontal motion */
376f92359bfSslatteng 			/* fscanf(fp, "%d", &n); */
377f92359bfSslatteng 			while ((c = getc(fp)) == ' ')
378f92359bfSslatteng 				;
379f92359bfSslatteng 			k = 0;
380f92359bfSslatteng 			do {
381f92359bfSslatteng 				k = 10 * k + c - '0';
382f92359bfSslatteng 			} while (isdigit(c = getc(fp)));
383f92359bfSslatteng 			ungetc(c, fp);
384f92359bfSslatteng 			hgoto(k);
385f92359bfSslatteng 			break;
386f92359bfSslatteng 		case 'h':	/* relative horizontal motion */
387f92359bfSslatteng 			while ((c = getc(fp)) == ' ')
388f92359bfSslatteng 				;
389f92359bfSslatteng 			k = 0;
390f92359bfSslatteng 			do {
391f92359bfSslatteng 				k = 10 * k + c - '0';
392f92359bfSslatteng 			} while (isdigit(c = getc(fp)));
393f92359bfSslatteng 			ungetc(c, fp);
394f92359bfSslatteng 			hmot(k);
395f92359bfSslatteng 			break;
396f92359bfSslatteng 		case 'w':	/* word space */
397f92359bfSslatteng 			break;
398f92359bfSslatteng 		case 'V':
399f92359bfSslatteng 			fscanf(fp, "%d", &n);
400f92359bfSslatteng 			vgoto(n);
401f92359bfSslatteng 			break;
402f92359bfSslatteng 		case 'v':
403f92359bfSslatteng 			fscanf(fp, "%d", &n);
404f92359bfSslatteng 			vmot(n);
405f92359bfSslatteng 			break;
406f92359bfSslatteng 		case 'p':	/* new page */
407f92359bfSslatteng 			fscanf(fp, "%d", &n);
408f92359bfSslatteng 			t_page(n);
409f92359bfSslatteng 			break;
410f92359bfSslatteng 		case 'n':	/* end of line */
411f92359bfSslatteng 			while (getc(fp) != '\n')
412f92359bfSslatteng 				;
413f92359bfSslatteng 			t_newline();
414f92359bfSslatteng 			break;
415f92359bfSslatteng 		case '#':	/* comment */
416f92359bfSslatteng 			while (getc(fp) != '\n')
417f92359bfSslatteng 				;
418f92359bfSslatteng 			break;
419f92359bfSslatteng 		case 'x':	/* device control */
420f92359bfSslatteng 			devcntrl(fp);
421f92359bfSslatteng 			break;
422f92359bfSslatteng 		default:
423ebd02298Sslatteng 			error(FATAL, "unknown input character %o %c", c, c);
424f92359bfSslatteng 		}
425f92359bfSslatteng 	}
426f92359bfSslatteng }
427f92359bfSslatteng 
428f92359bfSslatteng devcntrl(fp)	/* interpret device control functions */
429f92359bfSslatteng FILE *fp;
430f92359bfSslatteng {
431f92359bfSslatteng         char str[20], str1[50], buf[50];
432f92359bfSslatteng 	int c, n;
433f92359bfSslatteng 
434f92359bfSslatteng 	fscanf(fp, "%s", str);
435f92359bfSslatteng 	switch (str[0]) {	/* crude for now */
436f92359bfSslatteng 	case 'i':	/* initialize */
437f92359bfSslatteng 		fileinit();
438f92359bfSslatteng 		t_init();
439f92359bfSslatteng 		break;
440f92359bfSslatteng 	case 't':	/* trailer */
441f92359bfSslatteng 		break;
442f92359bfSslatteng 	case 'p':	/* pause -- can restart */
443f92359bfSslatteng 		t_reset('p');
444f92359bfSslatteng 		break;
445f92359bfSslatteng 	case 's':	/* stop */
446f92359bfSslatteng 		t_reset('s');
447f92359bfSslatteng 		break;
448f92359bfSslatteng 	case 'r':	/* resolution assumed when prepared */
4494da297a9Sslatteng 		fscanf(fp, "%d", &n);
4504da297a9Sslatteng 		if (n!=RES) error(FATAL,"Input computed with wrong resolution");
451f92359bfSslatteng 		break;
452f92359bfSslatteng 	case 'f':	/* font used */
453f92359bfSslatteng 		fscanf(fp, "%d %s", &n, str);
454f92359bfSslatteng 		fgets(buf, sizeof buf, fp);	/* in case there's a filename */
455f92359bfSslatteng 		ungetc('\n', fp);		/* fgets goes too far */
456f92359bfSslatteng 		str1[0] = 0;			/* in case nothing comes in */
457f92359bfSslatteng 		sscanf(buf, "%s", str1);
458f92359bfSslatteng 		loadfont(n, str, str1);
459f92359bfSslatteng 		break;
460f92359bfSslatteng 						/* these don't belong here... */
461f92359bfSslatteng 	case 'H':	/* char height */
462f92359bfSslatteng 		fscanf(fp, "%d", &n);
463f92359bfSslatteng 		t_charht(n);
464f92359bfSslatteng 		break;
465f92359bfSslatteng 	case 'S':	/* slant */
466f92359bfSslatteng 		fscanf(fp, "%d", &n);
467f92359bfSslatteng 		t_slant(n);
468f92359bfSslatteng 		break;
469f92359bfSslatteng 	}
470f92359bfSslatteng 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
471f92359bfSslatteng 		if (c == EOF)
472f92359bfSslatteng 			break;
473f92359bfSslatteng }
474f92359bfSslatteng 
475f92359bfSslatteng /* fileinit:	read in font and code files, etc.
476f92359bfSslatteng 		Must open table for device, read in resolution,
4774da297a9Sslatteng 		size info, font info, etc. and set params.
4784da297a9Sslatteng 		Also read in font name mapping.
479f92359bfSslatteng */
4804da297a9Sslatteng 
481f92359bfSslatteng fileinit()
482f92359bfSslatteng {
4834da297a9Sslatteng 	register int i;
4844da297a9Sslatteng 	register int fin;
4854da297a9Sslatteng 	register int nw;
4864da297a9Sslatteng 	register char *filebase;
4874da297a9Sslatteng 	register char *p;
4884da297a9Sslatteng 	register FILE *fp;
4894da297a9Sslatteng 	char	temp[100];
4904da297a9Sslatteng 
4914da297a9Sslatteng 		/* first, read in font map file.  The file must be of Format:
4924da297a9Sslatteng 			XX  FILENAME  (XX = troff font name)
4934da297a9Sslatteng 			with one entry per text line of the file.
4944da297a9Sslatteng 		   Extra stuff after FILENAME is ignored */
4954da297a9Sslatteng 
4964da297a9Sslatteng 	sprintf(temp, "%s/fontmap", bitdir);
4974da297a9Sslatteng 	if ((fp = fopen(temp, "r")) == NULL)
4984da297a9Sslatteng 		error(FATAL, "Can't open %s", temp);
4994da297a9Sslatteng 	for (i = 0; i <= NFONTS && fgets(temp, 100, fp) != NULL; i++) {
5004da297a9Sslatteng 		sscanf(temp, "%2s", fontmap[i].fname);
5014da297a9Sslatteng 		p = &temp[0];
5024da297a9Sslatteng 		while (*p != ' ' && *p != '	') p++;
5034da297a9Sslatteng 		while (*p == ' ' || *p == '	') p++;
5044da297a9Sslatteng 		filebase = p;
5054da297a9Sslatteng 		for (nw = 1; *p != '\n' && *p != ' ' && *p != '\t'; p++) nw++;
5064da297a9Sslatteng 		fontmap[i].ffile = nalloc(1, nw);
5074da297a9Sslatteng 		sscanf(filebase, "%s", fontmap[i].ffile);
5084da297a9Sslatteng 	}
5094da297a9Sslatteng 	fontmap[++i].fname[0] = '0';		/* finish off with zeros */
5104da297a9Sslatteng 	fontmap[i].ffile = (char *) 0;
5114da297a9Sslatteng 	fclose(fp);
5124da297a9Sslatteng #ifdef DEBUGABLE
5134da297a9Sslatteng 	if(dbg) {
5144da297a9Sslatteng 	    fprintf(stderr, "font map:\n");
5154da297a9Sslatteng 	    for (i = 0; fontmap[i].ffile; i++)
5164da297a9Sslatteng 		fprintf(stderr,"%s = %s\n", fontmap[i].fname, fontmap[i].ffile);
5174da297a9Sslatteng 	}
5184da297a9Sslatteng #endif
519f92359bfSslatteng 
520ebd02298Sslatteng 	sprintf(temp, "%s/devvar/DESC.out", fontdir);
521f92359bfSslatteng 	if ((fin = open(temp, 0)) < 0)
522ebd02298Sslatteng 		error(FATAL, "can't open tables for %s", temp);
523f92359bfSslatteng 	read(fin, &dev, sizeof(struct dev));
524f92359bfSslatteng 	nfonts = dev.nfonts;
525f92359bfSslatteng 	nsizes = dev.nsizes;
526f92359bfSslatteng 	nchtab = dev.nchtab;
527f92359bfSslatteng 	filebase = calloc(1, dev.filesize);	/* enough room for whole file */
528f92359bfSslatteng 	read(fin, filebase, dev.filesize);	/* all at once */
529f92359bfSslatteng 	pstab = (short *) filebase;
530f92359bfSslatteng 	chtab = pstab + nsizes + 1;
531f92359bfSslatteng 	chname = (char *) (chtab + dev.nchtab);
532f92359bfSslatteng 	p = chname + dev.lchname;
533f92359bfSslatteng 	for (i = 1; i <= nfonts; i++) {
534f92359bfSslatteng 		fontbase[i] = (struct font *) p;
535f92359bfSslatteng 		nw = *p & BMASK;		/* 1st thing is width count */
536*1c9df754Sslatteng 		p += sizeof(struct font);
537f92359bfSslatteng 		widtab[i] = p;
538f92359bfSslatteng 		codetab[i] = p + 2 * nw;
539f92359bfSslatteng 		fitab[i] = p + 3 * nw;
540f92359bfSslatteng 		p += 3 * nw + dev.nchtab + 128 - 32;
541f92359bfSslatteng 		t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
542f92359bfSslatteng #ifdef DEBUGABLE
543f92359bfSslatteng 		if (dbg > 1) fontprint(i);
544f92359bfSslatteng #endif
545f92359bfSslatteng 	}
546f92359bfSslatteng 	fontbase[0] = (struct font *)
547f92359bfSslatteng 		calloc(1,3*255 + dev.nchtab + (128-32) + sizeof (struct font));
548f92359bfSslatteng 	widtab[0] = (char *) fontbase[0] + sizeof (struct font);
549f92359bfSslatteng 	fontbase[0]->nwfont = 255;
550f92359bfSslatteng 	close(fin);
5514da297a9Sslatteng 
552f92359bfSslatteng }
553f92359bfSslatteng 
5544da297a9Sslatteng 
555f92359bfSslatteng fontprint(i)	/* debugging print of font i (0,...) */
556f92359bfSslatteng {
557f92359bfSslatteng 	int j, n;
558f92359bfSslatteng 	char *p;
559f92359bfSslatteng 
560f92359bfSslatteng 	fprintf(stderr,"font %d:\n", i);
561f92359bfSslatteng 	p = (char *) fontbase[i];
562f92359bfSslatteng 	n = fontbase[i]->nwfont & BMASK;
563f92359bfSslatteng 	fprintf(stderr,
564f92359bfSslatteng 	    "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",p,
565f92359bfSslatteng 	    n,fontbase[i]->specfont,fontbase[i]->namefont,widtab[i],fitab[i]);
566f92359bfSslatteng 	fprintf(stderr,"widths:\n");
567f92359bfSslatteng 	for (j=0; j <= n; j++) {
568f92359bfSslatteng 		fprintf(stderr," %2d", widtab[i][j] & BMASK);
569f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
570f92359bfSslatteng 	}
571f92359bfSslatteng 	fprintf(stderr,"\ncodetab:\n");
572f92359bfSslatteng 	for (j=0; j <= n; j++) {
573f92359bfSslatteng 		fprintf(stderr," %2d", codetab[i][j] & BMASK);
574f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
575f92359bfSslatteng 	}
576f92359bfSslatteng 	fprintf(stderr,"\nfitab:\n");
577f92359bfSslatteng 	for (j=0; j <= dev.nchtab + 128-32; j++) {
578f92359bfSslatteng 		fprintf(stderr," %2d", fitab[i][j] & BMASK);
579f92359bfSslatteng 		if (j % 20 == 19) fprintf(stderr,"\n");
580f92359bfSslatteng 	}
581f92359bfSslatteng 	fprintf(stderr,"\n");
582f92359bfSslatteng }
583f92359bfSslatteng 
584f92359bfSslatteng loadfont(n, s, s1)	/* load font info for font s on position n (0...) */
585f92359bfSslatteng int n;
586f92359bfSslatteng char *s, *s1;
587f92359bfSslatteng {
588f92359bfSslatteng 	char temp[60];
589f92359bfSslatteng 	int fin, nw, norig;
590f92359bfSslatteng 
5914da297a9Sslatteng 
592f92359bfSslatteng 	if (n < 0 || n > NFONTS)
593f92359bfSslatteng 		error(FATAL, "illegal fp command %d %s", n, s);
594f92359bfSslatteng 	if (strcmp(s, fontbase[n]->namefont) == 0)
595f92359bfSslatteng 		return;
596f92359bfSslatteng 	if (s1 == NULL || s1[0] == '\0')
597ebd02298Sslatteng 		sprintf(temp, "%s/devvar/%s.out", fontdir, s);
598f92359bfSslatteng 	else
599f92359bfSslatteng 		sprintf(temp, "%s/%s.out", s1, s);
600f92359bfSslatteng 	if ((fin = open(temp, 0)) < 0)
601f92359bfSslatteng 		error(FATAL, "can't open font table %s", temp);
602f92359bfSslatteng 	norig = fontbase[n]->nwfont & BMASK;
603f92359bfSslatteng 	read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font));
604f92359bfSslatteng 	if ((fontbase[n]->nwfont & BMASK) > norig)
605ebd02298Sslatteng 		error(FATAL, "Font %s too big for position %d", s, n);
606f92359bfSslatteng 	close(fin);
607f92359bfSslatteng 	nw = fontbase[n]->nwfont & BMASK;
608f92359bfSslatteng 	widtab[n] = (char *) fontbase[n] + sizeof(struct font);
609f92359bfSslatteng 	codetab[n] = (char *) widtab[n] + 2 * nw;
610f92359bfSslatteng 	fitab[n] = (char *) widtab[n] + 3 * nw;
611f92359bfSslatteng 	t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
612f92359bfSslatteng 	fontbase[n]->nwfont = norig;	/* to later use full original size */
613f92359bfSslatteng #ifdef DEBUGABLE
614f92359bfSslatteng 	if (dbg > 1) fontprint(n);
615f92359bfSslatteng #endif
616f92359bfSslatteng }
617f92359bfSslatteng 
618ebd02298Sslatteng 
619f92359bfSslatteng /*VARARGS1*/
620f92359bfSslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) {
621ebd02298Sslatteng 	fprintf(stderr, "dvar: ");
622f92359bfSslatteng 	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
623f92359bfSslatteng 	fprintf(stderr, "\n");
624*1c9df754Sslatteng 	if (f) exit(ABORT);
625f92359bfSslatteng }
626f92359bfSslatteng 
627f92359bfSslatteng 
628f92359bfSslatteng t_init()	/* initialize device */
629f92359bfSslatteng {
630f92359bfSslatteng 	int i;
631f92359bfSslatteng 
632f92359bfSslatteng 	hpos = vpos = 0;
633f92359bfSslatteng 
634f92359bfSslatteng 	setsize(t_size(10));	/* start somewhere */
635f92359bfSslatteng 	setfont(1);
636f92359bfSslatteng }
637f92359bfSslatteng 
638f92359bfSslatteng 
639f92359bfSslatteng struct state {
640f92359bfSslatteng 	int	ssize;
641f92359bfSslatteng 	int	sfont;
642f92359bfSslatteng 	int	shpos;
643f92359bfSslatteng 	int	svpos;
644ebd02298Sslatteng 	int	sstyle;
645ebd02298Sslatteng 	int	sthick;
646f92359bfSslatteng };
647f92359bfSslatteng struct	state	state[MAXSTATE];
648f92359bfSslatteng struct	state	*statep = state;
649f92359bfSslatteng 
650f92359bfSslatteng t_push()	/* begin a new block */
651f92359bfSslatteng {
652f92359bfSslatteng 	statep->ssize = size;
653f92359bfSslatteng 	statep->sfont = font;
654ebd02298Sslatteng 	statep->sstyle = linmod;
655ebd02298Sslatteng 	statep->sthick = linethickness;
656f92359bfSslatteng 	statep->shpos = hpos;
657f92359bfSslatteng 	statep->svpos = vpos;
658f92359bfSslatteng 	if (statep++ >= state+MAXSTATE)
659f92359bfSslatteng 		error(FATAL, "{ nested too deep");
660f92359bfSslatteng }
661f92359bfSslatteng 
662f92359bfSslatteng t_pop()	/* pop to previous state */
663f92359bfSslatteng {
664f92359bfSslatteng 	if (--statep < state)
665f92359bfSslatteng 		error(FATAL, "extra }");
666f92359bfSslatteng 	size = statep->ssize;
667f92359bfSslatteng 	font = statep->sfont;
668f92359bfSslatteng 	hpos = statep->shpos;
669f92359bfSslatteng 	vpos = statep->svpos;
670ebd02298Sslatteng 	linmod = statep->sstyle;
671ebd02298Sslatteng 	linethickness = statep->sthick;
672f92359bfSslatteng }
673f92359bfSslatteng 
674f92359bfSslatteng t_page(n)	/* do whatever new page functions */
675f92359bfSslatteng {
676f92359bfSslatteng 	int i;
677f92359bfSslatteng 
678f92359bfSslatteng 
679f92359bfSslatteng 	if (output) {
680f92359bfSslatteng 		if (++scount >= spage) {
681f92359bfSslatteng 			t_reset('p');
682f92359bfSslatteng 			scount = 0;
683f92359bfSslatteng 		}
684ebd02298Sslatteng 		slop_lines(NLINES);
685*1c9df754Sslatteng #ifdef DRIVER
686f92359bfSslatteng 		ioctl(OUTFILE, VSETSTATE, prtmode);
687f92359bfSslatteng 		if (write(OUTFILE, "\f", 2) != 2)
688f92359bfSslatteng 			exit(RESTART);
689f92359bfSslatteng 		ioctl(OUTFILE, VSETSTATE, pltmode);
690*1c9df754Sslatteng #endif
691f92359bfSslatteng 	}
692f92359bfSslatteng 
693f92359bfSslatteng 	vpos = 0;
694f92359bfSslatteng 	output = 1;
695f92359bfSslatteng 	if (nolist == 0)
696f92359bfSslatteng 		return;		/* no -o specified */
697f92359bfSslatteng 	output = 0;
698f92359bfSslatteng 	for (i = 0; i < nolist; i += 2)
699f92359bfSslatteng 		if (n >= olist[i] && n <= olist[i+1]) {
700f92359bfSslatteng 			output = 1;
701f92359bfSslatteng 			break;
702f92359bfSslatteng 		}
703f92359bfSslatteng }
704f92359bfSslatteng 
705f92359bfSslatteng t_newline()	/* do whatever for the end of a line */
706f92359bfSslatteng {
707f92359bfSslatteng 	hpos = 0;	/* because we're now back at the left margin */
708f92359bfSslatteng }
709f92359bfSslatteng 
710f92359bfSslatteng t_size(n)	/* convert integer to internal size number*/
711f92359bfSslatteng int n;
712f92359bfSslatteng {
713f92359bfSslatteng 	int i;
714f92359bfSslatteng 
715f92359bfSslatteng 	if (n <= pstab[0])
7164da297a9Sslatteng 		return(0);
717f92359bfSslatteng 	else if (n >= pstab[nsizes - 1])
7184da297a9Sslatteng 		return(nsizes - 1);
719f92359bfSslatteng 	for (i = 0; n > pstab[i]; i++)
720f92359bfSslatteng 		;
7214da297a9Sslatteng 	return(i);
722f92359bfSslatteng }
723f92359bfSslatteng 
724f92359bfSslatteng t_charht(n)	/* set character height to n */
725f92359bfSslatteng int n;
726f92359bfSslatteng {
727f92359bfSslatteng #ifdef DEBUGABLE
7284da297a9Sslatteng 	if (dbg) error(!FATAL, "can't set height on varian");
729f92359bfSslatteng #endif
730f92359bfSslatteng }
731f92359bfSslatteng 
732f92359bfSslatteng t_slant(n)	/* set slant to n */
733f92359bfSslatteng int n;
734f92359bfSslatteng {
735f92359bfSslatteng #ifdef DEBUGABLE
7364da297a9Sslatteng 	if (dbg) error(!FATAL, "can't set slant on varian");
737f92359bfSslatteng #endif
738f92359bfSslatteng }
739f92359bfSslatteng 
740f92359bfSslatteng t_font(s)	/* convert string to internal font number */
741f92359bfSslatteng char *s;
742f92359bfSslatteng {
743f92359bfSslatteng 	int n;
744f92359bfSslatteng 
745f92359bfSslatteng 	n = atoi(s);
746f92359bfSslatteng 	if (n < 0 || n > nfonts)
747f92359bfSslatteng 		n = 1;
748f92359bfSslatteng 	return(n);
749f92359bfSslatteng }
750f92359bfSslatteng 
751f92359bfSslatteng t_text(s)	/* print string s as text */
752f92359bfSslatteng char *s;
753f92359bfSslatteng {
754f92359bfSslatteng 	int c;
755f92359bfSslatteng 	char str[100];
756f92359bfSslatteng 
757f92359bfSslatteng 	if (!output)
758f92359bfSslatteng 		return;
759f92359bfSslatteng 	while (c = *s++) {
760f92359bfSslatteng 		if (c == '\\') {
761f92359bfSslatteng 			switch (c = *s++) {
762f92359bfSslatteng 			case '\\':
763f92359bfSslatteng 			case 'e':
764f92359bfSslatteng 				put1('\\');
765f92359bfSslatteng 				break;
766f92359bfSslatteng 			case '(':
767f92359bfSslatteng 				str[0] = *s++;
768f92359bfSslatteng 				str[1] = *s++;
769f92359bfSslatteng 				str[2] = '\0';
770f92359bfSslatteng 				put1s(str);
771f92359bfSslatteng 				break;
772f92359bfSslatteng 			}
773f92359bfSslatteng 		} else {
774f92359bfSslatteng 			put1(c);
775f92359bfSslatteng 		}
776f92359bfSslatteng 		hmot(lastw);
777f92359bfSslatteng #ifdef DEBUGABLE
778f92359bfSslatteng 		if (dbg) fprintf(stderr,"width = %d\n", lastw);
779f92359bfSslatteng #endif
780f92359bfSslatteng 	}
781f92359bfSslatteng }
782f92359bfSslatteng 
783f92359bfSslatteng t_reset(c)
784f92359bfSslatteng {
785f92359bfSslatteng 	output = 1;
786f92359bfSslatteng 	switch(c){
787f92359bfSslatteng 	case 'p':
788ebd02298Sslatteng 		slop_lines(NLINES);
789f92359bfSslatteng 		break;
790f92359bfSslatteng 	case 's':
791ebd02298Sslatteng 		slop_lines(NLINES);
792*1c9df754Sslatteng #ifdef DRIVER
793f92359bfSslatteng 		ioctl(OUTFILE, VSETSTATE, prtmode);
794f92359bfSslatteng 		if (write(OUTFILE, "\f", 2) != 2)
795f92359bfSslatteng 			exit(RESTART);
796*1c9df754Sslatteng #endif
7974da297a9Sslatteng 		break; /* no Return */
798f92359bfSslatteng 	}
799f92359bfSslatteng }
800f92359bfSslatteng 
801ebd02298Sslatteng 
802ebd02298Sslatteng /*----------------------------------------------------------------------------*
803ebd02298Sslatteng  | Routine:	hgoto (horizontal_spot)
804ebd02298Sslatteng  |
805ebd02298Sslatteng  | Results:	hpos is set to n.  If n overlaps in either direction, it wraps
806ebd02298Sslatteng  |		around to the other end of the page.
807ebd02298Sslatteng  *----------------------------------------------------------------------------*/
808ebd02298Sslatteng 
809ebd02298Sslatteng hgoto(n)
810ebd02298Sslatteng int n;
811f92359bfSslatteng {
812ebd02298Sslatteng     if (n < 0)
813ebd02298Sslatteng 	n += NLINES;
814ebd02298Sslatteng     else if (n >= NLINES)
815ebd02298Sslatteng 	n -= NLINES;
816ebd02298Sslatteng     hpos = n;
817f92359bfSslatteng }
818ebd02298Sslatteng 
819ebd02298Sslatteng 
820ebd02298Sslatteng /*----------------------------------------------------------------------------*
821ebd02298Sslatteng  | Routine:	vgoto (vertical_spot)
822ebd02298Sslatteng  |
823ebd02298Sslatteng  | Results:	vpos is set to n.  If n overlaps in either direction, it wraps
824ebd02298Sslatteng  |		around to the other end of the page.
825ebd02298Sslatteng  *----------------------------------------------------------------------------*/
826ebd02298Sslatteng 
827ebd02298Sslatteng vgoto(n)
828ebd02298Sslatteng int n;
829ebd02298Sslatteng {
830ebd02298Sslatteng     if (n < 0)
831ebd02298Sslatteng 	n += RASTER_LENGTH;
832ebd02298Sslatteng     else if (n > RASTER_LENGTH)
833ebd02298Sslatteng 	n -= RASTER_LENGTH;
834f92359bfSslatteng     vpos = n;
835f92359bfSslatteng }
836f92359bfSslatteng 
837f92359bfSslatteng put1s(s)	/* s is a funny char name */
838f92359bfSslatteng char *s;
839f92359bfSslatteng {
840f92359bfSslatteng 	int i;
841f92359bfSslatteng 
842f92359bfSslatteng 	if (!output)
843f92359bfSslatteng 		return;
844f92359bfSslatteng #ifdef DEBUGABLE
845f92359bfSslatteng 	if (dbg) fprintf(stderr,"%s ", s);
846f92359bfSslatteng #endif
847f92359bfSslatteng 	for (i = 0; i < nchtab; i++)
848f92359bfSslatteng 		if (strcmp(&chname[chtab[i]], s) == 0)
849f92359bfSslatteng 			break;
850f92359bfSslatteng 	if (i < nchtab)
851f92359bfSslatteng 		put1(i + 128);
852f92359bfSslatteng }
853f92359bfSslatteng 
854f92359bfSslatteng put1(c)	/* output char c */
855f92359bfSslatteng int c;
856f92359bfSslatteng {
857f92359bfSslatteng 	char *pw;
858f92359bfSslatteng 	register char *p;
859f92359bfSslatteng 	register int i, k;
860f92359bfSslatteng 	int j, ofont, code;
861f92359bfSslatteng 
862f92359bfSslatteng 	if (!output)
863f92359bfSslatteng 		return;
864f92359bfSslatteng 	c -= 32;
865f92359bfSslatteng 	if (c <= 0) {
866f92359bfSslatteng #ifdef DEBUGABLE
867f92359bfSslatteng 		if (dbg) fprintf(stderr,"non-exist 0%o\n", c + 32);
868f92359bfSslatteng #endif
8694da297a9Sslatteng  		lastw = (widtab[font][0] * pstab[size] + dev.unitwidth/2)
870f92359bfSslatteng 								/ dev.unitwidth;
871f92359bfSslatteng 		return;
872f92359bfSslatteng 	}
873f92359bfSslatteng 	k = ofont = font;
874f92359bfSslatteng 	i = fitab[font][c] & BMASK;
875f92359bfSslatteng 	if (i != 0) {			/* it's on this font */
876f92359bfSslatteng 		p = codetab[font];	/* get the printing value of ch */
877f92359bfSslatteng 		pw = widtab[font];	/* get the width */
878*1c9df754Sslatteng 	} else		/* on another font (we hope) */
879*1c9df754Sslatteng 		for (k=font, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)){
880f92359bfSslatteng 			if (fitab[k] == 0)
881f92359bfSslatteng 				continue;
882f92359bfSslatteng 			if ((i = fitab[k][c] & BMASK) != 0) {
883f92359bfSslatteng 				p = codetab[k];
884f92359bfSslatteng 				pw = widtab[k];
885f92359bfSslatteng 				setfont(k);
886f92359bfSslatteng 				break;
887f92359bfSslatteng 			}
888f92359bfSslatteng 		}
889*1c9df754Sslatteng 
890f92359bfSslatteng 	if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
891f92359bfSslatteng #ifdef DEBUGABLE
892f92359bfSslatteng 		if (dbg) fprintf(stderr,"not found 0%o\n", c+32);
893f92359bfSslatteng #endif
894f92359bfSslatteng 		return;
895f92359bfSslatteng 	}
896f92359bfSslatteng #ifdef DEBUGABLE
897f92359bfSslatteng 	if (dbg) {
898f92359bfSslatteng 		if (isprint(c+32))
899f92359bfSslatteng 			fprintf(stderr,"%c %d\n", c+32, code);
900f92359bfSslatteng 		else
901f92359bfSslatteng 			fprintf(stderr,"%03o %d\n", c+32, code);
902f92359bfSslatteng 	}
903f92359bfSslatteng #endif
904f92359bfSslatteng 	outc(code);	/* character is < 254 */
905f92359bfSslatteng 	if (font != ofont)
906f92359bfSslatteng 		setfont(ofont);
9074da297a9Sslatteng 	lastw = ((pw[i]&077) * pstab[size] + dev.unitwidth/2) / dev.unitwidth;
908f92359bfSslatteng }
909f92359bfSslatteng 
910f92359bfSslatteng 
911f92359bfSslatteng 
912f92359bfSslatteng setsize(n)	/* set point size to n (internal) */
913f92359bfSslatteng int n;
914f92359bfSslatteng {
915f92359bfSslatteng 
916f92359bfSslatteng 	if (n == size)
917f92359bfSslatteng 		return;	/* already there */
9184da297a9Sslatteng 	if (vloadfont(font, pstab[n]) != -1)
919f92359bfSslatteng 		size = n;
920f92359bfSslatteng }
921f92359bfSslatteng 
922f92359bfSslatteng t_fp(n, s, si)	/* font position n now contains font s, intname si */
923*1c9df754Sslatteng int n;		/* internal name is ignored */
924f92359bfSslatteng char *s, *si;
925f92359bfSslatteng {
9264da297a9Sslatteng 	register int i;
927f92359bfSslatteng 
9284da297a9Sslatteng 
9294da297a9Sslatteng 			/* first convert s to filename if possible */
9304da297a9Sslatteng 	for (i = 0; fontmap[i].ffile != (char *) 0; i++) {
9314da297a9Sslatteng #ifdef DEBUGABLE
9324da297a9Sslatteng 		if(dbg>1)fprintf(stderr,"testing :%s:%s:\n",s,fontmap[i].fname);
9334da297a9Sslatteng #endif
9344da297a9Sslatteng 		if (strcmp(s, fontmap[i].fname) == 0) {
9354da297a9Sslatteng 			s = fontmap[i].ffile;
9364da297a9Sslatteng #ifdef DEBUGABLE
9374da297a9Sslatteng 			if(dbg)fprintf(stderr, "found :%s:\n",fontmap[i].ffile);
9384da297a9Sslatteng #endif
9394da297a9Sslatteng 			break;
9404da297a9Sslatteng 		}
9414da297a9Sslatteng 	}
942*1c9df754Sslatteng 	fontname[n] = s;
943f92359bfSslatteng 	for(i = 0;i < NFONTS;i++)	/* free the bits of that font */
944f92359bfSslatteng 		if (fontdes[i].fnum == n){
945f92359bfSslatteng 			nfree(fontdes[i].bits);
946f92359bfSslatteng 			fontdes[i].bits = 0;
947f92359bfSslatteng 			fontdes[i].fnum = -1;
948f92359bfSslatteng 		}
949f92359bfSslatteng }
950f92359bfSslatteng 
9514da297a9Sslatteng 
952f92359bfSslatteng setfont(n)	/* set font to n */
953f92359bfSslatteng int n;
954f92359bfSslatteng {
955f92359bfSslatteng 	if (n < 0 || n > NFONTS)
956ebd02298Sslatteng 		error(FATAL, "illegal font %d", n);
9574da297a9Sslatteng 	if (vloadfont(n,pstab[size]) != -1)
958f92359bfSslatteng 		font = n;
959f92359bfSslatteng }
960f92359bfSslatteng 
961f92359bfSslatteng vloadfont(fnum, fsize)
962f92359bfSslatteng register int fnum;
963f92359bfSslatteng register int fsize;
964f92359bfSslatteng {
965f92359bfSslatteng 	register int i;
966f92359bfSslatteng 
967f92359bfSslatteng 	fontwanted = 0;
968f92359bfSslatteng 	if (fnum == cfnum && fsize == cpsize)
969f92359bfSslatteng 		return(0);
970f92359bfSslatteng 	for (i = 0; i < NFONTS; i++) {
971f92359bfSslatteng 		if (fontdes[i].fnum == fnum && fontdes[i].psize == fsize) {
972f92359bfSslatteng 			cfnum = fontdes[i].fnum;
973f92359bfSslatteng 			cpsize = fontdes[i].psize;
974f92359bfSslatteng 			dispatch = &fontdes[i].disp[0];
975f92359bfSslatteng 			bits = fontdes[i].bits;
976f92359bfSslatteng 			cfont = i;
977f92359bfSslatteng 			return (0);
978f92359bfSslatteng 		}
979f92359bfSslatteng 	}
980f92359bfSslatteng 		/* this is a new font */
981*1c9df754Sslatteng 	if (fnum < 0 || fnum > NFONTS || fontname[fnum] == 0) {
982f92359bfSslatteng 	    fprintf(stderr, "Internal error: illegal font %d name %s size\n",
983*1c9df754Sslatteng 			    fontname[fnum], fnum, fsize);
984f92359bfSslatteng 	    return(-1);
985f92359bfSslatteng 	}
986f92359bfSslatteng 		/* Need to verify the existance of that font/size here*/
987f92359bfSslatteng 	nfontnum = fnum;
988f92359bfSslatteng 	npsize = fsize;
989f92359bfSslatteng 	fontwanted++;
990f92359bfSslatteng 	return (0);
991f92359bfSslatteng }
992f92359bfSslatteng 
993f92359bfSslatteng 
994f92359bfSslatteng getfont()
995f92359bfSslatteng {
9964da297a9Sslatteng 	register int fnum;
9974da297a9Sslatteng 	register int fsize;
9984da297a9Sslatteng 	register int fontd;
9994da297a9Sslatteng 	register int d;
1000*1c9df754Sslatteng 	register int sizehunt = size;
1001f92359bfSslatteng 	char cbuf[BUFSIZ];
1002f92359bfSslatteng 
1003f92359bfSslatteng 	fnum = nfontnum;
1004f92359bfSslatteng 	fsize = npsize;
10054da297a9Sslatteng 			/* try to open font file - if unsuccessful, hunt for */
10064da297a9Sslatteng 			/* a file of same style, different size to substitute */
10074da297a9Sslatteng 	d = -1;	 /* direction to look in pstab (smaller first) */
10084da297a9Sslatteng 	do {
1009*1c9df754Sslatteng 	    sprintf(cbuf, "%s/%s.%dr", bitdir, fontname[fnum], fsize);
1010f92359bfSslatteng 	    fontd = open(cbuf, OPENREAD);
10114da297a9Sslatteng 	    if (fontd == -1) {		/* File wasn't found. Try another ps */
1012*1c9df754Sslatteng 		sizehunt += d;
1013*1c9df754Sslatteng 		if (sizehunt < 0) {	/* past beginning - look higher */
10144da297a9Sslatteng 		    d = 1;
1015*1c9df754Sslatteng 		    sizehunt = size + 1;
10164da297a9Sslatteng 		}
1017*1c9df754Sslatteng 		if (sizehunt > nsizes) {	/* past top - forget it */
10184da297a9Sslatteng 		    d = 0;
10194da297a9Sslatteng 		} else {
1020*1c9df754Sslatteng 		    fsize = pstab[sizehunt];
10214da297a9Sslatteng 		}
10224da297a9Sslatteng 	    }
10234da297a9Sslatteng 	} while (fontd == -1 && d != 0);
10244da297a9Sslatteng 
10254da297a9Sslatteng 	if (fontd == -1) {		/* completely unsuccessful */
1026f92359bfSslatteng 	    perror(cbuf);
10274da297a9Sslatteng 	    error(!FATAL,"fnum = %d, psize = %d, name = %s",
1028*1c9df754Sslatteng 		fnum, npsize, fontname[fnum]);
1029f92359bfSslatteng 	    fontwanted = 0;
1030f92359bfSslatteng 	    return (-1);
1031f92359bfSslatteng 	}
1032f92359bfSslatteng 	if (read(fontd, &header, sizeof  (header)) != sizeof (header)
1033f92359bfSslatteng 						|| header.magic != 0436)
1034f92359bfSslatteng 		fprintf(stderr, "%s: Bad font file", cbuf);
1035f92359bfSslatteng 	else {
1036f92359bfSslatteng 		cfont = relfont();
1037f92359bfSslatteng 		if ((bits=nalloc(header.size+DSIZ+1,1))== NULL)
1038f92359bfSslatteng 			if ((bits=allpanic(header.size+DSIZ+1))== NULL) {
1039*1c9df754Sslatteng 				error(FATAL,"%s: ran out of memory", cbuf);
1040f92359bfSslatteng 			}
1041f92359bfSslatteng 
1042f92359bfSslatteng 			/*
1043f92359bfSslatteng 			 * have allocated one chunk of mem for font, dispatch.
1044f92359bfSslatteng 			 * get the dispatch addr, align to word boundary.
1045f92359bfSslatteng 			 */
1046f92359bfSslatteng 
1047f92359bfSslatteng 		d = (int) bits+header.size;
1048f92359bfSslatteng 		d += 1;
1049f92359bfSslatteng 		d &= ~1;
1050f92359bfSslatteng 		if (read (fontd, d, DSIZ) != DSIZ
1051f92359bfSslatteng 			    || read (fontd, bits, header.size) != header.size)
1052f92359bfSslatteng 			fprintf(stderr, "bad font header");
1053f92359bfSslatteng 		else {
1054f92359bfSslatteng 			close(fontd);
1055f92359bfSslatteng 			cfnum = fontdes[cfont].fnum = fnum;
1056f92359bfSslatteng 			cpsize = fontdes[cfont].psize = fsize;
1057f92359bfSslatteng 			fontdes [cfont].bits = bits;
1058f92359bfSslatteng 			fontdes [cfont].disp = (struct dispatch *) d;
1059f92359bfSslatteng 			dispatch = &fontdes[cfont].disp[0];
1060f92359bfSslatteng 			fontwanted = 0;
1061f92359bfSslatteng 			return (0);
1062f92359bfSslatteng 		}
1063f92359bfSslatteng 	}
1064f92359bfSslatteng 	close(fontd);
1065f92359bfSslatteng 	fontwanted = 0;
1066f92359bfSslatteng 	return(-1);
1067f92359bfSslatteng }
1068f92359bfSslatteng 
1069f92359bfSslatteng /*
1070f92359bfSslatteng  * "release" a font position - find an empty one, if possible
1071f92359bfSslatteng  */
1072f92359bfSslatteng 
1073f92359bfSslatteng relfont()
1074f92359bfSslatteng {
1075f92359bfSslatteng     register int newfont;
1076f92359bfSslatteng 
1077f92359bfSslatteng     for (newfont = 0; newfont < NFONTS; newfont++)
1078f92359bfSslatteng 	if (fontdes [newfont].bits == (char *) -1  ||  !fontdes [newfont].bits)
1079f92359bfSslatteng 	    break;
1080f92359bfSslatteng     if (fontdes [newfont].bits != (char *) -1  &&  fontdes [newfont].bits) {
1081f92359bfSslatteng 	nfree (fontdes [newfont].bits);
1082f92359bfSslatteng 	fontdes [newfont].bits = (char *)0;
1083f92359bfSslatteng #ifdef DEBUGABLE
1084f92359bfSslatteng 	if (dbg) fprintf (stderr, "freeing position %d\n", newfont);
1085f92359bfSslatteng     } else {
1086f92359bfSslatteng 	if (dbg)
1087f92359bfSslatteng 	    fprintf (stderr, "taking, not freeing, position %d\n", newfont);
1088f92359bfSslatteng #endif
1089f92359bfSslatteng     }
1090f92359bfSslatteng     fontdes[newfont].bits = 0;
1091f92359bfSslatteng     return (newfont);
1092f92359bfSslatteng }
1093f92359bfSslatteng 
1094f92359bfSslatteng char *allpanic (nbytes)
1095f92359bfSslatteng int nbytes;
1096f92359bfSslatteng {
1097f92359bfSslatteng 	register int i;
1098f92359bfSslatteng 
1099f92359bfSslatteng 	for (i = 0; i <= NFONTS; i++)
1100f92359bfSslatteng 	    if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
1101f92359bfSslatteng 		nfree(fontdes[i].bits);
1102f92359bfSslatteng 	for (i = 0; i <= NFONTS; i++) {
1103f92359bfSslatteng 		fontdes[i].fnum = fontdes[i].psize = -1;
1104f92359bfSslatteng 		fontdes[i].bits = 0;
1105f92359bfSslatteng 		cfnum = cpsize = -1;
1106f92359bfSslatteng 	}
1107f92359bfSslatteng 	return(nalloc(nbytes,1));
1108f92359bfSslatteng }
1109f92359bfSslatteng 
1110f92359bfSslatteng int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
1111f92359bfSslatteng 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
1112f92359bfSslatteng int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
1113f92359bfSslatteng 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
1114f92359bfSslatteng int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
1115f92359bfSslatteng 
1116f92359bfSslatteng outc(code)
1117f92359bfSslatteng int code;		/* character to print */
1118f92359bfSslatteng {
1119f92359bfSslatteng     register struct dispatch *dis; /* ptr to character font record */
1120f92359bfSslatteng     register char *addr;	/* addr of font data */
1121f92359bfSslatteng     int llen;			/* length of each font line */
1122f92359bfSslatteng     int nlines;			/* number of font lines */
1123f92359bfSslatteng     register char *scanp;	/* ptr to output buffer */
1124f92359bfSslatteng     int scanp_inc;		/* increment to start of next buffer */
1125f92359bfSslatteng     int offset;			/* bit offset to start of font data */
11264da297a9Sslatteng     register int i;		/* loop counter */
1127f92359bfSslatteng     register int count;		/* font data ptr */
1128f92359bfSslatteng     register unsigned fontdata;	/* font data temporary */
1129f92359bfSslatteng     register int off8;		/* offset + 8 */
1130f92359bfSslatteng 
1131f92359bfSslatteng     if (fontwanted)
1132f92359bfSslatteng 	getfont();
1133f92359bfSslatteng     dis = dispatch + code;
1134f92359bfSslatteng     if (dis->nbytes) {
1135f92359bfSslatteng 	addr = bits + dis->addr;
11361a4ecc79Sslatteng 	llen = (dis->up + dis->down + 7) >> 3;
11371a4ecc79Sslatteng 	nlines = dis->right + dis->left;
11381a4ecc79Sslatteng 	scanp = buf0p + (hpos - dis->left) * BYTES_PER_LINE
11391a4ecc79Sslatteng 			- (1 + ((dis->down + vpos) >> 3));
1140f92359bfSslatteng 	if (scanp < &buffer[0])
1141f92359bfSslatteng 	    scanp += sizeof buffer;
1142f92359bfSslatteng 	scanp_inc = BYTES_PER_LINE - llen;
11431a4ecc79Sslatteng 	off8 = ((dis->down + vpos) &07);
11441a4ecc79Sslatteng 	offset = off8 - 8;
1145f92359bfSslatteng 	for (i = 0; i < nlines; i++) {
1146f92359bfSslatteng 	    if (scanp >= &buffer[BUFFER_SIZE])
1147*1c9df754Sslatteng 		scanp -= BUFFER_SIZE;
1148f92359bfSslatteng 	    count = llen;
1149*1c9df754Sslatteng 	    if (scanp + count < &buffer[BUFFER_SIZE]) {
1150f92359bfSslatteng 		do {
1151f92359bfSslatteng 		    fontdata = *(unsigned *)addr;
1152f92359bfSslatteng 		    addr += 4;
1153f92359bfSslatteng 		    if (count < 4)
1154f92359bfSslatteng 			fontdata &= ~strim[count];
1155f92359bfSslatteng 		    *(unsigned*)scanp |=(fontdata << offset) & ~M[off8];
1156f92359bfSslatteng 		    scanp++;
1157f92359bfSslatteng 		    *(unsigned*)scanp |=(fontdata << off8) & ~N[off8];
1158f92359bfSslatteng 		    scanp += 3;
1159f92359bfSslatteng 		    count -= 4;
1160f92359bfSslatteng 		} while (count > 0);
1161f92359bfSslatteng 	    }
1162f92359bfSslatteng 	    scanp += scanp_inc+count;
1163f92359bfSslatteng 	    addr += count;
1164f92359bfSslatteng 	}
1165f92359bfSslatteng 	return;
1166f92359bfSslatteng     }
1167f92359bfSslatteng     return;
1168f92359bfSslatteng }
1169f92359bfSslatteng 
1170f92359bfSslatteng slop_lines(nlines)
1171f92359bfSslatteng int nlines;
1172f92359bfSslatteng 
1173f92359bfSslatteng /* Output "nlines" lines from the buffer, and clear that section of the  */
1174f92359bfSslatteng /* buffer.	*/
1175f92359bfSslatteng 
1176f92359bfSslatteng {
1177f92359bfSslatteng 	unsigned usize;
1178f92359bfSslatteng 
1179f92359bfSslatteng 	usize = BYTES_PER_LINE * nlines;
11804da297a9Sslatteng 	vwrite(buf0p, usize);
1181f92359bfSslatteng 	vclear(buf0p, usize);
1182*1c9df754Sslatteng #ifdef DRIVER
1183f92359bfSslatteng 	ioctl(OUTFILE, VSETSTATE, pltmode);
1184*1c9df754Sslatteng #endif
1185f92359bfSslatteng }
1186f92359bfSslatteng 
11874da297a9Sslatteng vwrite(buf,usize)
1188f92359bfSslatteng char *buf;
1189f92359bfSslatteng unsigned usize;
1190f92359bfSslatteng {
1191f92359bfSslatteng 	register int tsize = 0;
1192f92359bfSslatteng 
1193f92359bfSslatteng 	while (usize){
1194f92359bfSslatteng 		buf += tsize;
1195f92359bfSslatteng 		tsize = usize > MAXWRIT ? MAXWRIT : usize;
1196f92359bfSslatteng #ifdef DEBUGABLE
1197f92359bfSslatteng 		if (dbg)fprintf(stderr,"buf = %d size = %d\n",buf,tsize);
1198f92359bfSslatteng #endif
1199f92359bfSslatteng 		if ((tsize = write(OUTFILE, buf, tsize)) < 0) {
1200ebd02298Sslatteng 			perror("dvar: write failed");
1201f92359bfSslatteng 			exit(RESTART);
1202f92359bfSslatteng 		}
1203f92359bfSslatteng 		usize -= tsize;
1204f92359bfSslatteng 	}
1205f92359bfSslatteng }
1206f92359bfSslatteng 
1207f92359bfSslatteng vclear (ptr, nbytes)
1208f92359bfSslatteng char	*ptr;
1209f92359bfSslatteng unsigned nbytes;
1210f92359bfSslatteng {
1211f92359bfSslatteng     register tsize = 0;
1212f92359bfSslatteng 
1213f92359bfSslatteng     while (nbytes){
1214f92359bfSslatteng 	if ((unsigned)(16*1024) < nbytes) {
1215f92359bfSslatteng 	    tsize = 16 * 1024;
1216f92359bfSslatteng 	} else
1217f92359bfSslatteng 	    tsize = nbytes;
1218f92359bfSslatteng 	nbytes -= tsize;
1219f92359bfSslatteng #ifdef DEBUGABLE
1220f92359bfSslatteng 	if (dbg) fprintf(stderr,"clearing ptr = %d size = %d\n",ptr,tsize);
1221f92359bfSslatteng #endif
1222f92359bfSslatteng 	clear(ptr,tsize);
1223f92359bfSslatteng 	ptr += tsize;
1224f92359bfSslatteng     }
1225f92359bfSslatteng }
1226f92359bfSslatteng 
1227f92359bfSslatteng /*ARGSUSED*/
1228f92359bfSslatteng clear(lp, nbytes)
1229f92359bfSslatteng int *lp;
1230f92359bfSslatteng int nbytes;
1231f92359bfSslatteng {
1232f92359bfSslatteng 	asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
1233f92359bfSslatteng }
1234f92359bfSslatteng 
1235f92359bfSslatteng char *
1236f92359bfSslatteng nalloc(i, j)
1237f92359bfSslatteng int i, j;
1238f92359bfSslatteng {
1239f92359bfSslatteng 	register char *cp;
1240f92359bfSslatteng 
1241f92359bfSslatteng 	cp = calloc(i, j);
1242f92359bfSslatteng #ifdef DEBUGABLE
1243f92359bfSslatteng 	if (dbg) fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp);
1244f92359bfSslatteng #endif
1245f92359bfSslatteng 	return(cp);
1246f92359bfSslatteng }
1247f92359bfSslatteng 
1248f92359bfSslatteng nfree(cp)
1249f92359bfSslatteng char *cp;
1250f92359bfSslatteng {
1251f92359bfSslatteng #ifdef DEBUGABLE
1252f92359bfSslatteng 	if (dbg) fprintf(stderr, "freeing at %x\n", cp);
1253f92359bfSslatteng #endif
1254f92359bfSslatteng 	free(cp);
1255f92359bfSslatteng }
1256f92359bfSslatteng 
1257f92359bfSslatteng 
1258f92359bfSslatteng /*
1259f92359bfSslatteng  * Points should be in the range 0 <= x < RASTER_LENGTH, 0 <= y < NLINES.
1260f92359bfSslatteng  * The origin is the top left-hand corner with increasing x towards the
12614da297a9Sslatteng  * right and increasing y going down.  X and Y should be sent as (0,0) being
12624da297a9Sslatteng  * at the bottom left.  The output array is NLINES x BYTES_PER_LINE pixels.
1263f92359bfSslatteng  */
1264f92359bfSslatteng point(x, y)
12651a4ecc79Sslatteng register int x;
12661a4ecc79Sslatteng register int y;
1267f92359bfSslatteng {
12681a4ecc79Sslatteng     if ((unsigned)(y=RASTER_LENGTH-y) < RASTER_LENGTH && (unsigned)x < NLINES) {
12691a4ecc79Sslatteng 	buffer [x * BYTES_PER_LINE + (y >> 3)] |= 1 << (7 - (y & 07));
1270f92359bfSslatteng     }
1271f92359bfSslatteng }
1272