/old/fcvt/fcvt.c
https://bitbucket.org/okuoku/csrg · C · 233 lines · 189 code · 18 blank · 26 comment · 30 complexity · c116b49d3340e61fbf404308185cbffc MD5 · raw file
- #ifndef lint
- static char sccsid[] = "@(#)fcvt.c 4.1 (Berkeley) 03/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 <stdio.h>
- #include <vfont.h>
- 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<rastrows; r++) {
- if (!packed) {
- for (i=0; i<ncol; i++) {
- lh = left(base); rh = right(base++);
- /* compensate for garbage in SAIL fonts */
- if (i == ncol-1) {
- if (nleft <= 18) {
- rh = 0;
- lh &= ~rightbits[18-nleft];
- } else
- rh &= ~rightbits[36-nleft];
- }
- if (i%2) {
- u[p-1] |= (lh>>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<bytenum; i++) {
- lh <<= bytesize;
- lh |= (rh >> 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<bytesize; i += 8) {
- *dest++ = (lh >> 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;
- }