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