1: static char *sccsid = "@(#)vfontinfo.c 4.4 (Berkeley) 5/30/81";
2: /* Font Information for VCat-style fonts
3: * Andy Hertzfeld 4/79
4: *
5: * Modified to print Ascii chars 1/80 by Mark Horton
6: * Zoom option added 5/81 by Steve Stone with tables from Mark Horton.
7: * Message option added 5/31 by Mark Horton
8: */
9: #include <stdio.h>
10: #include <ctype.h>
11: #include <vfont.h>
12:
13: struct header ;
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];
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;
31:
32: main(argc,argv)
33: int argc;
34: char **argv;
35:
36: {
37: int FID,i,j;
38:
39: while (argc > 1 && argv[1][0] == '-') {
40: switch(argv[1][1]) {
41: case 'v':
42: verbose++;
43: break;
44: case 'z':
45: zoom = argv[1][2] - '0';
46: break;
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;
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)
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: }
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) {
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) {
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);
118: base = disptable[j].up;
119: WB = (W+7)/8;
120: if (zoom < 0) {
121: /*
122: * Old 1 for 1 code. The aspect ratio
123: * is awful, so we don't use it.
124: */
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");
133: }
134: printf("\n");
135: } else {
136: shozoom();
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: }
144: }
145: }
146: }
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: }
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:
180: if (row<0 || row>=H || col>=W) return(0);
181: thisbyte = charbits[row*WB + (col>>3)] & 0xff;
182: thisbit = 0x80 >> (col&7);
183: ret = thisbyte & thisbit;
184: return (ret != 0);
185: }
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;
295: int line = curline + (base+3)/4;
296: int col;
297:
298: k = base%4;
299: if (k > 0) k -= 4;
300: while (k < H) {
301: l = 0;
302: col = curcol;
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:
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]);
319: l++;
320: col++;
321: }
322: if (msgflag == 0)
323: printf("\n");
324: k += 4;
325: line--;
326: }
327: if (msgflag == 0)
328: printf("\n");
329: }