|
|
1.1 root 1: /*
2: * Convert from the SAIL font format to the Unix font format.
3: * Usage: fcvt sailfile unixfile
4: */
5: long left(), right();
6: int sws; /* sail word size in 36 bit words */
7: char b[40000], u[2000];
8: #include <stdio.h>
9: #include <vfont.h>
10:
11: struct header vheader;
12: struct dispatch disptable[256];
13:
14: long 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:
20: main(argc, argv)
21: char **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: */
153: put(bytenum, bytesize, lh, rh, dest)
154: int bytenum, bytesize;
155: long lh, rh;
156: char *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: */
180: long
181: left(p)
182: int 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: */
207: long
208: right(p)
209: int 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.