1 #ifndef lint
2 static char sccsid[] = "@(#)vfontinfo.c	4.3 (Berkeley) 7/16/83";
3 #endif
4 
5 /* Font Information for VCat-style fonts
6  *      Andy Hertzfeld  4/79
7  *
8  *	Modified to print Ascii chars 1/80 by Mark Horton
9  *	Zoom option added 5/81 by Steve Stone with tables from Mark Horton.
10  *	Message option added 5/31 by Mark Horton
11  */
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <vfont.h>
15 
16 #ifndef BITDIR
17 #define BITDIR "/usr/lib/vfont"
18 #endif
19 
20 struct header FontHeader;
21 struct dispatch disptable[256];
22 
23 char	IName[100];
24 char *	rdchar();
25 long	fbase;
26 
27 char	defascii[256];
28 char	*charswanted = defascii;
29 int	verbose;
30 char	charbits[4000];
31 int	H, W, WB, base;
32 int 	zoom = 1;
33 
34 char msgout[24][80];
35 int msgflag = 0;
36 int curline, curcol;	/* cursor, numbered from lower left corner */
37 int minline=24, maxline=0, maxcol=0;
38 
39 main(argc,argv)
40 int argc;
41 char **argv;
42 
43 {
44 	int FID,i,j;
45 
46 	while (argc > 1 && argv[1][0] == '-') {
47 		switch(argv[1][1]) {
48 		case 'z':
49 			zoom = argv[1][2] - '0';  /* zoom implies verbose */
50 		case 'v':
51 			verbose++;
52 			break;
53 		case 'm':
54 			msgflag = 1;
55 			zoom = 2;
56 			for (i=0; i<24; i++)
57 				for (j=0; j<80; j++)
58 					msgout[i][j] = ' ';
59 			curline = 5; curcol = 0;
60 			break;
61 		default:
62 			printf("Bad flag: %s\n", argv[1]);
63 		}
64 		argc--; argv++;
65 	}
66 	if (argc < 2) {
67 		fprintf(stderr,"Usage: %s filename", argv[0]);
68 		exit(2);
69 	}
70 
71 	for (i=0; i<128; i++)
72 		defascii[i] = i;
73 	if (argc >= 3)
74 		charswanted = argv[2];
75 
76 	sprintf(IName, "%s/%s", BITDIR, argv[1]);
77 	if ((FID = open(argv[1],0)) < 0)
78 		if ((FID = open(IName,0)) < 0) {
79 			printf("Can't find %s\n",argv[1]);
80 			exit(8);
81 		};
82 
83 	if (read(FID,&FontHeader,sizeof FontHeader) != sizeof FontHeader)
84 		error("Bad header in Font file.");
85 
86 	if (read(FID,&disptable[0],sizeof disptable) != sizeof disptable)
87 		error("Bad dispatch table in Font file");
88 
89 	fbase = sizeof FontHeader + sizeof disptable;
90 
91 	if (FontHeader.magic != 0436)
92 		printf("Magic number %o wrong\n", FontHeader.magic);
93 	if (!msgflag) {
94 		printf("Font %s, ",argv[1]);
95 		printf("raster size %d, ",FontHeader.size);
96 		printf("max width %d, max height %d, xtend %d\n",
97 			FontHeader.maxx, FontHeader.maxy,FontHeader.xtend);
98 		printf("\n");
99 		for (i = strlen(argv[1]) + 1; i > 0; --i)
100 			printf(" ");
101 		printf("ASCII     offset    size  left    right   up     down    width \n");
102 	}
103 
104 	for (i=0; i<256; i++) {
105 		j = charswanted[i];
106 		if (i>0 && j==0)
107 			break;
108 		if (disptable[j].nbytes != 0) {
109 			if (!msgflag)
110 				printf("%s  %3o %2s     %4d   %4d   %4d   %4d   %4d   %4d   %5d\n",
111 					argv[1],
112 					j, rdchar(j),
113 					disptable[j].addr,
114 					disptable[j].nbytes,
115 					disptable[j].left,
116 					disptable[j].right,
117 					disptable[j].up,
118 					disptable[j].down,
119 					disptable[j].width);
120 			if (verbose || msgflag) {
121 				int len = disptable[j].nbytes;
122 				int k, l, last;
123 
124 				lseek(FID, fbase+disptable[j].addr, 0);
125 				read(FID, charbits, len);
126 				H = (disptable[j].up) + (disptable[j].down);
127 				W = (disptable[j].left) + (disptable[j].right);
128 				base = disptable[j].up;
129 #ifdef sun
130 				WB = ((W+15)/16)*2;
131 #else
132 				WB = (W+7)/8;
133 #endif
134 				shozoom();
135 				if (msgflag) {
136 					k = disptable[j].width;
137 					if (zoom == 0) k *= 2;
138 					else if (zoom == 2) k /= 2;
139 					curcol += k;
140 				}
141 			}
142 		}
143 	}
144 	if (msgflag) {
145 		for (i=maxline; i>=minline; i--) {
146 			for (j=0; j<maxcol; j++)
147 				putchar(msgout[i][j]);
148 			putchar('\n');
149 		}
150 	}
151 	exit(0);
152 }
153 
154 error(string)
155 char *string;
156 
157 {
158 	printf("\nvfontinfo: %s\n",string);
159 	exit(8);
160 };
161 
162 char *rdchar(c)
163 char c;
164 {
165 	static char ret[3];
166 	ret[0] = isprint(c) ? ' ' : '^';
167 	ret[1] = isprint(c) ?  c  : c^0100;
168 	ret[2] = 0;
169 	return (ret);
170 }
171 
172 int
173 fbit(row, col)
174 int row, col;
175 {
176 	int thisbyte, thisbit, ret;
177 
178 	if (row<0 || row>=H || col>=W) return(0);
179 	thisbyte = charbits[row*WB + (col>>3)] & 0xff;
180 	thisbit = 0x80 >> (col&7);
181 	ret = thisbyte & thisbit;
182 	return (ret != 0);
183 }
184 
185 
186 /*
187 The implementation would work like this:
188 	zoom level	method
189 	0		2 chars/pixel, 1 is "[]", 0 is "  ".
190 	1		2 pixels/char 2x1, using " " "," "'" "|"
191 	2		8 pixels/char 4x2, using 16x16 table
192 	3		32 pixels/char 8x4, mapped into (2)
193 	4 and up	similar, mapped into (2)
194 
195 The 16x16 table maps a 4x2 pattern into a printing ascii character which
196 most closely approximates that pattern, e.g. the pattern
197 	|'
198 	''
199 would be represented by the character "[".  I have such a table worked out.
200 
201 Grainer zoom levels would take the rule of reducing it into a smaller bitmap,
202 or-ing the bits together.  (e.g. level 3 would take a 2x2 chunk and map it
203 into a single pixel: 0 if all 4 are 0, 1 otherwise.)  These pixels would be
204 displayed as in 2.
205 */
206 
207 /*
208  * graphtab: a table for rudimentary graphics on ordinary terminals.
209  * For each 4x2 bit pattern of the form:
210  *	ae
211  *	bf
212  *	cg
213  *	dh
214  * form the 4 bit quantities abcd and efgh and get table entry
215  *	graphtab[abcd][efgh]
216  * to display in that character position.
217  *
218  * General philosophies: the dh bits are intended for descenders where
219  * possible.  Characters with radically different appearance on different
220  * terminals (e.g. _ and ^) are avoided.
221  *
222  * Version 1.0, March 1981, Mark Horton.
223  */
224 
225 char tab1[4] = {
226 	' ', ',', '\'', '|'
227 };
228 
229 char graphtab[16][16] = {
230 ' ', '.', '.', ',', '.', ';', ':', 'j', '\'', ':', ':', ';', '\'', ';', '!', '|',
231 '.', '.', ':', ',', ';', ';', ';', 'j', '/', ';', ';', ';', 'j', 'j', 'j', 'j',
232 '.', ',', '~', ',', 'r', '<', 'j', 'q', '/', ';', 'I', ';', '/', '|', 'I', '|',
233 ',', ',', 'r', 'x', '/', '/', '/', 'd', '/', '/', '/', 'd', '/', '/', '/', 'd',
234 '.', ':', '\\', ';', '-', '=', 'v', 'q', '\'', ':', '<', '|', '\'', ':', '+', '+',
235 ';', ';', '>', ';', '=', '=', 'g', 'g', '\'', ':', 'S', 'S', '/', '/', '/', '+',
236 ':', '\\', '\\', '\\', 'r', '<', 'w', 'q', '/', '<', '6', '4', '/', '/', 'd', '+',
237 'l', 'L', '+', 'b', 'y', '[', 'p', 'g', '/', '<', '/', '6', '/', '/', '/', '+',
238 '`', ':', ':', ';', '`', '\\', '\\', '\\', '"', ':', ':', ';', '`', '\\', 'Y', 'T',
239 ';', ';', ';', ';', '`', '2', '>', '\\', ':', '=', ';', ';', '?', '?', ']', ']',
240 ':', ';', ';', ';', '>', '2', '>', '\\', 'F', ';', 'O', ';', '7', '?', ']', '7',
241 ';', ';', ';', ';', '?', '2', '>', 'b', ';', ';', ';', ';', '?', '?', ']', '#',
242 '\'', '\\', '\\', '\\', '`', '\\', '\\', '\\', '\'', '\'', '<', '5', '"', '"', 'v', 'q',
243 ';', '\\', '\\', '\\', '`', '=', '\\', '\\', '\'', '\'', '5', '5', '"', '?', 'g', 'g',
244 'I', 'L', 'L', 'L', 'D', '\\', 'b', 'f', 'F', '[', '[', '[', 'P', '?', '#', 'M',
245 '|', '|', '|', '|', '|', '#', '+', '#', 'T', '[', 'F', 'F', 'P', '?', 'P', 'M'
246 };
247 
248 
249 shozoom()
250 {
251 	register i;
252 
253 	if (zoom == 0)
254 		sho0();
255 	else if (zoom == 1)
256 		sho1();
257 	else if (zoom == 2)
258 		sho2();
259 }
260 
261 sho0()
262 {
263 	register k,l;
264 
265 	for (k=0; k<H; k++) {
266 		for (l=0; l<W; l++)
267 			printf("%s", fbit(k,l)?"[]": "  ");
268 		printf("\n");
269 	}
270 	printf("\n");
271 }
272 
273 sho1()
274 {
275 	register k,l;
276 
277 	k = 0;
278 	for (k = 0; k <= H; k += 2) {
279 		for(l=0;l<W;l++) putchar(tab1[(fbit(k,l) << 1) | fbit(k+1,l)]);
280 		putchar('\n');
281 	}
282 	putchar('\n');
283 }
284 
285 sho2()
286 {
287 	register i,j,k,l;
288 	int line = curline + (base+3)/4;
289 	int col;
290 
291 	k = base%4;
292 	if (k > 0) k -= 4;
293 	while (k < H) {
294 		l = 0;
295 		col = curcol;
296 		while (l<W) {
297 			i = fbit(k,l)*8 + fbit(k+1,l)*4 +
298 			    fbit(k+2,l)*2 + fbit(k+3,l);
299 			l++;
300 			j = fbit(k,l)*8 + fbit(k+1,l)*4 +
301 			    fbit(k+2,l)*2 + fbit(k+3,l);
302 
303 			if (msgflag) {
304 				if (graphtab[i][j] != ' ') {
305 					if (line > maxline) maxline = line;
306 					if (line < minline) minline = line;
307 					if (col > maxcol)   maxcol  = col;
308 				}
309 				msgout[line][col] = graphtab[i][j];
310 			} else
311 				printf("%c",graphtab[i][j]);
312 			l++;
313 			col++;
314 		}
315 		if (msgflag == 0)
316 			printf("\n");
317 		k += 4;
318 		line--;
319 	}
320 	if (msgflag == 0)
321 		printf("\n");
322 }
323