xref: /csrg-svn/old/vpr/vtools/fcvt.c (revision 13944)
1*13944Ssam #ifndef lint
2*13944Ssam static char sccsid[] = "@(#)fcvt.c	4.2 (Berkeley) 07/16/83";
3*13944Ssam #endif
4*13944Ssam 
512084Sralph /*
612084Sralph  * Convert from the SAIL font format to the Unix font format.
712084Sralph  * Usage: fcvt sailfile unixfile
812084Sralph  */
912084Sralph 
1012084Sralph #include <stdio.h>
1112084Sralph #include <vfont.h>
1212084Sralph 
1312084Sralph int	sws;			/* sail word size in 36 bit words */
1412084Sralph char	b[40000], u[2000];
1512084Sralph long	left(), right();
1612084Sralph 
1712084Sralph struct header vheader;
1812084Sralph struct dispatch disptable[256];
1912084Sralph 
2012084Sralph long rightbits[19] = {
2112084Sralph 	0,	1,	03,	07,	017,	037,
2212084Sralph 	077,	0177,	0377,	0777,	01777,	03777,
2312084Sralph 	07777,	017777,	037777,	077777,	0177777,0377777,0777777
2412084Sralph };
2512084Sralph 
2612084Sralph main(argc, argv)
2712084Sralph 	int argc;
2812084Sralph 	char *argv[];
2912084Sralph {
3012084Sralph 	int infd = open(argv[1], 0);
3112084Sralph 	int outfd = creat(argv[2], 0666);
3212084Sralph 	int n;
3312084Sralph 	long lh, rh;
3412084Sralph 	int base, nb, ncol, nleft, r, i;
3512084Sralph 	int c, p;
3612084Sralph 	/* Sail counters and things */
3712084Sralph 	int height, maxwidth, baseline;
3812084Sralph 	int charwidth, rastwidth, charcode, wordcount;
3912084Sralph 	int leftkern, rowsfromtop, datarowcount;
4012084Sralph 	/* Unix counters and things */
4112084Sralph 	int rastrows, rastcols;
4212084Sralph 	int curaddr;
4312084Sralph 	int packed;	/* true if sail packed format for this glyph */
4412084Sralph 	int nperword;
4512084Sralph 
4612084Sralph 	if (infd < 0 || outfd < 0) {
4712084Sralph 		printf("Usage: fcvt sailfile unixfile\n");
4812084Sralph 		exit(1);
4912084Sralph 	}
5012084Sralph 	n = read(infd, b, sizeof b);
5112084Sralph 	sws = 2 * n / 9;
5212084Sralph 	if (n == sizeof b) {
5312084Sralph 		printf("Font larger than %d bytes - recompile me\n", n);
5412084Sralph 		exit(1);
5512084Sralph 	}
5612084Sralph 	close(infd);
5712084Sralph 
5812084Sralph 	height = right(0201);
5912084Sralph 	maxwidth = right(0202);
6012084Sralph 	baseline = right(0203);
6112084Sralph 
6212084Sralph 	vheader.magic = 0436;
6312084Sralph 	/* size gets done later */
6412084Sralph 	vheader.maxx = height;
6512084Sralph 	vheader.maxy = maxwidth;
6612084Sralph 	/* I don't know what xtnd would map to */
6712084Sralph 
6812084Sralph 	lseek(outfd, (long) sizeof vheader + sizeof disptable, 0);
6912084Sralph 	curaddr = 0;
7012084Sralph 
7112084Sralph 	/* Look at each char */
7212084Sralph 	for (c=0; c<0200; c++) {
7312084Sralph 		/* Find Sail info */
7412084Sralph 		base = right(c);
7512084Sralph 		if (base == 0)
7612084Sralph 			continue;
7712084Sralph 		charwidth = left(c);
7812084Sralph 		rastwidth = (left(base) >> 9) & 0777;
7912084Sralph 		if (rastwidth == 0)
8012084Sralph 			rastwidth = charwidth;
8112084Sralph 		charcode = left(base) & 0777;
8212084Sralph 		if (charcode != c)
8312084Sralph 			printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c);
8412084Sralph 		wordcount = right(base);
8512084Sralph 		if (base+wordcount > sws) {
8612084Sralph 			printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c);
8712084Sralph 			continue;
8812084Sralph 		}
8912084Sralph 		leftkern = (left(base+1) >> 9) & 0777;
9012084Sralph 		rowsfromtop = left(base+1) & 0777;
9112084Sralph 		datarowcount = right(base+1);
9212084Sralph 
9312084Sralph 		rastrows = datarowcount;
9412084Sralph 		rastcols = (rastwidth + 35) / 36 * 36;
9512084Sralph 
9612084Sralph 		/* Unix disptable stuff */
9712084Sralph 		disptable[c].addr = curaddr;
9812084Sralph 		nb = rastrows * ((rastcols + 7) >> 3);
9912084Sralph 		disptable[c].nbytes = nb;
10012084Sralph 		curaddr += nb;
10112084Sralph 		disptable[c].left = leftkern;
10212084Sralph 		disptable[c].right = rastcols - leftkern;
10312084Sralph 		disptable[c].up = baseline - rowsfromtop;
10412084Sralph 		disptable[c].down = rastrows - disptable[c].up;
10512084Sralph 		disptable[c].width = charwidth;
10612084Sralph 		packed = (datarowcount > wordcount);
10712084Sralph 		nperword = 36 / rastwidth;
10812084Sralph 
10912084Sralph 		/* Now get the raster rows themselves */
11012084Sralph 		p = 0;
11112084Sralph 		ncol = rastcols / 36;
11212084Sralph 		nleft = ((rastwidth-1) % 36 + 1);
11312084Sralph 		base += 2;
11412084Sralph 		for (r=0; r<rastrows; r++) {
11512084Sralph 			if (!packed) {
11612084Sralph 				for (i=0; i<ncol; i++) {
11712084Sralph 					lh = left(base); rh = right(base++);
11812084Sralph 					/* compensate for garbage in SAIL fonts */
11912084Sralph 					if (i == ncol-1) {
12012084Sralph 						if (nleft <= 18) {
12112084Sralph 							rh = 0;
12212084Sralph 							lh &= ~rightbits[18-nleft];
12312084Sralph 						} else
12412084Sralph 							rh &= ~rightbits[36-nleft];
12512084Sralph 					}
12612084Sralph 					if (i%2) {
12712084Sralph 						u[p-1] |= (lh>>14) & 017;
12812084Sralph 						u[p++] = lh >> 6;
12912084Sralph 						u[p++] = ((lh&077)<<2) | ((rh>>16)&03);
13012084Sralph 						u[p++] = rh >> 8;
13112084Sralph 						u[p++] = rh;
13212084Sralph 					} else {
13312084Sralph 						u[p++] = lh >> 10;
13412084Sralph 						u[p++] = lh >> 2;
13512084Sralph 						u[p++] = ((lh&03)<<6) | (rh>>12);
13612084Sralph 						u[p++] = rh >> 4;
13712084Sralph 						u[p++] = (rh & 017) << 4;
13812084Sralph 					}
13912084Sralph 				}
14012084Sralph 			} else {
14112084Sralph 				put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p);
14212084Sralph 				p += 5;	/* 5 8 bit bytes per 36 bit word */
14312084Sralph 			}
14412084Sralph 		}
14512084Sralph 		write(outfd, u, p);
14612084Sralph 	}
14712084Sralph 	lseek(outfd, 0, 0);
14812084Sralph 	vheader.size = curaddr;
14912084Sralph 	write(outfd, &vheader, sizeof vheader);
15012084Sralph 	write(outfd, disptable, sizeof disptable);
15112084Sralph 	close(outfd);
15212084Sralph 	exit(0);
15312084Sralph }
15412084Sralph 
15512084Sralph /*
15612084Sralph  * put a pdp-10 style variable size byte into 8 bit Unix bytes starting
15712084Sralph  * at location dest.  The byte is bytesize bits, and is the bytenumth byte
15812084Sralph  * in the 36 bit word (lh,,rh).
15912084Sralph  */
16012084Sralph put(bytenum, bytesize, lh, rh, dest)
16112084Sralph 	int bytenum, bytesize;
16212084Sralph 	long lh, rh;
16312084Sralph 	char *dest;
16412084Sralph {
16512084Sralph 	register int i;
16612084Sralph 
16712084Sralph 	for (i=0; i<5; i++)
16812084Sralph 		dest[i] = 0;
16912084Sralph 	for (i=0; i<bytenum; i++) {
17012084Sralph 		lh <<= bytesize;
17112084Sralph 		lh |= (rh >> 18-bytesize) & rightbits[bytesize];
17212084Sralph 		rh <<= bytesize;
17312084Sralph 	}
17412084Sralph 	lh &= ~rightbits[18-bytesize];
17512084Sralph 	/* We now have the byte we want left justified in lh */
17612084Sralph 	lh <<= 14;
17712084Sralph 	/* lh is now the byte we want, left justified in 32 bit word */
17812084Sralph 	for (i=0; i<bytesize; i += 8) {
17912084Sralph 		*dest++ = (lh >> 24) & 0377;
18012084Sralph 		lh <<= 8;
18112084Sralph 	}
18212084Sralph }
18312084Sralph 
18412084Sralph /*
18512084Sralph  * Return the left half (18 bits) of pdp-10 word p.
18612084Sralph  */
18712084Sralph long
18812084Sralph left(p)
18912084Sralph 	int p;
19012084Sralph {
19112084Sralph 	register int lp, odd;
19212084Sralph 	register long retval;
19312084Sralph 
19412084Sralph 	odd = p%2;
19512084Sralph 	lp = 9*p/2;
19612084Sralph 	if (p >= sws) {
19712084Sralph 		return(0);
19812084Sralph 	}
19912084Sralph 	if (odd) {
20012084Sralph 		retval  = (b[lp++] & 0017) << 14;
20112084Sralph 		retval |= (b[lp++] & 0377) << 6;
20212084Sralph 		retval |= (b[lp] >> 2) & 63;
20312084Sralph 	} else {
20412084Sralph 		retval  = (b[lp++] & 0377) << 10;
20512084Sralph 		retval |= (b[lp++] & 0377) << 2;
20612084Sralph 		retval |= (b[lp] >> 6) & 3;
20712084Sralph 	}
20812084Sralph 	return retval;
20912084Sralph }
21012084Sralph 
21112084Sralph /*
21212084Sralph  * Return the right half of 36 bit word #p.
21312084Sralph  */
21412084Sralph long
21512084Sralph right(p)
21612084Sralph 	int p;
21712084Sralph {
21812084Sralph 	register int lp, odd;
21912084Sralph 	register long retval;
22012084Sralph 
22112084Sralph 	odd = p%2;
22212084Sralph 	lp = 9*p/2 + 2;
22312084Sralph 	if (p >= sws) {
22412084Sralph 		return(0);
22512084Sralph 	}
22612084Sralph 	if (odd) {
22712084Sralph 		retval  = (b[lp++] & 0003) << 16;
22812084Sralph 		retval |= (b[lp++] & 0377) << 8;
22912084Sralph 		retval |= (b[lp]   & 0377);
23012084Sralph 	} else {
23112084Sralph 		retval  = (b[lp++] & 0077) << 12;
23212084Sralph 		retval |= (b[lp++] & 0377) << 4;
23312084Sralph 		retval |= (b[lp] >> 4) & 017;
23412084Sralph 	}
23512084Sralph 	return retval;
23612084Sralph }
237