1*13944Ssam #ifndef lint 2*13944Ssam static char sccsid[] = "@(#)fcvt.c 4.2 (Berkeley) 07/16/83"; 3*13944Ssam #endif 4*13944Ssam 512084Sralph /* 612084Sralph * Convert from the SAIL font format to the Unix font format. 712084Sralph * Usage: fcvt sailfile unixfile 812084Sralph */ 912084Sralph 1012084Sralph #include <stdio.h> 1112084Sralph #include <vfont.h> 1212084Sralph 1312084Sralph int sws; /* sail word size in 36 bit words */ 1412084Sralph char b[40000], u[2000]; 1512084Sralph long left(), right(); 1612084Sralph 1712084Sralph struct header vheader; 1812084Sralph struct dispatch disptable[256]; 1912084Sralph 2012084Sralph long rightbits[19] = { 2112084Sralph 0, 1, 03, 07, 017, 037, 2212084Sralph 077, 0177, 0377, 0777, 01777, 03777, 2312084Sralph 07777, 017777, 037777, 077777, 0177777,0377777,0777777 2412084Sralph }; 2512084Sralph 2612084Sralph main(argc, argv) 2712084Sralph int argc; 2812084Sralph char *argv[]; 2912084Sralph { 3012084Sralph int infd = open(argv[1], 0); 3112084Sralph int outfd = creat(argv[2], 0666); 3212084Sralph int n; 3312084Sralph long lh, rh; 3412084Sralph int base, nb, ncol, nleft, r, i; 3512084Sralph int c, p; 3612084Sralph /* Sail counters and things */ 3712084Sralph int height, maxwidth, baseline; 3812084Sralph int charwidth, rastwidth, charcode, wordcount; 3912084Sralph int leftkern, rowsfromtop, datarowcount; 4012084Sralph /* Unix counters and things */ 4112084Sralph int rastrows, rastcols; 4212084Sralph int curaddr; 4312084Sralph int packed; /* true if sail packed format for this glyph */ 4412084Sralph int nperword; 4512084Sralph 4612084Sralph if (infd < 0 || outfd < 0) { 4712084Sralph printf("Usage: fcvt sailfile unixfile\n"); 4812084Sralph exit(1); 4912084Sralph } 5012084Sralph n = read(infd, b, sizeof b); 5112084Sralph sws = 2 * n / 9; 5212084Sralph if (n == sizeof b) { 5312084Sralph printf("Font larger than %d bytes - recompile me\n", n); 5412084Sralph exit(1); 5512084Sralph } 5612084Sralph close(infd); 5712084Sralph 5812084Sralph height = right(0201); 5912084Sralph maxwidth = right(0202); 6012084Sralph baseline = right(0203); 6112084Sralph 6212084Sralph vheader.magic = 0436; 6312084Sralph /* size gets done later */ 6412084Sralph vheader.maxx = height; 6512084Sralph vheader.maxy = maxwidth; 6612084Sralph /* I don't know what xtnd would map to */ 6712084Sralph 6812084Sralph lseek(outfd, (long) sizeof vheader + sizeof disptable, 0); 6912084Sralph curaddr = 0; 7012084Sralph 7112084Sralph /* Look at each char */ 7212084Sralph for (c=0; c<0200; c++) { 7312084Sralph /* Find Sail info */ 7412084Sralph base = right(c); 7512084Sralph if (base == 0) 7612084Sralph continue; 7712084Sralph charwidth = left(c); 7812084Sralph rastwidth = (left(base) >> 9) & 0777; 7912084Sralph if (rastwidth == 0) 8012084Sralph rastwidth = charwidth; 8112084Sralph charcode = left(base) & 0777; 8212084Sralph if (charcode != c) 8312084Sralph printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c); 8412084Sralph wordcount = right(base); 8512084Sralph if (base+wordcount > sws) { 8612084Sralph printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c); 8712084Sralph continue; 8812084Sralph } 8912084Sralph leftkern = (left(base+1) >> 9) & 0777; 9012084Sralph rowsfromtop = left(base+1) & 0777; 9112084Sralph datarowcount = right(base+1); 9212084Sralph 9312084Sralph rastrows = datarowcount; 9412084Sralph rastcols = (rastwidth + 35) / 36 * 36; 9512084Sralph 9612084Sralph /* Unix disptable stuff */ 9712084Sralph disptable[c].addr = curaddr; 9812084Sralph nb = rastrows * ((rastcols + 7) >> 3); 9912084Sralph disptable[c].nbytes = nb; 10012084Sralph curaddr += nb; 10112084Sralph disptable[c].left = leftkern; 10212084Sralph disptable[c].right = rastcols - leftkern; 10312084Sralph disptable[c].up = baseline - rowsfromtop; 10412084Sralph disptable[c].down = rastrows - disptable[c].up; 10512084Sralph disptable[c].width = charwidth; 10612084Sralph packed = (datarowcount > wordcount); 10712084Sralph nperword = 36 / rastwidth; 10812084Sralph 10912084Sralph /* Now get the raster rows themselves */ 11012084Sralph p = 0; 11112084Sralph ncol = rastcols / 36; 11212084Sralph nleft = ((rastwidth-1) % 36 + 1); 11312084Sralph base += 2; 11412084Sralph for (r=0; r<rastrows; r++) { 11512084Sralph if (!packed) { 11612084Sralph for (i=0; i<ncol; i++) { 11712084Sralph lh = left(base); rh = right(base++); 11812084Sralph /* compensate for garbage in SAIL fonts */ 11912084Sralph if (i == ncol-1) { 12012084Sralph if (nleft <= 18) { 12112084Sralph rh = 0; 12212084Sralph lh &= ~rightbits[18-nleft]; 12312084Sralph } else 12412084Sralph rh &= ~rightbits[36-nleft]; 12512084Sralph } 12612084Sralph if (i%2) { 12712084Sralph u[p-1] |= (lh>>14) & 017; 12812084Sralph u[p++] = lh >> 6; 12912084Sralph u[p++] = ((lh&077)<<2) | ((rh>>16)&03); 13012084Sralph u[p++] = rh >> 8; 13112084Sralph u[p++] = rh; 13212084Sralph } else { 13312084Sralph u[p++] = lh >> 10; 13412084Sralph u[p++] = lh >> 2; 13512084Sralph u[p++] = ((lh&03)<<6) | (rh>>12); 13612084Sralph u[p++] = rh >> 4; 13712084Sralph u[p++] = (rh & 017) << 4; 13812084Sralph } 13912084Sralph } 14012084Sralph } else { 14112084Sralph put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p); 14212084Sralph p += 5; /* 5 8 bit bytes per 36 bit word */ 14312084Sralph } 14412084Sralph } 14512084Sralph write(outfd, u, p); 14612084Sralph } 14712084Sralph lseek(outfd, 0, 0); 14812084Sralph vheader.size = curaddr; 14912084Sralph write(outfd, &vheader, sizeof vheader); 15012084Sralph write(outfd, disptable, sizeof disptable); 15112084Sralph close(outfd); 15212084Sralph exit(0); 15312084Sralph } 15412084Sralph 15512084Sralph /* 15612084Sralph * put a pdp-10 style variable size byte into 8 bit Unix bytes starting 15712084Sralph * at location dest. The byte is bytesize bits, and is the bytenumth byte 15812084Sralph * in the 36 bit word (lh,,rh). 15912084Sralph */ 16012084Sralph put(bytenum, bytesize, lh, rh, dest) 16112084Sralph int bytenum, bytesize; 16212084Sralph long lh, rh; 16312084Sralph char *dest; 16412084Sralph { 16512084Sralph register int i; 16612084Sralph 16712084Sralph for (i=0; i<5; i++) 16812084Sralph dest[i] = 0; 16912084Sralph for (i=0; i<bytenum; i++) { 17012084Sralph lh <<= bytesize; 17112084Sralph lh |= (rh >> 18-bytesize) & rightbits[bytesize]; 17212084Sralph rh <<= bytesize; 17312084Sralph } 17412084Sralph lh &= ~rightbits[18-bytesize]; 17512084Sralph /* We now have the byte we want left justified in lh */ 17612084Sralph lh <<= 14; 17712084Sralph /* lh is now the byte we want, left justified in 32 bit word */ 17812084Sralph for (i=0; i<bytesize; i += 8) { 17912084Sralph *dest++ = (lh >> 24) & 0377; 18012084Sralph lh <<= 8; 18112084Sralph } 18212084Sralph } 18312084Sralph 18412084Sralph /* 18512084Sralph * Return the left half (18 bits) of pdp-10 word p. 18612084Sralph */ 18712084Sralph long 18812084Sralph left(p) 18912084Sralph int p; 19012084Sralph { 19112084Sralph register int lp, odd; 19212084Sralph register long retval; 19312084Sralph 19412084Sralph odd = p%2; 19512084Sralph lp = 9*p/2; 19612084Sralph if (p >= sws) { 19712084Sralph return(0); 19812084Sralph } 19912084Sralph if (odd) { 20012084Sralph retval = (b[lp++] & 0017) << 14; 20112084Sralph retval |= (b[lp++] & 0377) << 6; 20212084Sralph retval |= (b[lp] >> 2) & 63; 20312084Sralph } else { 20412084Sralph retval = (b[lp++] & 0377) << 10; 20512084Sralph retval |= (b[lp++] & 0377) << 2; 20612084Sralph retval |= (b[lp] >> 6) & 3; 20712084Sralph } 20812084Sralph return retval; 20912084Sralph } 21012084Sralph 21112084Sralph /* 21212084Sralph * Return the right half of 36 bit word #p. 21312084Sralph */ 21412084Sralph long 21512084Sralph right(p) 21612084Sralph int p; 21712084Sralph { 21812084Sralph register int lp, odd; 21912084Sralph register long retval; 22012084Sralph 22112084Sralph odd = p%2; 22212084Sralph lp = 9*p/2 + 2; 22312084Sralph if (p >= sws) { 22412084Sralph return(0); 22512084Sralph } 22612084Sralph if (odd) { 22712084Sralph retval = (b[lp++] & 0003) << 16; 22812084Sralph retval |= (b[lp++] & 0377) << 8; 22912084Sralph retval |= (b[lp] & 0377); 23012084Sralph } else { 23112084Sralph retval = (b[lp++] & 0077) << 12; 23212084Sralph retval |= (b[lp++] & 0377) << 4; 23312084Sralph retval |= (b[lp] >> 4) & 017; 23412084Sralph } 23512084Sralph return retval; 23612084Sralph } 237