160728b8fSslatteng #ifndef lint
260728b8fSslatteng static char sccsid[] = "@(#)vfontinfo.c	4.3 (Berkeley) 7/16/83";
360728b8fSslatteng #endif
460728b8fSslatteng 
560728b8fSslatteng /* Font Information for VCat-style fonts
660728b8fSslatteng  *      Andy Hertzfeld  4/79
760728b8fSslatteng  *
860728b8fSslatteng  *	Modified to print Ascii chars 1/80 by Mark Horton
960728b8fSslatteng  *	Zoom option added 5/81 by Steve Stone with tables from Mark Horton.
1060728b8fSslatteng  *	Message option added 5/31 by Mark Horton
1160728b8fSslatteng  */
1260728b8fSslatteng #include <stdio.h>
1360728b8fSslatteng #include <ctype.h>
1460728b8fSslatteng #include <vfont.h>
1560728b8fSslatteng 
16f3f30b8cSslatteng #ifndef BITDIR
17f3f30b8cSslatteng #define BITDIR "/usr/lib/vfont"
18f3f30b8cSslatteng #endif
19f3f30b8cSslatteng 
2060728b8fSslatteng struct header FontHeader;
2160728b8fSslatteng struct dispatch disptable[256];
2260728b8fSslatteng 
2360728b8fSslatteng char	IName[100];
2460728b8fSslatteng char *	rdchar();
2560728b8fSslatteng long	fbase;
2660728b8fSslatteng 
2760728b8fSslatteng char	defascii[256];
2860728b8fSslatteng char	*charswanted = defascii;
2960728b8fSslatteng int	verbose;
3060728b8fSslatteng char	charbits[4000];
3160728b8fSslatteng int	H, W, WB, base;
3260728b8fSslatteng int 	zoom = 1;
3360728b8fSslatteng 
3460728b8fSslatteng char msgout[24][80];
3560728b8fSslatteng int msgflag = 0;
3660728b8fSslatteng int curline, curcol;	/* cursor, numbered from lower left corner */
3760728b8fSslatteng int minline=24, maxline=0, maxcol=0;
3860728b8fSslatteng 
main(argc,argv)3960728b8fSslatteng main(argc,argv)
4060728b8fSslatteng int argc;
4160728b8fSslatteng char **argv;
4260728b8fSslatteng 
4360728b8fSslatteng {
4460728b8fSslatteng 	int FID,i,j;
4560728b8fSslatteng 
4660728b8fSslatteng 	while (argc > 1 && argv[1][0] == '-') {
4760728b8fSslatteng 		switch(argv[1][1]) {
48a1e99f02Sslatteng 		case 'z':
49a1e99f02Sslatteng 			zoom = argv[1][2] - '0';  /* zoom implies verbose */
5060728b8fSslatteng 		case 'v':
5160728b8fSslatteng 			verbose++;
5260728b8fSslatteng 			break;
5360728b8fSslatteng 		case 'm':
5460728b8fSslatteng 			msgflag = 1;
5560728b8fSslatteng 			zoom = 2;
5660728b8fSslatteng 			for (i=0; i<24; i++)
5760728b8fSslatteng 				for (j=0; j<80; j++)
5860728b8fSslatteng 					msgout[i][j] = ' ';
5960728b8fSslatteng 			curline = 5; curcol = 0;
6060728b8fSslatteng 			break;
6160728b8fSslatteng 		default:
6260728b8fSslatteng 			printf("Bad flag: %s\n", argv[1]);
6360728b8fSslatteng 		}
6460728b8fSslatteng 		argc--; argv++;
6560728b8fSslatteng 	}
6660728b8fSslatteng 	if (argc < 2) {
6760728b8fSslatteng 		fprintf(stderr,"Usage: %s filename", argv[0]);
6860728b8fSslatteng 		exit(2);
6960728b8fSslatteng 	}
7060728b8fSslatteng 
7160728b8fSslatteng 	for (i=0; i<128; i++)
7260728b8fSslatteng 		defascii[i] = i;
7360728b8fSslatteng 	if (argc >= 3)
7460728b8fSslatteng 		charswanted = argv[2];
7560728b8fSslatteng 
76f3f30b8cSslatteng 	sprintf(IName, "%s/%s", BITDIR, argv[1]);
7760728b8fSslatteng 	if ((FID = open(argv[1],0)) < 0)
7860728b8fSslatteng 		if ((FID = open(IName,0)) < 0) {
7960728b8fSslatteng 			printf("Can't find %s\n",argv[1]);
8060728b8fSslatteng 			exit(8);
8160728b8fSslatteng 		};
8260728b8fSslatteng 
8360728b8fSslatteng 	if (read(FID,&FontHeader,sizeof FontHeader) != sizeof FontHeader)
8460728b8fSslatteng 		error("Bad header in Font file.");
8560728b8fSslatteng 
8660728b8fSslatteng 	if (read(FID,&disptable[0],sizeof disptable) != sizeof disptable)
8760728b8fSslatteng 		error("Bad dispatch table in Font file");
8860728b8fSslatteng 
8960728b8fSslatteng 	fbase = sizeof FontHeader + sizeof disptable;
9060728b8fSslatteng 
9160728b8fSslatteng 	if (FontHeader.magic != 0436)
9260728b8fSslatteng 		printf("Magic number %o wrong\n", FontHeader.magic);
9360728b8fSslatteng 	if (!msgflag) {
9460728b8fSslatteng 		printf("Font %s, ",argv[1]);
9560728b8fSslatteng 		printf("raster size %d, ",FontHeader.size);
9660728b8fSslatteng 		printf("max width %d, max height %d, xtend %d\n",
9760728b8fSslatteng 			FontHeader.maxx, FontHeader.maxy,FontHeader.xtend);
9860728b8fSslatteng 		printf("\n");
9960728b8fSslatteng 		for (i = strlen(argv[1]) + 1; i > 0; --i)
10060728b8fSslatteng 			printf(" ");
10160728b8fSslatteng 		printf("ASCII     offset    size  left    right   up     down    width \n");
10260728b8fSslatteng 	}
10360728b8fSslatteng 
10460728b8fSslatteng 	for (i=0; i<256; i++) {
10560728b8fSslatteng 		j = charswanted[i];
10660728b8fSslatteng 		if (i>0 && j==0)
10760728b8fSslatteng 			break;
10860728b8fSslatteng 		if (disptable[j].nbytes != 0) {
10960728b8fSslatteng 			if (!msgflag)
11060728b8fSslatteng 				printf("%s  %3o %2s     %4d   %4d   %4d   %4d   %4d   %4d   %5d\n",
11160728b8fSslatteng 					argv[1],
11260728b8fSslatteng 					j, rdchar(j),
11360728b8fSslatteng 					disptable[j].addr,
11460728b8fSslatteng 					disptable[j].nbytes,
11560728b8fSslatteng 					disptable[j].left,
11660728b8fSslatteng 					disptable[j].right,
11760728b8fSslatteng 					disptable[j].up,
11860728b8fSslatteng 					disptable[j].down,
11960728b8fSslatteng 					disptable[j].width);
12060728b8fSslatteng 			if (verbose || msgflag) {
12160728b8fSslatteng 				int len = disptable[j].nbytes;
12260728b8fSslatteng 				int k, l, last;
12360728b8fSslatteng 
12460728b8fSslatteng 				lseek(FID, fbase+disptable[j].addr, 0);
12560728b8fSslatteng 				read(FID, charbits, len);
12660728b8fSslatteng 				H = (disptable[j].up) + (disptable[j].down);
12760728b8fSslatteng 				W = (disptable[j].left) + (disptable[j].right);
12860728b8fSslatteng 				base = disptable[j].up;
129*4d151695Sslatteng #ifdef sun
130*4d151695Sslatteng 				WB = ((W+15)/16)*2;
131*4d151695Sslatteng #else
13260728b8fSslatteng 				WB = (W+7)/8;
133*4d151695Sslatteng #endif
13460728b8fSslatteng 				shozoom();
13560728b8fSslatteng 				if (msgflag) {
13660728b8fSslatteng 					k = disptable[j].width;
13760728b8fSslatteng 					if (zoom == 0) k *= 2;
13860728b8fSslatteng 					else if (zoom == 2) k /= 2;
13960728b8fSslatteng 					curcol += k;
14060728b8fSslatteng 				}
14160728b8fSslatteng 			}
14260728b8fSslatteng 		}
14360728b8fSslatteng 	}
14460728b8fSslatteng 	if (msgflag) {
14560728b8fSslatteng 		for (i=maxline; i>=minline; i--) {
14660728b8fSslatteng 			for (j=0; j<maxcol; j++)
14760728b8fSslatteng 				putchar(msgout[i][j]);
14860728b8fSslatteng 			putchar('\n');
14960728b8fSslatteng 		}
15060728b8fSslatteng 	}
151f1fe4600Sslatteng 	exit(0);
15260728b8fSslatteng }
15360728b8fSslatteng 
error(string)15460728b8fSslatteng error(string)
15560728b8fSslatteng char *string;
15660728b8fSslatteng 
15760728b8fSslatteng {
15860728b8fSslatteng 	printf("\nvfontinfo: %s\n",string);
15960728b8fSslatteng 	exit(8);
16060728b8fSslatteng };
16160728b8fSslatteng 
rdchar(c)16260728b8fSslatteng char *rdchar(c)
16360728b8fSslatteng char c;
16460728b8fSslatteng {
16560728b8fSslatteng 	static char ret[3];
16660728b8fSslatteng 	ret[0] = isprint(c) ? ' ' : '^';
16760728b8fSslatteng 	ret[1] = isprint(c) ?  c  : c^0100;
16860728b8fSslatteng 	ret[2] = 0;
16960728b8fSslatteng 	return (ret);
17060728b8fSslatteng }
17160728b8fSslatteng 
17260728b8fSslatteng int
fbit(row,col)17360728b8fSslatteng fbit(row, col)
17460728b8fSslatteng int row, col;
17560728b8fSslatteng {
17660728b8fSslatteng 	int thisbyte, thisbit, ret;
17760728b8fSslatteng 
17860728b8fSslatteng 	if (row<0 || row>=H || col>=W) return(0);
17960728b8fSslatteng 	thisbyte = charbits[row*WB + (col>>3)] & 0xff;
18060728b8fSslatteng 	thisbit = 0x80 >> (col&7);
18160728b8fSslatteng 	ret = thisbyte & thisbit;
18260728b8fSslatteng 	return (ret != 0);
18360728b8fSslatteng }
18460728b8fSslatteng 
18560728b8fSslatteng 
18660728b8fSslatteng /*
18760728b8fSslatteng The implementation would work like this:
18860728b8fSslatteng 	zoom level	method
18960728b8fSslatteng 	0		2 chars/pixel, 1 is "[]", 0 is "  ".
19060728b8fSslatteng 	1		2 pixels/char 2x1, using " " "," "'" "|"
19160728b8fSslatteng 	2		8 pixels/char 4x2, using 16x16 table
19260728b8fSslatteng 	3		32 pixels/char 8x4, mapped into (2)
19360728b8fSslatteng 	4 and up	similar, mapped into (2)
19460728b8fSslatteng 
19560728b8fSslatteng The 16x16 table maps a 4x2 pattern into a printing ascii character which
19660728b8fSslatteng most closely approximates that pattern, e.g. the pattern
19760728b8fSslatteng 	|'
19860728b8fSslatteng 	''
19960728b8fSslatteng would be represented by the character "[".  I have such a table worked out.
20060728b8fSslatteng 
20160728b8fSslatteng Grainer zoom levels would take the rule of reducing it into a smaller bitmap,
20260728b8fSslatteng or-ing the bits together.  (e.g. level 3 would take a 2x2 chunk and map it
20360728b8fSslatteng into a single pixel: 0 if all 4 are 0, 1 otherwise.)  These pixels would be
20460728b8fSslatteng displayed as in 2.
20560728b8fSslatteng */
20660728b8fSslatteng 
20760728b8fSslatteng /*
20860728b8fSslatteng  * graphtab: a table for rudimentary graphics on ordinary terminals.
20960728b8fSslatteng  * For each 4x2 bit pattern of the form:
21060728b8fSslatteng  *	ae
21160728b8fSslatteng  *	bf
21260728b8fSslatteng  *	cg
21360728b8fSslatteng  *	dh
21460728b8fSslatteng  * form the 4 bit quantities abcd and efgh and get table entry
21560728b8fSslatteng  *	graphtab[abcd][efgh]
21660728b8fSslatteng  * to display in that character position.
21760728b8fSslatteng  *
21860728b8fSslatteng  * General philosophies: the dh bits are intended for descenders where
21960728b8fSslatteng  * possible.  Characters with radically different appearance on different
22060728b8fSslatteng  * terminals (e.g. _ and ^) are avoided.
22160728b8fSslatteng  *
22260728b8fSslatteng  * Version 1.0, March 1981, Mark Horton.
22360728b8fSslatteng  */
22460728b8fSslatteng 
22560728b8fSslatteng char tab1[4] = {
22660728b8fSslatteng 	' ', ',', '\'', '|'
22760728b8fSslatteng };
22860728b8fSslatteng 
22960728b8fSslatteng char graphtab[16][16] = {
23060728b8fSslatteng ' ', '.', '.', ',', '.', ';', ':', 'j', '\'', ':', ':', ';', '\'', ';', '!', '|',
23160728b8fSslatteng '.', '.', ':', ',', ';', ';', ';', 'j', '/', ';', ';', ';', 'j', 'j', 'j', 'j',
23260728b8fSslatteng '.', ',', '~', ',', 'r', '<', 'j', 'q', '/', ';', 'I', ';', '/', '|', 'I', '|',
23360728b8fSslatteng ',', ',', 'r', 'x', '/', '/', '/', 'd', '/', '/', '/', 'd', '/', '/', '/', 'd',
23460728b8fSslatteng '.', ':', '\\', ';', '-', '=', 'v', 'q', '\'', ':', '<', '|', '\'', ':', '+', '+',
23560728b8fSslatteng ';', ';', '>', ';', '=', '=', 'g', 'g', '\'', ':', 'S', 'S', '/', '/', '/', '+',
23660728b8fSslatteng ':', '\\', '\\', '\\', 'r', '<', 'w', 'q', '/', '<', '6', '4', '/', '/', 'd', '+',
23760728b8fSslatteng 'l', 'L', '+', 'b', 'y', '[', 'p', 'g', '/', '<', '/', '6', '/', '/', '/', '+',
23860728b8fSslatteng '`', ':', ':', ';', '`', '\\', '\\', '\\', '"', ':', ':', ';', '`', '\\', 'Y', 'T',
23960728b8fSslatteng ';', ';', ';', ';', '`', '2', '>', '\\', ':', '=', ';', ';', '?', '?', ']', ']',
24060728b8fSslatteng ':', ';', ';', ';', '>', '2', '>', '\\', 'F', ';', 'O', ';', '7', '?', ']', '7',
24160728b8fSslatteng ';', ';', ';', ';', '?', '2', '>', 'b', ';', ';', ';', ';', '?', '?', ']', '#',
24260728b8fSslatteng '\'', '\\', '\\', '\\', '`', '\\', '\\', '\\', '\'', '\'', '<', '5', '"', '"', 'v', 'q',
24360728b8fSslatteng ';', '\\', '\\', '\\', '`', '=', '\\', '\\', '\'', '\'', '5', '5', '"', '?', 'g', 'g',
24460728b8fSslatteng 'I', 'L', 'L', 'L', 'D', '\\', 'b', 'f', 'F', '[', '[', '[', 'P', '?', '#', 'M',
24560728b8fSslatteng '|', '|', '|', '|', '|', '#', '+', '#', 'T', '[', 'F', 'F', 'P', '?', 'P', 'M'
24660728b8fSslatteng };
24760728b8fSslatteng 
24860728b8fSslatteng 
shozoom()24960728b8fSslatteng shozoom()
25060728b8fSslatteng {
25160728b8fSslatteng 	register i;
25260728b8fSslatteng 
25360728b8fSslatteng 	if (zoom == 0)
25460728b8fSslatteng 		sho0();
25560728b8fSslatteng 	else if (zoom == 1)
25660728b8fSslatteng 		sho1();
25760728b8fSslatteng 	else if (zoom == 2)
25860728b8fSslatteng 		sho2();
25960728b8fSslatteng }
26060728b8fSslatteng 
sho0()26160728b8fSslatteng sho0()
26260728b8fSslatteng {
26360728b8fSslatteng 	register k,l;
26460728b8fSslatteng 
26560728b8fSslatteng 	for (k=0; k<H; k++) {
26660728b8fSslatteng 		for (l=0; l<W; l++)
26760728b8fSslatteng 			printf("%s", fbit(k,l)?"[]": "  ");
26860728b8fSslatteng 		printf("\n");
26960728b8fSslatteng 	}
27060728b8fSslatteng 	printf("\n");
27160728b8fSslatteng }
27260728b8fSslatteng 
sho1()27360728b8fSslatteng sho1()
27460728b8fSslatteng {
27560728b8fSslatteng 	register k,l;
27660728b8fSslatteng 
27760728b8fSslatteng 	k = 0;
27860728b8fSslatteng 	for (k = 0; k <= H; k += 2) {
27960728b8fSslatteng 		for(l=0;l<W;l++) putchar(tab1[(fbit(k,l) << 1) | fbit(k+1,l)]);
28060728b8fSslatteng 		putchar('\n');
28160728b8fSslatteng 	}
28260728b8fSslatteng 	putchar('\n');
28360728b8fSslatteng }
28460728b8fSslatteng 
sho2()28560728b8fSslatteng sho2()
28660728b8fSslatteng {
28760728b8fSslatteng 	register i,j,k,l;
28860728b8fSslatteng 	int line = curline + (base+3)/4;
28960728b8fSslatteng 	int col;
29060728b8fSslatteng 
29160728b8fSslatteng 	k = base%4;
29260728b8fSslatteng 	if (k > 0) k -= 4;
29360728b8fSslatteng 	while (k < H) {
29460728b8fSslatteng 		l = 0;
29560728b8fSslatteng 		col = curcol;
29660728b8fSslatteng 		while (l<W) {
29760728b8fSslatteng 			i = fbit(k,l)*8 + fbit(k+1,l)*4 +
29860728b8fSslatteng 			    fbit(k+2,l)*2 + fbit(k+3,l);
29960728b8fSslatteng 			l++;
30060728b8fSslatteng 			j = fbit(k,l)*8 + fbit(k+1,l)*4 +
30160728b8fSslatteng 			    fbit(k+2,l)*2 + fbit(k+3,l);
30260728b8fSslatteng 
30360728b8fSslatteng 			if (msgflag) {
30460728b8fSslatteng 				if (graphtab[i][j] != ' ') {
30560728b8fSslatteng 					if (line > maxline) maxline = line;
30660728b8fSslatteng 					if (line < minline) minline = line;
30760728b8fSslatteng 					if (col > maxcol)   maxcol  = col;
30860728b8fSslatteng 				}
30960728b8fSslatteng 				msgout[line][col] = graphtab[i][j];
31060728b8fSslatteng 			} else
31160728b8fSslatteng 				printf("%c",graphtab[i][j]);
31260728b8fSslatteng 			l++;
31360728b8fSslatteng 			col++;
31460728b8fSslatteng 		}
31560728b8fSslatteng 		if (msgflag == 0)
31660728b8fSslatteng 			printf("\n");
31760728b8fSslatteng 		k += 4;
31860728b8fSslatteng 		line--;
31960728b8fSslatteng 	}
32060728b8fSslatteng 	if (msgflag == 0)
32160728b8fSslatteng 		printf("\n");
32260728b8fSslatteng }
323