BSD 4 development
[unix-history] / usr / src / cmd / vpr / fcvt.c
CommitLineData
57d7e39a
BJ
1/*
2 * Convert from the SAIL font format to the Unix font format.
3 * Usage: fcvt sailfile unixfile
4 */
5long left(), right();
6int sws; /* sail word size in 36 bit words */
7char b[40000], u[2000];
8#include <stdio.h>
9#include <vfont.h>
10
11struct header vheader;
12struct dispatch disptable[256];
13
14long 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
20main(argc, argv)
21char **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 */
153put(bytenum, bytesize, lh, rh, dest)
154int bytenum, bytesize;
155long lh, rh;
156char *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 */
180long
181left(p)
182int 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 */
207long
208right(p)
209int 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}