1*31889Sdenise #ifndef lint
2*31889Sdenise static char sccsid[]="@(#)prects.c	1.1	(CWI)	87/07/16";
3*31889Sdenise #endif lint
4*31889Sdenise /*
5*31889Sdenise  * read the fontdir/char.rle files from cdata output to produce the
6*31889Sdenise  * rectangular data for a font.
7*31889Sdenise  */
8*31889Sdenise 
9*31889Sdenise #include <sys/types.h>
10*31889Sdenise #include <sys/dir.h>
11*31889Sdenise #include <sys/file.h>
12*31889Sdenise #include <stdio.h>
13*31889Sdenise #include <strings.h>
14*31889Sdenise 
15*31889Sdenise #include "../defs.h"
16*31889Sdenise #include "huff7.h"
17*31889Sdenise #include "huff14.h"
18*31889Sdenise #include "Ptable.h"
19*31889Sdenise 
20*31889Sdenise extern long lseek();
21*31889Sdenise 
22*31889Sdenise extern Word	huff7[];
23*31889Sdenise extern Word	huff14[];
24*31889Sdenise extern Byte	Ptable[];
25*31889Sdenise 
26*31889Sdenise /*
27*31889Sdenise  * bit map will be at most 1024 by 1024 points
28*31889Sdenise  *
29*31889Sdenise  * The right answer would be to compact the data in
30*31889Sdenise  * bytes, but I'm just going to hack this... (DD)
31*31889Sdenise  */
32*31889Sdenise 
33*31889Sdenise #define MAXnat	1024
34*31889Sdenise #define MAX	128
35*31889Sdenise typedef unsigned short nat;
36*31889Sdenise 
37*31889Sdenise Byte bitmap[MAX][MAXnat], 		/* `real' binary data		*/
38*31889Sdenise      newbitmap[MAXnat][ MAXnat];	/* expanded data in chars	*/
39*31889Sdenise Byte sqmap[MAXnat][MAXnat],
40*31889Sdenise      prmap[MAXnat][MAXnat],
41*31889Sdenise      uline[MAXnat];
42*31889Sdenise 
43*31889Sdenise FILE *fd;
44*31889Sdenise int eoc = 0;	/* signals end of a character */
45*31889Sdenise 
46*31889Sdenise /*
47*31889Sdenise  * storage of 3 previous scan lines plus current working scan line
48*31889Sdenise  * 6 extra points (always of) for begin of end of scanline for predict()
49*31889Sdenise  */
50*31889Sdenise 
51*31889Sdenise Byte a[1030], b[1030], c[1030], d[1030];
52*31889Sdenise 	/* pointers to the scanline storage */
53*31889Sdenise Byte *sl0 = &a[3], *sl1 = &b[3], *sl2 = &c[3], *sl3 = &d[3];
54*31889Sdenise 
55*31889Sdenise #define EVER	;;
56*31889Sdenise 
57*31889Sdenise /*
58*31889Sdenise  * Opcodes for the huffman decoder
59*31889Sdenise  */
60*31889Sdenise 
61*31889Sdenise #define OPCODE	0300
62*31889Sdenise #define FINAL	0
63*31889Sdenise #define POINT	0200
64*31889Sdenise #define SUFFIX	0100
65*31889Sdenise 
66*31889Sdenise /*
67*31889Sdenise  * address bits for pointer (huffman decode)
68*31889Sdenise  */
69*31889Sdenise 
70*31889Sdenise #define ADDRS	077
71*31889Sdenise #define SUFDAT	017
72*31889Sdenise 
73*31889Sdenise /*
74*31889Sdenise  * Run length value types
75*31889Sdenise  */
76*31889Sdenise 
77*31889Sdenise #define DUMP	1
78*31889Sdenise #define X0	2
79*31889Sdenise #define Y0	3
80*31889Sdenise #define LMAX	4
81*31889Sdenise #define RUNL	5
82*31889Sdenise 
83*31889Sdenise #define Charmax 128
84*31889Sdenise 
85*31889Sdenise struct Header head;
86*31889Sdenise struct Chars Char[Charmax];
87*31889Sdenise struct Rect rect;
88*31889Sdenise 
89*31889Sdenise struct Rect buf[BUFSIZ];		/* global buffer to hold rects */
90*31889Sdenise struct Rect *bob = buf;			/* pointer to start of buffer */
91*31889Sdenise struct Rect *eob = &buf[BUFSIZ-1];	/* pointer to end of buffer */
92*31889Sdenise struct Rect *curp = buf;		/* current buffer pointer */
93*31889Sdenise long offset;				/* offset in file */
94*31889Sdenise 
95*31889Sdenise 
96*31889Sdenise /*
97*31889Sdenise  * We start with significant bit
98*31889Sdenise  */
99*31889Sdenise 
100*31889Sdenise #define BITMASK	0100000L
101*31889Sdenise 
102*31889Sdenise #define dbprintf if(debug)printf
103*31889Sdenise int debug = 0;
104*31889Sdenise 
105*31889Sdenise 
106*31889Sdenise #define MAXFNAME 30
107*31889Sdenise char filename[MAXFNAME];
108*31889Sdenise int fdo; 			/* file descriptor for output file */
109*31889Sdenise 
main(argc,argv)110*31889Sdenise main(argc, argv)
111*31889Sdenise int argc;
112*31889Sdenise char **argv;
113*31889Sdenise {
114*31889Sdenise 	int i, j;
115*31889Sdenise 	DIR *dir;
116*31889Sdenise 	char  outfile[BUFSIZ];	/* name for output file */
117*31889Sdenise 	struct direct *dirbuf;
118*31889Sdenise 	char *file, *directory;
119*31889Sdenise 	Word *type, *gethuff();
120*31889Sdenise 	int k;  		/* character we are on */
121*31889Sdenise 	char *p;
122*31889Sdenise 
123*31889Sdenise 	argv++;
124*31889Sdenise 	while( --argc && *argv[0] == '-') {
125*31889Sdenise 
126*31889Sdenise 		switch((*argv)[1]) {
127*31889Sdenise 			case 'd':
128*31889Sdenise 				debug++;
129*31889Sdenise 				break;
130*31889Sdenise 			case 'o':
131*31889Sdenise 				sprintf(outfile,"%s", (*argv)+2);
132*31889Sdenise 				break;
133*31889Sdenise 			default:
134*31889Sdenise 				error("Unknown option %s", *argv);
135*31889Sdenise 		}
136*31889Sdenise 		argv++;
137*31889Sdenise 	}
138*31889Sdenise 
139*31889Sdenise 	if(argc < 1)
140*31889Sdenise 		error("No data specified");
141*31889Sdenise 
142*31889Sdenise 	while(argc--) {
143*31889Sdenise 		directory = rindex(*argv, '/');
144*31889Sdenise 		if( directory == (char *)0)
145*31889Sdenise 			directory = *argv;
146*31889Sdenise 		else
147*31889Sdenise 			directory++;
148*31889Sdenise 
149*31889Sdenise 		if((dir = opendir(*argv)) == NULL)
150*31889Sdenise 			error("Can't open directory %s", *argv);
151*31889Sdenise 		argv++;
152*31889Sdenise 		if(sscanf(directory, "%d-%d", &j, &i) == 0)
153*31889Sdenise 			error("scanf error");
154*31889Sdenise 		type = gethuff(i);
155*31889Sdenise 		if(outfile[0] == NULL)
156*31889Sdenise 			sprintf(outfile,"%s.rect", directory);
157*31889Sdenise 		dbprintf("Output to file %s\n", outfile );
158*31889Sdenise 		if((fdo = open(outfile,O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
159*31889Sdenise 			error("open error %s\n", outfile);
160*31889Sdenise 		head.magic = MAGIC;
161*31889Sdenise 		bcopy(directory, head.name,strlen(directory));
162*31889Sdenise 		headit();
163*31889Sdenise 		setchars();
164*31889Sdenise 		setoffset();
165*31889Sdenise 		for(dirbuf = readdir(dir); dirbuf != NULL; dirbuf = readdir(dir) ) {
166*31889Sdenise 			if(strcmp((file = dirbuf->d_name), ".") == 0 ||
167*31889Sdenise 				strcmp(file, "..") == 0)
168*31889Sdenise 				continue;
169*31889Sdenise 			sprintf(filename,"%s/%s",directory,file);
170*31889Sdenise 			p = file;
171*31889Sdenise 			while(*p++)
172*31889Sdenise 				;
173*31889Sdenise 			p -= 5;
174*31889Sdenise 			if(strcmp(p, ".rle") != 0){
175*31889Sdenise 				fprintf(stderr, "strange file %s, skipped\n",  filename);
176*31889Sdenise 				continue;
177*31889Sdenise 			}
178*31889Sdenise 			sscanf(file, "%o", &k);
179*31889Sdenise 			if(k >  Charmax) {
180*31889Sdenise 				fprintf(stderr,"Wierd Character  %s\n", filename);
181*31889Sdenise 				continue;
182*31889Sdenise 			}
183*31889Sdenise 			chardecode(type, k-1);
184*31889Sdenise 			cleanup();
185*31889Sdenise 		}
186*31889Sdenise 		flusho();
187*31889Sdenise 		setchars();
188*31889Sdenise 	}
189*31889Sdenise }
190*31889Sdenise 
191*31889Sdenise 
192*31889Sdenise /*
193*31889Sdenise  * gethuff:
194*31889Sdenise  *	get the huff value from the directory name.
195*31889Sdenise  */
196*31889Sdenise 
197*31889Sdenise Word *
gethuff(mcode)198*31889Sdenise gethuff(mcode)
199*31889Sdenise int mcode;
200*31889Sdenise {
201*31889Sdenise 	Word *huff;
202*31889Sdenise 
203*31889Sdenise 	switch(mcode) {
204*31889Sdenise 		case MSC1:
205*31889Sdenise 		case MSC2:
206*31889Sdenise 			huff = huff7;
207*31889Sdenise 			break;
208*31889Sdenise 		case MSC3:
209*31889Sdenise 			huff = huff14;
210*31889Sdenise 			break;
211*31889Sdenise 		default:
212*31889Sdenise 			error("Unknown master code %#o\n", mcode);
213*31889Sdenise 	}
214*31889Sdenise 	return huff;
215*31889Sdenise }
216*31889Sdenise 
217*31889Sdenise 
218*31889Sdenise /*
219*31889Sdenise  * chardecode:
220*31889Sdenise  *	decode the encode character date in gcd of
221*31889Sdenise  *	pointsize code mcode
222*31889Sdenise  */
223*31889Sdenise 
224*31889Sdenise int X, Y, Lmax;	/* the offsets */
225*31889Sdenise int curx, cury;
226*31889Sdenise int endline;
227*31889Sdenise 
chardecode(huff,charno)228*31889Sdenise chardecode(huff, charno)
229*31889Sdenise int charno; Word *huff;
230*31889Sdenise {
231*31889Sdenise 	int runl;
232*31889Sdenise 
233*31889Sdenise 	(void) getbit(1);	/* reset the getbit routine */
234*31889Sdenise 
235*31889Sdenise 	curx = Char[charno].Relwidth =  getnbits(8);	/* ignore the first 8 bits */
236*31889Sdenise 	curx = X = Char[charno].XO = huffdecode(huff);
237*31889Sdenise 	cury = Y = Char[charno].YO = huffdecode(huff);
238*31889Sdenise 	Lmax = Char[charno].Lmax = huffdecode(huff);
239*31889Sdenise 
240*31889Sdenise 	/*
241*31889Sdenise 	 * Lmax 18 means 17 dots, so y should go from
242*31889Sdenise 	 * Y to Lmax -1 ????
243*31889Sdenise 	 */
244*31889Sdenise 	endline = Y + Lmax - 1 ;
245*31889Sdenise 
246*31889Sdenise 	while(!eoc) {
247*31889Sdenise 		for( cury = Y ; cury <= endline; ) {
248*31889Sdenise 			runl = huffdecode(huff);
249*31889Sdenise 			if(!runl) {		/* End of Line */
250*31889Sdenise 				predict(cury, endline - cury, 1);
251*31889Sdenise 				cury = endline;
252*31889Sdenise 				break;
253*31889Sdenise 			}
254*31889Sdenise 			else {
255*31889Sdenise 				predict(cury, runl, 0);
256*31889Sdenise 				cury += runl;
257*31889Sdenise 				if(cury >= endline)
258*31889Sdenise 					break;
259*31889Sdenise 			}
260*31889Sdenise 		}
261*31889Sdenise 		cury =  Y ;
262*31889Sdenise 		storescanline(curx, cury, endline);
263*31889Sdenise 		swapscanp();
264*31889Sdenise 		curx++;
265*31889Sdenise 	}
266*31889Sdenise 	Char[charno].X = curx - X ;
267*31889Sdenise 	Char[charno].Y = (Lmax + Y - 2) - Y;
268*31889Sdenise 	Char[charno].offset = offset;
269*31889Sdenise 	setbitmap(X, Y, curx, Lmax + Y - 2);
270*31889Sdenise 	maxsq();
271*31889Sdenise 	prune();
272*31889Sdenise 	Char[charno].Nstructs =	combi();
273*31889Sdenise 	dbprintf("The next offset is %ld\n", offset);
274*31889Sdenise 	dbprintf("@ End of character data (%d)\n", charno);
275*31889Sdenise }
276*31889Sdenise 
277*31889Sdenise 
278*31889Sdenise /*
279*31889Sdenise  * huffdecode
280*31889Sdenise  *
281*31889Sdenise  * returns the runlength of the Character Generation Data
282*31889Sdenise  * using huffman decode table huff.
283*31889Sdenise  */
284*31889Sdenise 
huffdecode(huff)285*31889Sdenise huffdecode(huff)
286*31889Sdenise Word *huff;
287*31889Sdenise {
288*31889Sdenise 	register Word data = 0;
289*31889Sdenise 	register tmp;
290*31889Sdenise 	register int suffix;
291*31889Sdenise 
292*31889Sdenise 	for(EVER) {
293*31889Sdenise 		switch(data & OPCODE) {
294*31889Sdenise 			case FINAL:
295*31889Sdenise 				if(data == 0) {
296*31889Sdenise 					tmp = (*huff | getbit(0)) & ADDRS;
297*31889Sdenise 					data = *(huff + tmp);
298*31889Sdenise 					if(data == 0 )
299*31889Sdenise 						return(0);
300*31889Sdenise 				} else {
301*31889Sdenise 					tmp = data & ~FINAL;
302*31889Sdenise 					return(tmp);
303*31889Sdenise 				}
304*31889Sdenise 				break;
305*31889Sdenise 			case POINT:
306*31889Sdenise 				tmp =  (data | getbit(0)) & ADDRS;
307*31889Sdenise 				data = *(huff + tmp);
308*31889Sdenise 				break;
309*31889Sdenise 			case SUFFIX:
310*31889Sdenise 				tmp = data & SUFDAT;
311*31889Sdenise 				suffix = getnbits(tmp);
312*31889Sdenise 				if(!suffix)
313*31889Sdenise 					eoc++;
314*31889Sdenise 				return(suffix);
315*31889Sdenise 			default:
316*31889Sdenise 				error("Unknown opcode %#o\n", data);
317*31889Sdenise 		}
318*31889Sdenise 	}
319*31889Sdenise }
320*31889Sdenise 
321*31889Sdenise 
322*31889Sdenise /*
323*31889Sdenise  * get the value of n bits from the gcd
324*31889Sdenise  */
325*31889Sdenise 
getnbits(n)326*31889Sdenise getnbits(n)
327*31889Sdenise int n;
328*31889Sdenise {
329*31889Sdenise 	register int i;
330*31889Sdenise 	register int j;
331*31889Sdenise 	unsigned int value = 0;
332*31889Sdenise 
333*31889Sdenise 	for(i = n; i > 0; i-- ) {
334*31889Sdenise 		j = getbit(0);
335*31889Sdenise 		value = (value << 1) | j;
336*31889Sdenise 		if( i > sizeof(value) * 8)
337*31889Sdenise 			error("Overflow in getnbits(%d)\n", i);
338*31889Sdenise 	}
339*31889Sdenise 	return(value);
340*31889Sdenise }
341*31889Sdenise 
342*31889Sdenise 
343*31889Sdenise /*
344*31889Sdenise  * return a bit from the character generation data
345*31889Sdenise  *
346*31889Sdenise  * initialise when argument is set
347*31889Sdenise  */
348*31889Sdenise 
getbit(init)349*31889Sdenise getbit(init)
350*31889Sdenise int init;
351*31889Sdenise {
352*31889Sdenise 	static bitno;
353*31889Sdenise 	static unsigned int mask;
354*31889Sdenise 	static unsigned int n;
355*31889Sdenise 	register int bit;
356*31889Sdenise 	register int k;
357*31889Sdenise 
358*31889Sdenise 	if(init) {
359*31889Sdenise 		bitno = 1;
360*31889Sdenise 		if((fd = fopen(filename, "r")) == NULL )
361*31889Sdenise 			error("Cannot open %s", filename);
362*31889Sdenise 		return 0;
363*31889Sdenise 	} else {
364*31889Sdenise 		if( (bitno - 1) % 16 == 0) {
365*31889Sdenise 			bitno = 1;
366*31889Sdenise 			if(( k = fread( (char *)&n, sizeof(Word), 1, fd)) != 1)
367*31889Sdenise 				error("Read error %d", k);
368*31889Sdenise 			mask = BITMASK;
369*31889Sdenise 		}
370*31889Sdenise 	}
371*31889Sdenise 
372*31889Sdenise 	bit = n & mask;
373*31889Sdenise 	bitno++;
374*31889Sdenise 	mask = mask >> 1;
375*31889Sdenise 	if(bit) {
376*31889Sdenise 		return(1);
377*31889Sdenise 	} else {
378*31889Sdenise 		return(0);
379*31889Sdenise 	}
380*31889Sdenise }
381*31889Sdenise 
382*31889Sdenise 
383*31889Sdenise /*
384*31889Sdenise  * predict:
385*31889Sdenise  * predicts the dot on position x, y, over a runlength r.
386*31889Sdenise  * if 3th argument is set, don't generate exception point.
387*31889Sdenise  */
388*31889Sdenise 
389*31889Sdenise #define P8192	020000
390*31889Sdenise #define P4096	010000
391*31889Sdenise #define P2048	004000
392*31889Sdenise #define P1024	002000
393*31889Sdenise #define P0512	001000
394*31889Sdenise #define P0256	000400
395*31889Sdenise #define P0128	000200
396*31889Sdenise #define P0064	000100
397*31889Sdenise #define P0032	000040
398*31889Sdenise #define P0016	000020
399*31889Sdenise #define P0008	000010
400*31889Sdenise #define P0004	000004
401*31889Sdenise #define P0002	000002
402*31889Sdenise #define P0001	000001
403*31889Sdenise 
404*31889Sdenise #define	ON	1
405*31889Sdenise #define OFF	0
406*31889Sdenise 
407*31889Sdenise 
predict(y,r,e)408*31889Sdenise predict(y, r, e)
409*31889Sdenise register int y;
410*31889Sdenise int e, r;
411*31889Sdenise {
412*31889Sdenise 	unsigned int same = 0;
413*31889Sdenise 	unsigned register int mask = 0;
414*31889Sdenise 	unsigned register int state = 0;
415*31889Sdenise 	unsigned register int i;
416*31889Sdenise 	unsigned int prev = 0, new = 0, except = 0;
417*31889Sdenise 	extern unsigned int getmask();
418*31889Sdenise 
419*31889Sdenise 	i = r;
420*31889Sdenise 	do {
421*31889Sdenise 		state = except = prev = 0;
422*31889Sdenise 		mask = getmask(y);
423*31889Sdenise 		if(mask & P8192) {
424*31889Sdenise 			mask ^= 017777;
425*31889Sdenise 			prev = 1;
426*31889Sdenise 		}
427*31889Sdenise 		mask &= 017777;
428*31889Sdenise 		same = getdot(mask);
429*31889Sdenise 		if( i == 1 && e == 0) {	/* exception point */
430*31889Sdenise 			except = 1;
431*31889Sdenise 		}
432*31889Sdenise 		state = except;
433*31889Sdenise 		state |= prev << 1;
434*31889Sdenise 		state |= same << 2;
435*31889Sdenise 		switch(state & 07) {
436*31889Sdenise 			case 0:
437*31889Sdenise 			case 3:
438*31889Sdenise 			case 5:
439*31889Sdenise 			case 6:
440*31889Sdenise 				new = ON;
441*31889Sdenise 				break;
442*31889Sdenise 			case 1:
443*31889Sdenise 			case 2:
444*31889Sdenise 			case 4:
445*31889Sdenise 			case 7:
446*31889Sdenise 				new = OFF;
447*31889Sdenise 				break;
448*31889Sdenise 			default:
449*31889Sdenise 				error("Unexpected state %#o\n", state);
450*31889Sdenise 		}
451*31889Sdenise 		storedot( new, y );
452*31889Sdenise 		y++;
453*31889Sdenise 	} while (--i);
454*31889Sdenise }
455*31889Sdenise 
456*31889Sdenise /*
457*31889Sdenise  * find wether the dot should be the same or not
458*31889Sdenise  */
459*31889Sdenise 
460*31889Sdenise #define PMASK	017774
461*31889Sdenise #define TWOBIT	03
462*31889Sdenise 
463*31889Sdenise 
getdot(value)464*31889Sdenise getdot(value)
465*31889Sdenise unsigned int value;
466*31889Sdenise {
467*31889Sdenise 	register int tmp, i, j, k;
468*31889Sdenise 
469*31889Sdenise 	i = (value & PMASK) >> 2;
470*31889Sdenise 	j = value & TWOBIT;
471*31889Sdenise 	if(i > sizeof(Ptable))
472*31889Sdenise 		error("Prom adressing error");
473*31889Sdenise 
474*31889Sdenise 	tmp = Ptable[i];
475*31889Sdenise 	k = (tmp >> j) & 1;
476*31889Sdenise 	return k;
477*31889Sdenise }
478*31889Sdenise 
479*31889Sdenise 
480*31889Sdenise /*
481*31889Sdenise  * store point in current working area
482*31889Sdenise  */
483*31889Sdenise 
storedot(dot,y)484*31889Sdenise storedot( dot, y)
485*31889Sdenise register unsigned int dot;
486*31889Sdenise register int y;
487*31889Sdenise {
488*31889Sdenise 	if(y > Lmax + 2 + Y )
489*31889Sdenise 		error("Out of range in store dot, y = %d", y);
490*31889Sdenise 
491*31889Sdenise 	if(y == endline -1)
492*31889Sdenise 		return;
493*31889Sdenise 	sl0[y] = dot;
494*31889Sdenise }
495*31889Sdenise 
496*31889Sdenise 
497*31889Sdenise /*
498*31889Sdenise  * construct the predict mask for position x, y
499*31889Sdenise  */
500*31889Sdenise 
501*31889Sdenise unsigned int
getmask(y)502*31889Sdenise getmask(y)
503*31889Sdenise register int y;
504*31889Sdenise {
505*31889Sdenise 	register unsigned int mask = 0;
506*31889Sdenise 
507*31889Sdenise 	if( y < 3 || y > 1029)
508*31889Sdenise 		error("Out of range in getmask, y = %d\n", y);
509*31889Sdenise 
510*31889Sdenise 	if( sl3[y+2] )		/* PROM 1    */
511*31889Sdenise 		mask |= P0001;
512*31889Sdenise 	if( sl3[y+1] )
513*31889Sdenise 		mask |= P0002;
514*31889Sdenise 	if( sl3[y-1] )		/* PROM 4    */
515*31889Sdenise 		mask |= P0004;
516*31889Sdenise 	if( sl3[y-2] )		/* PROM 8    */
517*31889Sdenise 		mask |= P0008;
518*31889Sdenise 	if( sl2[y+3] )		/* PROM 16   */
519*31889Sdenise 		mask |= P0016;
520*31889Sdenise 	if( sl2[y+1] )		/* PROM 32   */
521*31889Sdenise 		mask |= P0032;
522*31889Sdenise 	if( sl2[y-1] )		/* PROM 64   */
523*31889Sdenise 		mask |= P0064;
524*31889Sdenise 	if( sl2[y-3] )		/* PROM 128  */
525*31889Sdenise 		mask |= P0128;
526*31889Sdenise 	if( sl1[y+2] )		/* PROM 256  */
527*31889Sdenise 		mask |= P0256;
528*31889Sdenise 	if( sl1[y+1] )		/* PROM 512  */
529*31889Sdenise 		mask |= P0512;
530*31889Sdenise 	if( sl1[ y ] )		/* PROM 1024 */
531*31889Sdenise 		mask |= P1024;
532*31889Sdenise 	if( sl1[y-1] )		/* PROM 2048 */
533*31889Sdenise 		mask |= P2048;
534*31889Sdenise 	if( sl1[y-3] )		/* PROM 4096 */
535*31889Sdenise 		mask |= P4096;
536*31889Sdenise 	if( sl0[y-1] )		/* PROM 8192 */
537*31889Sdenise 		mask |= P8192;
538*31889Sdenise 	return(mask);
539*31889Sdenise }
540*31889Sdenise 
541*31889Sdenise 
542*31889Sdenise /*
543*31889Sdenise  * swap the scan line buffers
544*31889Sdenise  */
545*31889Sdenise 
swapscanp()546*31889Sdenise swapscanp()
547*31889Sdenise {
548*31889Sdenise 	register Byte *sav;
549*31889Sdenise 
550*31889Sdenise 	/*
551*31889Sdenise 	 * swap the buffers
552*31889Sdenise 	 */
553*31889Sdenise 	sav = sl3;
554*31889Sdenise 	sl3 = sl2;
555*31889Sdenise 	sl2 = sl1;
556*31889Sdenise 	sl1 = sl0;
557*31889Sdenise 	sl0 = sav;
558*31889Sdenise 
559*31889Sdenise }
560*31889Sdenise 
561*31889Sdenise 
cleanup()562*31889Sdenise cleanup()
563*31889Sdenise {
564*31889Sdenise 	register int i;
565*31889Sdenise 	register int j;
566*31889Sdenise 
567*31889Sdenise 	for( i = 0; i < 1030; i++)
568*31889Sdenise 		a[i] = b[i] = c[i] = d[i] = 0;
569*31889Sdenise 	sl0 = &a[3];
570*31889Sdenise 	sl1 = &b[3];
571*31889Sdenise 	sl2 = &c[3];
572*31889Sdenise 	sl3 = &d[3];
573*31889Sdenise 	for( i = 0; i < MAXnat; i++)
574*31889Sdenise 		for( j = 0; j < MAXnat; j++) {
575*31889Sdenise 			newbitmap[j][i] = 0;
576*31889Sdenise 			sqmap[j][i] = 0;
577*31889Sdenise 			prmap[j][i] = 0;
578*31889Sdenise 			uline[j] = 0;
579*31889Sdenise 		}
580*31889Sdenise 	for( i = 0; i < MAXnat; i++)
581*31889Sdenise 		for (j = 0; j < MAX; j++)
582*31889Sdenise 			bitmap[j][i] = 0;
583*31889Sdenise 	eoc = 0;
584*31889Sdenise 	(void) fclose(fd);
585*31889Sdenise }
586*31889Sdenise 
587*31889Sdenise 
588*31889Sdenise /*
589*31889Sdenise  * store the curent scan line in the bitmap
590*31889Sdenise  *
591*31889Sdenise  * bit clumsy, we could just as well dump everyscan line each time
592*31889Sdenise  * but, as said before, we don't know what to do with the bitmap...
593*31889Sdenise  *
594*31889Sdenise  */
595*31889Sdenise 
storescanline(x,y,toy)596*31889Sdenise storescanline(x, y, toy)
597*31889Sdenise register int x, y, toy;
598*31889Sdenise {
599*31889Sdenise 	register int m, n, i;
600*31889Sdenise 
601*31889Sdenise 	m = x / 8;
602*31889Sdenise 	n = x % 8;
603*31889Sdenise 	if(m > MAX)
604*31889Sdenise 		error("bit map overflow for x (%d)\n", m);
605*31889Sdenise 
606*31889Sdenise 	if(toy >= MAXnat)
607*31889Sdenise 		error("Bitmap overflow");
608*31889Sdenise 	for( i = y; i < toy; i++)
609*31889Sdenise 		if(sl0[i])
610*31889Sdenise 			bitmap[m][i] |= (1 << n);
611*31889Sdenise }
612*31889Sdenise 
613*31889Sdenise short width, height;
614*31889Sdenise 
615*31889Sdenise #define For_v for(v=0; v < height; v++)
616*31889Sdenise #define For_h for(h=0; h < width; h++)
617*31889Sdenise 
618*31889Sdenise 
619*31889Sdenise /*
620*31889Sdenise  * print the bit map
621*31889Sdenise  */
622*31889Sdenise 
setbitmap(fromx,fromy,tox,toy)623*31889Sdenise setbitmap(fromx, fromy, tox, toy)
624*31889Sdenise int fromx, fromy, tox, toy;
625*31889Sdenise {
626*31889Sdenise 	register int m, n;
627*31889Sdenise 	register int x, y;
628*31889Sdenise 	nat v, h;
629*31889Sdenise 
630*31889Sdenise 	width = tox - fromx;
631*31889Sdenise 	height = toy - fromy;
632*31889Sdenise 	if (width > MAXnat || height > MAXnat) {
633*31889Sdenise 		error("*** X or Y is too large (%d %d)\n", width, height);
634*31889Sdenise 	}
635*31889Sdenise 
636*31889Sdenise 	dbprintf("# Rectangle map of character %s\n", filename);
637*31889Sdenise 	dbprintf("%% X %d Y %d\n", width, height);
638*31889Sdenise 
639*31889Sdenise 	for(v= 0, y = toy - 1; y >= fromy; v++, y--) {
640*31889Sdenise 		for( h=0, x = fromx; x < tox; h++, x++) {
641*31889Sdenise 			m = x / 8;
642*31889Sdenise 			n = x % 8;
643*31889Sdenise 			if((bitmap[m][y]  >> n ) & 1)
644*31889Sdenise 				newbitmap[v][h] = 1;
645*31889Sdenise 			else
646*31889Sdenise 				newbitmap[v][h] = 0;
647*31889Sdenise 		}
648*31889Sdenise 	}
649*31889Sdenise }
650*31889Sdenise 
651*31889Sdenise 
652*31889Sdenise 
maxsq()653*31889Sdenise maxsq()
654*31889Sdenise {
655*31889Sdenise 	register nat v, h, m;
656*31889Sdenise 	nat uleft, up, left;
657*31889Sdenise 	For_h
658*31889Sdenise 		uline[h]= 0;
659*31889Sdenise 	For_v {
660*31889Sdenise 		uleft= left= 0;
661*31889Sdenise 		For_h {
662*31889Sdenise 			up= uline[h];
663*31889Sdenise 			if (newbitmap[v][h]) {
664*31889Sdenise 				m= uleft;
665*31889Sdenise 				if (up < m) m= up;
666*31889Sdenise 				if (left < m) m= left;
667*31889Sdenise 				sqmap[v][h]= ++m;
668*31889Sdenise 			} else
669*31889Sdenise 				sqmap[v][h]= m= 0;
670*31889Sdenise 			uleft= up;
671*31889Sdenise 			uline[h]= left= m;
672*31889Sdenise 		}
673*31889Sdenise 		sqmap[v][h]= 0;
674*31889Sdenise 	}
675*31889Sdenise }
676*31889Sdenise 
677*31889Sdenise 
prune()678*31889Sdenise prune()
679*31889Sdenise {
680*31889Sdenise 	register nat v, h, m;
681*31889Sdenise 	nat vv, hh;
682*31889Sdenise 	For_v {
683*31889Sdenise 		For_h {
684*31889Sdenise 			m= sqmap[v][h];
685*31889Sdenise 			for (vv= v; m && vv <= v+1 && vv < height; vv++)
686*31889Sdenise 			for (hh= h; m && hh <= h+1 && hh < width; hh++)
687*31889Sdenise 				if (sqmap[vv][hh] > m) m= 0;
688*31889Sdenise 			prmap[v][h]= m;
689*31889Sdenise 		}
690*31889Sdenise 	}
691*31889Sdenise }
692*31889Sdenise 
693*31889Sdenise 
combi()694*31889Sdenise combi()
695*31889Sdenise {
696*31889Sdenise 	register nat v, h, m, p=0, hh;
697*31889Sdenise 	int rects = 0;	/* track number of structures written */
698*31889Sdenise 
699*31889Sdenise 	For_v {
700*31889Sdenise 		p=m= 0;
701*31889Sdenise 		for (h= 0; h <= width; h++) {
702*31889Sdenise 			if (h == width || prmap[v][h] != m) {
703*31889Sdenise 				/* Don't pay attention to "singletons" (h-p == 1) */
704*31889Sdenise 				if (m && h-p > 1) {
705*31889Sdenise 					rects++;
706*31889Sdenise 					rect.yO = v-m+1;
707*31889Sdenise 					rect.y = m;
708*31889Sdenise 					rect.xO = p-m+1;
709*31889Sdenise 					rect.x = h-1-p+m;
710*31889Sdenise 					oput(rect);
711*31889Sdenise 					dbprintf("> V@%3d|%3d*H@%3d|%3d\n",  v-m+1, m, p-m+1, h-1-p+m);
712*31889Sdenise 					/* Mark squares as accounted for */
713*31889Sdenise 					for (hh= p; hh < h; hh++) sqmap[v][hh]= 0;
714*31889Sdenise 				}
715*31889Sdenise 				if (h < width) m= prmap[v][p= h];
716*31889Sdenise 			}
717*31889Sdenise 		}
718*31889Sdenise 	}
719*31889Sdenise 	for (h = 0; h <= width; h++) {
720*31889Sdenise 		p=m= 0;
721*31889Sdenise 		for (v= 0; v <= height; v++) {
722*31889Sdenise 			if (v == height || prmap[v][h] != m) {
723*31889Sdenise 				/* Pay attention to unaccounted-for "singletons" */
724*31889Sdenise 				if (m && (v-p > 1 || sqmap[v-1][h])) {
725*31889Sdenise 					rects++;
726*31889Sdenise 					rect.yO = p-m+1;
727*31889Sdenise 					rect.y = v-1-p+m;
728*31889Sdenise 					rect.xO = h-m+1;
729*31889Sdenise 					rect.x = m;
730*31889Sdenise 					oput(rect);
731*31889Sdenise 					dbprintf("> V@%3d|%3d*H@%3d|%3d\n", p-m+1, v-1-p+m, h-m+1, m);
732*31889Sdenise 				}
733*31889Sdenise 				if (v < height) m= prmap[p= v][h];
734*31889Sdenise 			}
735*31889Sdenise 		}
736*31889Sdenise 	}
737*31889Sdenise 	dbprintf("<\n");
738*31889Sdenise 	dbprintf("The Nstructs should be %d\n", rects);
739*31889Sdenise 	return(rects);
740*31889Sdenise }
741*31889Sdenise 
headit()742*31889Sdenise headit()
743*31889Sdenise {
744*31889Sdenise 	if(lseek(fdo, (long)0, 0) == -1)
745*31889Sdenise 		error("seek error in head routine");
746*31889Sdenise 	if(write(fdo, (char *) &head, sizeof(struct Header)) != sizeof(struct Header))
747*31889Sdenise 		error("write error in head routine");
748*31889Sdenise }
setchars()749*31889Sdenise setchars()
750*31889Sdenise {
751*31889Sdenise 	if(lseek(fdo, (long)(sizeof(struct Header)), 0) == -1)
752*31889Sdenise 		error("seek error in setchars routine");
753*31889Sdenise 	if (write(fdo, (char *)Char, Charmax * sizeof(struct Chars)) != Charmax * sizeof(struct Chars))
754*31889Sdenise 		error("Write error in setchars routine");
755*31889Sdenise }
756*31889Sdenise 
757*31889Sdenise 
758*31889Sdenise /* output a rect struct */
759*31889Sdenise 
760*31889Sdenise oput(r)
761*31889Sdenise struct Rect r;
762*31889Sdenise {
763*31889Sdenise 	*curp++ = r;
764*31889Sdenise 	if(curp > eob) {
765*31889Sdenise 		flusho();
766*31889Sdenise 		curp = bob;
767*31889Sdenise 	}
768*31889Sdenise 	offset += sizeof(struct Rect);
769*31889Sdenise }
770*31889Sdenise 
771*31889Sdenise /* flush the buffer holding the rectangles */
772*31889Sdenise 
flusho()773*31889Sdenise flusho()
774*31889Sdenise {
775*31889Sdenise 
776*31889Sdenise 	if ( write(fdo, (char *)bob, (int)(curp - bob) * sizeof(struct Rect)) !=
777*31889Sdenise 			(int)(curp - bob)*sizeof(struct Rect))
778*31889Sdenise 		error("Write error in flusho routine");
779*31889Sdenise }
780*31889Sdenise 
setoffset()781*31889Sdenise setoffset()
782*31889Sdenise {
783*31889Sdenise 	offset = sizeof(struct Header) + Charmax * sizeof(struct Chars);
784*31889Sdenise }
785