1 #ifndef lint 2 static char sccsid[] = "@(#)fcvt.c 4.2 (Berkeley) 07/16/83"; 3 #endif 4 5 /* 6 * Convert from the SAIL font format to the Unix font format. 7 * Usage: fcvt sailfile unixfile 8 */ 9 10 #include <stdio.h> 11 #include <vfont.h> 12 13 int sws; /* sail word size in 36 bit words */ 14 char b[40000], u[2000]; 15 long left(), right(); 16 17 struct header vheader; 18 struct dispatch disptable[256]; 19 20 long rightbits[19] = { 21 0, 1, 03, 07, 017, 037, 22 077, 0177, 0377, 0777, 01777, 03777, 23 07777, 017777, 037777, 077777, 0177777,0377777,0777777 24 }; 25 26 main(argc, argv) 27 int argc; 28 char *argv[]; 29 { 30 int infd = open(argv[1], 0); 31 int outfd = creat(argv[2], 0666); 32 int n; 33 long lh, rh; 34 int base, nb, ncol, nleft, r, i; 35 int c, p; 36 /* Sail counters and things */ 37 int height, maxwidth, baseline; 38 int charwidth, rastwidth, charcode, wordcount; 39 int leftkern, rowsfromtop, datarowcount; 40 /* Unix counters and things */ 41 int rastrows, rastcols; 42 int curaddr; 43 int packed; /* true if sail packed format for this glyph */ 44 int nperword; 45 46 if (infd < 0 || outfd < 0) { 47 printf("Usage: fcvt sailfile unixfile\n"); 48 exit(1); 49 } 50 n = read(infd, b, sizeof b); 51 sws = 2 * n / 9; 52 if (n == sizeof b) { 53 printf("Font larger than %d bytes - recompile me\n", n); 54 exit(1); 55 } 56 close(infd); 57 58 height = right(0201); 59 maxwidth = right(0202); 60 baseline = right(0203); 61 62 vheader.magic = 0436; 63 /* size gets done later */ 64 vheader.maxx = height; 65 vheader.maxy = maxwidth; 66 /* I don't know what xtnd would map to */ 67 68 lseek(outfd, (long) sizeof vheader + sizeof disptable, 0); 69 curaddr = 0; 70 71 /* Look at each char */ 72 for (c=0; c<0200; c++) { 73 /* Find Sail info */ 74 base = right(c); 75 if (base == 0) 76 continue; 77 charwidth = left(c); 78 rastwidth = (left(base) >> 9) & 0777; 79 if (rastwidth == 0) 80 rastwidth = charwidth; 81 charcode = left(base) & 0777; 82 if (charcode != c) 83 printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c); 84 wordcount = right(base); 85 if (base+wordcount > sws) { 86 printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c); 87 continue; 88 } 89 leftkern = (left(base+1) >> 9) & 0777; 90 rowsfromtop = left(base+1) & 0777; 91 datarowcount = right(base+1); 92 93 rastrows = datarowcount; 94 rastcols = (rastwidth + 35) / 36 * 36; 95 96 /* Unix disptable stuff */ 97 disptable[c].addr = curaddr; 98 nb = rastrows * ((rastcols + 7) >> 3); 99 disptable[c].nbytes = nb; 100 curaddr += nb; 101 disptable[c].left = leftkern; 102 disptable[c].right = rastcols - leftkern; 103 disptable[c].up = baseline - rowsfromtop; 104 disptable[c].down = rastrows - disptable[c].up; 105 disptable[c].width = charwidth; 106 packed = (datarowcount > wordcount); 107 nperword = 36 / rastwidth; 108 109 /* Now get the raster rows themselves */ 110 p = 0; 111 ncol = rastcols / 36; 112 nleft = ((rastwidth-1) % 36 + 1); 113 base += 2; 114 for (r=0; r<rastrows; r++) { 115 if (!packed) { 116 for (i=0; i<ncol; i++) { 117 lh = left(base); rh = right(base++); 118 /* compensate for garbage in SAIL fonts */ 119 if (i == ncol-1) { 120 if (nleft <= 18) { 121 rh = 0; 122 lh &= ~rightbits[18-nleft]; 123 } else 124 rh &= ~rightbits[36-nleft]; 125 } 126 if (i%2) { 127 u[p-1] |= (lh>>14) & 017; 128 u[p++] = lh >> 6; 129 u[p++] = ((lh&077)<<2) | ((rh>>16)&03); 130 u[p++] = rh >> 8; 131 u[p++] = rh; 132 } else { 133 u[p++] = lh >> 10; 134 u[p++] = lh >> 2; 135 u[p++] = ((lh&03)<<6) | (rh>>12); 136 u[p++] = rh >> 4; 137 u[p++] = (rh & 017) << 4; 138 } 139 } 140 } else { 141 put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p); 142 p += 5; /* 5 8 bit bytes per 36 bit word */ 143 } 144 } 145 write(outfd, u, p); 146 } 147 lseek(outfd, 0, 0); 148 vheader.size = curaddr; 149 write(outfd, &vheader, sizeof vheader); 150 write(outfd, disptable, sizeof disptable); 151 close(outfd); 152 exit(0); 153 } 154 155 /* 156 * put a pdp-10 style variable size byte into 8 bit Unix bytes starting 157 * at location dest. The byte is bytesize bits, and is the bytenumth byte 158 * in the 36 bit word (lh,,rh). 159 */ 160 put(bytenum, bytesize, lh, rh, dest) 161 int bytenum, bytesize; 162 long lh, rh; 163 char *dest; 164 { 165 register int i; 166 167 for (i=0; i<5; i++) 168 dest[i] = 0; 169 for (i=0; i<bytenum; i++) { 170 lh <<= bytesize; 171 lh |= (rh >> 18-bytesize) & rightbits[bytesize]; 172 rh <<= bytesize; 173 } 174 lh &= ~rightbits[18-bytesize]; 175 /* We now have the byte we want left justified in lh */ 176 lh <<= 14; 177 /* lh is now the byte we want, left justified in 32 bit word */ 178 for (i=0; i<bytesize; i += 8) { 179 *dest++ = (lh >> 24) & 0377; 180 lh <<= 8; 181 } 182 } 183 184 /* 185 * Return the left half (18 bits) of pdp-10 word p. 186 */ 187 long 188 left(p) 189 int p; 190 { 191 register int lp, odd; 192 register long retval; 193 194 odd = p%2; 195 lp = 9*p/2; 196 if (p >= sws) { 197 return(0); 198 } 199 if (odd) { 200 retval = (b[lp++] & 0017) << 14; 201 retval |= (b[lp++] & 0377) << 6; 202 retval |= (b[lp] >> 2) & 63; 203 } else { 204 retval = (b[lp++] & 0377) << 10; 205 retval |= (b[lp++] & 0377) << 2; 206 retval |= (b[lp] >> 6) & 3; 207 } 208 return retval; 209 } 210 211 /* 212 * Return the right half of 36 bit word #p. 213 */ 214 long 215 right(p) 216 int p; 217 { 218 register int lp, odd; 219 register long retval; 220 221 odd = p%2; 222 lp = 9*p/2 + 2; 223 if (p >= sws) { 224 return(0); 225 } 226 if (odd) { 227 retval = (b[lp++] & 0003) << 16; 228 retval |= (b[lp++] & 0377) << 8; 229 retval |= (b[lp] & 0377); 230 } else { 231 retval = (b[lp++] & 0077) << 12; 232 retval |= (b[lp++] & 0377) << 4; 233 retval |= (b[lp] >> 4) & 017; 234 } 235 return retval; 236 } 237