1: #ifndef lint
2: static char sccsid[] = "@(#)fcvt.c 4.1 (Berkeley) 3/29/83";
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 ;
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: }