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