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) 05/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 vheader; 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 } 243