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) 5/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 ;
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:
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: */
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
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
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: }