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