xref: /csrg-svn/old/vpr/vtools/fcvt.c (revision 12084)
1*12084Sralph /*	fcvt.c	4.1	83/04/28	*/
2*12084Sralph /*
3*12084Sralph  * Convert from the SAIL font format to the Unix font format.
4*12084Sralph  * Usage: fcvt sailfile unixfile
5*12084Sralph  */
6*12084Sralph 
7*12084Sralph #include <stdio.h>
8*12084Sralph #include <vfont.h>
9*12084Sralph 
10*12084Sralph int	sws;			/* sail word size in 36 bit words */
11*12084Sralph char	b[40000], u[2000];
12*12084Sralph long	left(), right();
13*12084Sralph 
14*12084Sralph struct header vheader;
15*12084Sralph struct dispatch disptable[256];
16*12084Sralph 
17*12084Sralph long rightbits[19] = {
18*12084Sralph 	0,	1,	03,	07,	017,	037,
19*12084Sralph 	077,	0177,	0377,	0777,	01777,	03777,
20*12084Sralph 	07777,	017777,	037777,	077777,	0177777,0377777,0777777
21*12084Sralph };
22*12084Sralph 
23*12084Sralph main(argc, argv)
24*12084Sralph 	int argc;
25*12084Sralph 	char *argv[];
26*12084Sralph {
27*12084Sralph 	int infd = open(argv[1], 0);
28*12084Sralph 	int outfd = creat(argv[2], 0666);
29*12084Sralph 	int n;
30*12084Sralph 	long lh, rh;
31*12084Sralph 	int base, nb, ncol, nleft, r, i;
32*12084Sralph 	int c, p;
33*12084Sralph 	/* Sail counters and things */
34*12084Sralph 	int height, maxwidth, baseline;
35*12084Sralph 	int charwidth, rastwidth, charcode, wordcount;
36*12084Sralph 	int leftkern, rowsfromtop, datarowcount;
37*12084Sralph 	/* Unix counters and things */
38*12084Sralph 	int rastrows, rastcols;
39*12084Sralph 	int curaddr;
40*12084Sralph 	int packed;	/* true if sail packed format for this glyph */
41*12084Sralph 	int nperword;
42*12084Sralph 
43*12084Sralph 	if (infd < 0 || outfd < 0) {
44*12084Sralph 		printf("Usage: fcvt sailfile unixfile\n");
45*12084Sralph 		exit(1);
46*12084Sralph 	}
47*12084Sralph 	n = read(infd, b, sizeof b);
48*12084Sralph 	sws = 2 * n / 9;
49*12084Sralph 	if (n == sizeof b) {
50*12084Sralph 		printf("Font larger than %d bytes - recompile me\n", n);
51*12084Sralph 		exit(1);
52*12084Sralph 	}
53*12084Sralph 	close(infd);
54*12084Sralph 
55*12084Sralph 	height = right(0201);
56*12084Sralph 	maxwidth = right(0202);
57*12084Sralph 	baseline = right(0203);
58*12084Sralph 
59*12084Sralph 	vheader.magic = 0436;
60*12084Sralph 	/* size gets done later */
61*12084Sralph 	vheader.maxx = height;
62*12084Sralph 	vheader.maxy = maxwidth;
63*12084Sralph 	/* I don't know what xtnd would map to */
64*12084Sralph 
65*12084Sralph 	lseek(outfd, (long) sizeof vheader + sizeof disptable, 0);
66*12084Sralph 	curaddr = 0;
67*12084Sralph 
68*12084Sralph 	/* Look at each char */
69*12084Sralph 	for (c=0; c<0200; c++) {
70*12084Sralph 		/* Find Sail info */
71*12084Sralph 		base = right(c);
72*12084Sralph 		if (base == 0)
73*12084Sralph 			continue;
74*12084Sralph 		charwidth = left(c);
75*12084Sralph 		rastwidth = (left(base) >> 9) & 0777;
76*12084Sralph 		if (rastwidth == 0)
77*12084Sralph 			rastwidth = charwidth;
78*12084Sralph 		charcode = left(base) & 0777;
79*12084Sralph 		if (charcode != c)
80*12084Sralph 			printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c);
81*12084Sralph 		wordcount = right(base);
82*12084Sralph 		if (base+wordcount > sws) {
83*12084Sralph 			printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c);
84*12084Sralph 			continue;
85*12084Sralph 		}
86*12084Sralph 		leftkern = (left(base+1) >> 9) & 0777;
87*12084Sralph 		rowsfromtop = left(base+1) & 0777;
88*12084Sralph 		datarowcount = right(base+1);
89*12084Sralph 
90*12084Sralph 		rastrows = datarowcount;
91*12084Sralph 		rastcols = (rastwidth + 35) / 36 * 36;
92*12084Sralph 
93*12084Sralph 		/* Unix disptable stuff */
94*12084Sralph 		disptable[c].addr = curaddr;
95*12084Sralph 		nb = rastrows * ((rastcols + 7) >> 3);
96*12084Sralph 		disptable[c].nbytes = nb;
97*12084Sralph 		curaddr += nb;
98*12084Sralph 		disptable[c].left = leftkern;
99*12084Sralph 		disptable[c].right = rastcols - leftkern;
100*12084Sralph 		disptable[c].up = baseline - rowsfromtop;
101*12084Sralph 		disptable[c].down = rastrows - disptable[c].up;
102*12084Sralph 		disptable[c].width = charwidth;
103*12084Sralph 		packed = (datarowcount > wordcount);
104*12084Sralph 		nperword = 36 / rastwidth;
105*12084Sralph 
106*12084Sralph 		/* Now get the raster rows themselves */
107*12084Sralph 		p = 0;
108*12084Sralph 		ncol = rastcols / 36;
109*12084Sralph 		nleft = ((rastwidth-1) % 36 + 1);
110*12084Sralph 		base += 2;
111*12084Sralph 		for (r=0; r<rastrows; r++) {
112*12084Sralph 			if (!packed) {
113*12084Sralph 				for (i=0; i<ncol; i++) {
114*12084Sralph 					lh = left(base); rh = right(base++);
115*12084Sralph 					/* compensate for garbage in SAIL fonts */
116*12084Sralph 					if (i == ncol-1) {
117*12084Sralph 						if (nleft <= 18) {
118*12084Sralph 							rh = 0;
119*12084Sralph 							lh &= ~rightbits[18-nleft];
120*12084Sralph 						} else
121*12084Sralph 							rh &= ~rightbits[36-nleft];
122*12084Sralph 					}
123*12084Sralph 					if (i%2) {
124*12084Sralph 						u[p-1] |= (lh>>14) & 017;
125*12084Sralph 						u[p++] = lh >> 6;
126*12084Sralph 						u[p++] = ((lh&077)<<2) | ((rh>>16)&03);
127*12084Sralph 						u[p++] = rh >> 8;
128*12084Sralph 						u[p++] = rh;
129*12084Sralph 					} else {
130*12084Sralph 						u[p++] = lh >> 10;
131*12084Sralph 						u[p++] = lh >> 2;
132*12084Sralph 						u[p++] = ((lh&03)<<6) | (rh>>12);
133*12084Sralph 						u[p++] = rh >> 4;
134*12084Sralph 						u[p++] = (rh & 017) << 4;
135*12084Sralph 					}
136*12084Sralph 				}
137*12084Sralph 			} else {
138*12084Sralph 				put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p);
139*12084Sralph 				p += 5;	/* 5 8 bit bytes per 36 bit word */
140*12084Sralph 			}
141*12084Sralph 		}
142*12084Sralph 		write(outfd, u, p);
143*12084Sralph 	}
144*12084Sralph 	lseek(outfd, 0, 0);
145*12084Sralph 	vheader.size = curaddr;
146*12084Sralph 	write(outfd, &vheader, sizeof vheader);
147*12084Sralph 	write(outfd, disptable, sizeof disptable);
148*12084Sralph 	close(outfd);
149*12084Sralph 	exit(0);
150*12084Sralph }
151*12084Sralph 
152*12084Sralph /*
153*12084Sralph  * put a pdp-10 style variable size byte into 8 bit Unix bytes starting
154*12084Sralph  * at location dest.  The byte is bytesize bits, and is the bytenumth byte
155*12084Sralph  * in the 36 bit word (lh,,rh).
156*12084Sralph  */
157*12084Sralph put(bytenum, bytesize, lh, rh, dest)
158*12084Sralph 	int bytenum, bytesize;
159*12084Sralph 	long lh, rh;
160*12084Sralph 	char *dest;
161*12084Sralph {
162*12084Sralph 	register int i;
163*12084Sralph 
164*12084Sralph 	for (i=0; i<5; i++)
165*12084Sralph 		dest[i] = 0;
166*12084Sralph 	for (i=0; i<bytenum; i++) {
167*12084Sralph 		lh <<= bytesize;
168*12084Sralph 		lh |= (rh >> 18-bytesize) & rightbits[bytesize];
169*12084Sralph 		rh <<= bytesize;
170*12084Sralph 	}
171*12084Sralph 	lh &= ~rightbits[18-bytesize];
172*12084Sralph 	/* We now have the byte we want left justified in lh */
173*12084Sralph 	lh <<= 14;
174*12084Sralph 	/* lh is now the byte we want, left justified in 32 bit word */
175*12084Sralph 	for (i=0; i<bytesize; i += 8) {
176*12084Sralph 		*dest++ = (lh >> 24) & 0377;
177*12084Sralph 		lh <<= 8;
178*12084Sralph 	}
179*12084Sralph }
180*12084Sralph 
181*12084Sralph /*
182*12084Sralph  * Return the left half (18 bits) of pdp-10 word p.
183*12084Sralph  */
184*12084Sralph long
185*12084Sralph left(p)
186*12084Sralph 	int p;
187*12084Sralph {
188*12084Sralph 	register int lp, odd;
189*12084Sralph 	register long retval;
190*12084Sralph 
191*12084Sralph 	odd = p%2;
192*12084Sralph 	lp = 9*p/2;
193*12084Sralph 	if (p >= sws) {
194*12084Sralph 		return(0);
195*12084Sralph 	}
196*12084Sralph 	if (odd) {
197*12084Sralph 		retval  = (b[lp++] & 0017) << 14;
198*12084Sralph 		retval |= (b[lp++] & 0377) << 6;
199*12084Sralph 		retval |= (b[lp] >> 2) & 63;
200*12084Sralph 	} else {
201*12084Sralph 		retval  = (b[lp++] & 0377) << 10;
202*12084Sralph 		retval |= (b[lp++] & 0377) << 2;
203*12084Sralph 		retval |= (b[lp] >> 6) & 3;
204*12084Sralph 	}
205*12084Sralph 	return retval;
206*12084Sralph }
207*12084Sralph 
208*12084Sralph /*
209*12084Sralph  * Return the right half of 36 bit word #p.
210*12084Sralph  */
211*12084Sralph long
212*12084Sralph right(p)
213*12084Sralph 	int p;
214*12084Sralph {
215*12084Sralph 	register int lp, odd;
216*12084Sralph 	register long retval;
217*12084Sralph 
218*12084Sralph 	odd = p%2;
219*12084Sralph 	lp = 9*p/2 + 2;
220*12084Sralph 	if (p >= sws) {
221*12084Sralph 		return(0);
222*12084Sralph 	}
223*12084Sralph 	if (odd) {
224*12084Sralph 		retval  = (b[lp++] & 0003) << 16;
225*12084Sralph 		retval |= (b[lp++] & 0377) << 8;
226*12084Sralph 		retval |= (b[lp]   & 0377);
227*12084Sralph 	} else {
228*12084Sralph 		retval  = (b[lp++] & 0077) << 12;
229*12084Sralph 		retval |= (b[lp++] & 0377) << 4;
230*12084Sralph 		retval |= (b[lp] >> 4) & 017;
231*12084Sralph 	}
232*12084Sralph 	return retval;
233*12084Sralph }
234