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