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
main(argc,argv)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 */
put(bytenum,bytesize,lh,rh,dest)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
left(p)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
right(p)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