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