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