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) 5/15/85";
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 ;
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:
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:
169: error(string)
170: char *string;
171:
172: {
173: printf("\nvfontinfo: %s\n",string);
174: exit(8);
175: };
176:
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
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:
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:
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:
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:
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: }