#ifndef lint static char sccsid[] = "@(#)fcvt.c 4.1 (Berkeley) 3/29/83"; #endif not lint /* * Convert from the SAIL font format to the Unix font format. * Usage: fcvt sailfile unixfile */ long left(), right(); int sws; /* sail word size in 36 bit words */ char b[40000], u[2000]; #include #include struct header vheader; struct dispatch disptable[256]; long rightbits[19] = { 0, 1, 03, 07, 017, 037, 077, 0177, 0377, 0777, 01777, 03777, 07777, 017777, 037777, 077777, 0177777,0377777,0777777 }; main(argc, argv) char **argv; { int infd = open(argv[1], 0); int outfd = creat(argv[2], 0666); int n; long lh, rh; int base, nb, ncol, nleft, r, i; int c, p; /* Sail counters and things */ int height, maxwidth, baseline; int charwidth, rastwidth, charcode, wordcount; int leftkern, rowsfromtop, datarowcount; /* Unix counters and things */ int rastrows, rastcols; int curaddr; int packed; /* true if sail packed format for this glyph */ int nperword; if (infd < 0 || outfd < 0) { printf("Usage: fcvt sailfile unixfile\n"); exit(1); } n = read(infd, b, sizeof b); sws = 2 * n / 9; if (n == sizeof b) { printf("Font larger than %d bytes - recompile me\n", n); exit(1); } close(infd); height = right(0201); maxwidth = right(0202); baseline = right(0203); vheader.magic = 0436; /* size gets done later */ vheader.maxx = height; vheader.maxy = maxwidth; /* I don't know what xtnd would map to */ lseek(outfd, (long) sizeof vheader + sizeof disptable, 0); curaddr = 0; /* Look at each char */ for (c=0; c<0200; c++) { /* Find Sail info */ base = right(c); if (base == 0) continue; charwidth = left(c); rastwidth = (left(base) >> 9) & 0777; if (rastwidth == 0) rastwidth = charwidth; charcode = left(base) & 0777; if (charcode != c) printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c); wordcount = right(base); if (base+wordcount > sws) { printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c); continue; } leftkern = (left(base+1) >> 9) & 0777; rowsfromtop = left(base+1) & 0777; datarowcount = right(base+1); rastrows = datarowcount; rastcols = (rastwidth + 35) / 36 * 36; /* Unix disptable stuff */ disptable[c].addr = curaddr; nb = rastrows * ((rastcols + 7) >> 3); disptable[c].nbytes = nb; curaddr += nb; disptable[c].left = leftkern; disptable[c].right = rastcols - leftkern; disptable[c].up = baseline - rowsfromtop; disptable[c].down = rastrows - disptable[c].up; disptable[c].width = charwidth; packed = (datarowcount > wordcount); nperword = 36 / rastwidth; /* Now get the raster rows themselves */ p = 0; ncol = rastcols / 36; nleft = ((rastwidth-1) % 36 + 1); base += 2; for (r=0; r>14) & 017; u[p++] = lh >> 6; u[p++] = ((lh&077)<<2) | ((rh>>16)&03); u[p++] = rh >> 8; u[p++] = rh; } else { u[p++] = lh >> 10; u[p++] = lh >> 2; u[p++] = ((lh&03)<<6) | (rh>>12); u[p++] = rh >> 4; u[p++] = (rh & 017) << 4; } } } else { put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p); p += 5; /* 5 8 bit bytes per 36 bit word */ } } write(outfd, u, p); } lseek(outfd, 0, 0); vheader.size = curaddr; write(outfd, &vheader, sizeof vheader); write(outfd, disptable, sizeof disptable); close(outfd); exit(0); } /* * put a pdp-10 style variable size byte into 8 bit Unix bytes starting * at location dest. The byte is bytesize bits, and is the bytenumth byte * in the 36 bit word (lh,,rh). */ put(bytenum, bytesize, lh, rh, dest) int bytenum, bytesize; long lh, rh; char *dest; { register int i; for (i=0; i<5; i++) dest[i] = 0; for (i=0; i> 18-bytesize) & rightbits[bytesize]; rh <<= bytesize; } lh &= ~rightbits[18-bytesize]; /* We now have the byte we want left justified in lh */ lh <<= 14; /* lh is now the byte we want, left justified in 32 bit word */ for (i=0; i> 24) & 0377; lh <<= 8; } } /* * Return the left half (18 bits) of pdp-10 word p. */ long left(p) int p; { register int lp, odd; register long retval; odd = p%2; lp = 9*p/2; if (p >= sws) { return(0); } if (odd) { retval = (b[lp++] & 0017) << 14; retval |= (b[lp++] & 0377) << 6; retval |= (b[lp] >> 2) & 63; } else { retval = (b[lp++] & 0377) << 10; retval |= (b[lp++] & 0377) << 2; retval |= (b[lp] >> 6) & 3; } return retval; } /* * Return the right half of 36 bit word #p. */ long right(p) int p; { register int lp, odd; register long retval; odd = p%2; lp = 9*p/2 + 2; if (p >= sws) { return(0); } if (odd) { retval = (b[lp++] & 0003) << 16; retval |= (b[lp++] & 0377) << 8; retval |= (b[lp] & 0377); } else { retval = (b[lp++] & 0077) << 12; retval |= (b[lp++] & 0377) << 4; retval |= (b[lp] >> 4) & 017; } return retval; }