xref: /original-bsd/old/vpr/vtools/fcvt.c (revision d85f30f4)
1*d85f30f4Sdist /*
2*d85f30f4Sdist  * Copyright (c) 1983 Regents of the University of California.
3*d85f30f4Sdist  * All rights reserved.  The Berkeley software License Agreement
4*d85f30f4Sdist  * specifies the terms and conditions for redistribution.
5*d85f30f4Sdist  */
6*d85f30f4Sdist 
726d9b545Ssam #ifndef lint
8*d85f30f4Sdist static char sccsid[] = "@(#)fcvt.c	5.1 (Berkeley) 05/15/85";
9*d85f30f4Sdist #endif not lint
1026d9b545Ssam 
1162c4157cSralph /*
1262c4157cSralph  * Convert from the SAIL font format to the Unix font format.
1362c4157cSralph  * Usage: fcvt sailfile unixfile
1462c4157cSralph  */
1562c4157cSralph 
1662c4157cSralph #include <stdio.h>
1762c4157cSralph #include <vfont.h>
1862c4157cSralph 
1962c4157cSralph int	sws;			/* sail word size in 36 bit words */
2062c4157cSralph char	b[40000], u[2000];
2162c4157cSralph long	left(), right();
2262c4157cSralph 
2362c4157cSralph struct header vheader;
2462c4157cSralph struct dispatch disptable[256];
2562c4157cSralph 
2662c4157cSralph long rightbits[19] = {
2762c4157cSralph 	0,	1,	03,	07,	017,	037,
2862c4157cSralph 	077,	0177,	0377,	0777,	01777,	03777,
2962c4157cSralph 	07777,	017777,	037777,	077777,	0177777,0377777,0777777
3062c4157cSralph };
3162c4157cSralph 
main(argc,argv)3262c4157cSralph main(argc, argv)
3362c4157cSralph 	int argc;
3462c4157cSralph 	char *argv[];
3562c4157cSralph {
3662c4157cSralph 	int infd = open(argv[1], 0);
3762c4157cSralph 	int outfd = creat(argv[2], 0666);
3862c4157cSralph 	int n;
3962c4157cSralph 	long lh, rh;
4062c4157cSralph 	int base, nb, ncol, nleft, r, i;
4162c4157cSralph 	int c, p;
4262c4157cSralph 	/* Sail counters and things */
4362c4157cSralph 	int height, maxwidth, baseline;
4462c4157cSralph 	int charwidth, rastwidth, charcode, wordcount;
4562c4157cSralph 	int leftkern, rowsfromtop, datarowcount;
4662c4157cSralph 	/* Unix counters and things */
4762c4157cSralph 	int rastrows, rastcols;
4862c4157cSralph 	int curaddr;
4962c4157cSralph 	int packed;	/* true if sail packed format for this glyph */
5062c4157cSralph 	int nperword;
5162c4157cSralph 
5262c4157cSralph 	if (infd < 0 || outfd < 0) {
5362c4157cSralph 		printf("Usage: fcvt sailfile unixfile\n");
5462c4157cSralph 		exit(1);
5562c4157cSralph 	}
5662c4157cSralph 	n = read(infd, b, sizeof b);
5762c4157cSralph 	sws = 2 * n / 9;
5862c4157cSralph 	if (n == sizeof b) {
5962c4157cSralph 		printf("Font larger than %d bytes - recompile me\n", n);
6062c4157cSralph 		exit(1);
6162c4157cSralph 	}
6262c4157cSralph 	close(infd);
6362c4157cSralph 
6462c4157cSralph 	height = right(0201);
6562c4157cSralph 	maxwidth = right(0202);
6662c4157cSralph 	baseline = right(0203);
6762c4157cSralph 
6862c4157cSralph 	vheader.magic = 0436;
6962c4157cSralph 	/* size gets done later */
7062c4157cSralph 	vheader.maxx = height;
7162c4157cSralph 	vheader.maxy = maxwidth;
7262c4157cSralph 	/* I don't know what xtnd would map to */
7362c4157cSralph 
7462c4157cSralph 	lseek(outfd, (long) sizeof vheader + sizeof disptable, 0);
7562c4157cSralph 	curaddr = 0;
7662c4157cSralph 
7762c4157cSralph 	/* Look at each char */
7862c4157cSralph 	for (c=0; c<0200; c++) {
7962c4157cSralph 		/* Find Sail info */
8062c4157cSralph 		base = right(c);
8162c4157cSralph 		if (base == 0)
8262c4157cSralph 			continue;
8362c4157cSralph 		charwidth = left(c);
8462c4157cSralph 		rastwidth = (left(base) >> 9) & 0777;
8562c4157cSralph 		if (rastwidth == 0)
8662c4157cSralph 			rastwidth = charwidth;
8762c4157cSralph 		charcode = left(base) & 0777;
8862c4157cSralph 		if (charcode != c)
8962c4157cSralph 			printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c);
9062c4157cSralph 		wordcount = right(base);
9162c4157cSralph 		if (base+wordcount > sws) {
9262c4157cSralph 			printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c);
9362c4157cSralph 			continue;
9462c4157cSralph 		}
9562c4157cSralph 		leftkern = (left(base+1) >> 9) & 0777;
9662c4157cSralph 		rowsfromtop = left(base+1) & 0777;
9762c4157cSralph 		datarowcount = right(base+1);
9862c4157cSralph 
9962c4157cSralph 		rastrows = datarowcount;
10062c4157cSralph 		rastcols = (rastwidth + 35) / 36 * 36;
10162c4157cSralph 
10262c4157cSralph 		/* Unix disptable stuff */
10362c4157cSralph 		disptable[c].addr = curaddr;
10462c4157cSralph 		nb = rastrows * ((rastcols + 7) >> 3);
10562c4157cSralph 		disptable[c].nbytes = nb;
10662c4157cSralph 		curaddr += nb;
10762c4157cSralph 		disptable[c].left = leftkern;
10862c4157cSralph 		disptable[c].right = rastcols - leftkern;
10962c4157cSralph 		disptable[c].up = baseline - rowsfromtop;
11062c4157cSralph 		disptable[c].down = rastrows - disptable[c].up;
11162c4157cSralph 		disptable[c].width = charwidth;
11262c4157cSralph 		packed = (datarowcount > wordcount);
11362c4157cSralph 		nperword = 36 / rastwidth;
11462c4157cSralph 
11562c4157cSralph 		/* Now get the raster rows themselves */
11662c4157cSralph 		p = 0;
11762c4157cSralph 		ncol = rastcols / 36;
11862c4157cSralph 		nleft = ((rastwidth-1) % 36 + 1);
11962c4157cSralph 		base += 2;
12062c4157cSralph 		for (r=0; r<rastrows; r++) {
12162c4157cSralph 			if (!packed) {
12262c4157cSralph 				for (i=0; i<ncol; i++) {
12362c4157cSralph 					lh = left(base); rh = right(base++);
12462c4157cSralph 					/* compensate for garbage in SAIL fonts */
12562c4157cSralph 					if (i == ncol-1) {
12662c4157cSralph 						if (nleft <= 18) {
12762c4157cSralph 							rh = 0;
12862c4157cSralph 							lh &= ~rightbits[18-nleft];
12962c4157cSralph 						} else
13062c4157cSralph 							rh &= ~rightbits[36-nleft];
13162c4157cSralph 					}
13262c4157cSralph 					if (i%2) {
13362c4157cSralph 						u[p-1] |= (lh>>14) & 017;
13462c4157cSralph 						u[p++] = lh >> 6;
13562c4157cSralph 						u[p++] = ((lh&077)<<2) | ((rh>>16)&03);
13662c4157cSralph 						u[p++] = rh >> 8;
13762c4157cSralph 						u[p++] = rh;
13862c4157cSralph 					} else {
13962c4157cSralph 						u[p++] = lh >> 10;
14062c4157cSralph 						u[p++] = lh >> 2;
14162c4157cSralph 						u[p++] = ((lh&03)<<6) | (rh>>12);
14262c4157cSralph 						u[p++] = rh >> 4;
14362c4157cSralph 						u[p++] = (rh & 017) << 4;
14462c4157cSralph 					}
14562c4157cSralph 				}
14662c4157cSralph 			} else {
14762c4157cSralph 				put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p);
14862c4157cSralph 				p += 5;	/* 5 8 bit bytes per 36 bit word */
14962c4157cSralph 			}
15062c4157cSralph 		}
15162c4157cSralph 		write(outfd, u, p);
15262c4157cSralph 	}
15362c4157cSralph 	lseek(outfd, 0, 0);
15462c4157cSralph 	vheader.size = curaddr;
15562c4157cSralph 	write(outfd, &vheader, sizeof vheader);
15662c4157cSralph 	write(outfd, disptable, sizeof disptable);
15762c4157cSralph 	close(outfd);
15862c4157cSralph 	exit(0);
15962c4157cSralph }
16062c4157cSralph 
16162c4157cSralph /*
16262c4157cSralph  * put a pdp-10 style variable size byte into 8 bit Unix bytes starting
16362c4157cSralph  * at location dest.  The byte is bytesize bits, and is the bytenumth byte
16462c4157cSralph  * in the 36 bit word (lh,,rh).
16562c4157cSralph  */
put(bytenum,bytesize,lh,rh,dest)16662c4157cSralph put(bytenum, bytesize, lh, rh, dest)
16762c4157cSralph 	int bytenum, bytesize;
16862c4157cSralph 	long lh, rh;
16962c4157cSralph 	char *dest;
17062c4157cSralph {
17162c4157cSralph 	register int i;
17262c4157cSralph 
17362c4157cSralph 	for (i=0; i<5; i++)
17462c4157cSralph 		dest[i] = 0;
17562c4157cSralph 	for (i=0; i<bytenum; i++) {
17662c4157cSralph 		lh <<= bytesize;
17762c4157cSralph 		lh |= (rh >> 18-bytesize) & rightbits[bytesize];
17862c4157cSralph 		rh <<= bytesize;
17962c4157cSralph 	}
18062c4157cSralph 	lh &= ~rightbits[18-bytesize];
18162c4157cSralph 	/* We now have the byte we want left justified in lh */
18262c4157cSralph 	lh <<= 14;
18362c4157cSralph 	/* lh is now the byte we want, left justified in 32 bit word */
18462c4157cSralph 	for (i=0; i<bytesize; i += 8) {
18562c4157cSralph 		*dest++ = (lh >> 24) & 0377;
18662c4157cSralph 		lh <<= 8;
18762c4157cSralph 	}
18862c4157cSralph }
18962c4157cSralph 
19062c4157cSralph /*
19162c4157cSralph  * Return the left half (18 bits) of pdp-10 word p.
19262c4157cSralph  */
19362c4157cSralph long
left(p)19462c4157cSralph left(p)
19562c4157cSralph 	int p;
19662c4157cSralph {
19762c4157cSralph 	register int lp, odd;
19862c4157cSralph 	register long retval;
19962c4157cSralph 
20062c4157cSralph 	odd = p%2;
20162c4157cSralph 	lp = 9*p/2;
20262c4157cSralph 	if (p >= sws) {
20362c4157cSralph 		return(0);
20462c4157cSralph 	}
20562c4157cSralph 	if (odd) {
20662c4157cSralph 		retval  = (b[lp++] & 0017) << 14;
20762c4157cSralph 		retval |= (b[lp++] & 0377) << 6;
20862c4157cSralph 		retval |= (b[lp] >> 2) & 63;
20962c4157cSralph 	} else {
21062c4157cSralph 		retval  = (b[lp++] & 0377) << 10;
21162c4157cSralph 		retval |= (b[lp++] & 0377) << 2;
21262c4157cSralph 		retval |= (b[lp] >> 6) & 3;
21362c4157cSralph 	}
21462c4157cSralph 	return retval;
21562c4157cSralph }
21662c4157cSralph 
21762c4157cSralph /*
21862c4157cSralph  * Return the right half of 36 bit word #p.
21962c4157cSralph  */
22062c4157cSralph long
right(p)22162c4157cSralph right(p)
22262c4157cSralph 	int p;
22362c4157cSralph {
22462c4157cSralph 	register int lp, odd;
22562c4157cSralph 	register long retval;
22662c4157cSralph 
22762c4157cSralph 	odd = p%2;
22862c4157cSralph 	lp = 9*p/2 + 2;
22962c4157cSralph 	if (p >= sws) {
23062c4157cSralph 		return(0);
23162c4157cSralph 	}
23262c4157cSralph 	if (odd) {
23362c4157cSralph 		retval  = (b[lp++] & 0003) << 16;
23462c4157cSralph 		retval |= (b[lp++] & 0377) << 8;
23562c4157cSralph 		retval |= (b[lp]   & 0377);
23662c4157cSralph 	} else {
23762c4157cSralph 		retval  = (b[lp++] & 0077) << 12;
23862c4157cSralph 		retval |= (b[lp++] & 0377) << 4;
23962c4157cSralph 		retval |= (b[lp] >> 4) & 017;
24062c4157cSralph 	}
24162c4157cSralph 	return retval;
24262c4157cSralph }
243