date and time created 88/07/22 16:08:01 by bostic
[unix-history] / usr / src / old / fcvt / fcvt.c
CommitLineData
33a7f81e
KM
1#ifndef lint
2static 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 */
9long left(), right();
10int sws; /* sail word size in 36 bit words */
11char b[40000], u[2000];
12#include <stdio.h>
13#include <vfont.h>
14
15struct header vheader;
16struct dispatch disptable[256];
17
18long 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
24main(argc, argv)
25char **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 */
157put(bytenum, bytesize, lh, rh, dest)
158int bytenum, bytesize;
159long lh, rh;
160char *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 */
184long
185left(p)
186int 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 */
211long
212right(p)
213int 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}