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