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