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