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