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