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