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