1*26455Sslatteng static char sccsid[] = "ifontinfo.c	1.7	(Berkeley)	86/03/04";
214682Sslatteng 
314682Sslatteng /* Font Information for Imagen-style fonts (RST format)
414682Sslatteng  *      taken from vfontinfo, by Andy Hertzfeld  4/79
514682Sslatteng  */
614682Sslatteng 
714682Sslatteng #include <stdio.h>
814682Sslatteng #include <ctype.h>
914682Sslatteng #include "rst.h"
1014682Sslatteng 
1118120Sslatteng #ifndef BITDIR
1218120Sslatteng #define  BITDIR	"/usr/src/local/imagen/fonts/raster"
1318120Sslatteng #endif
1414682Sslatteng 
1514682Sslatteng char *	rdchar();
1614682Sslatteng char *	malloc();
1714682Sslatteng 
1815281Sslatteng char *idstrings;		/* place for identifying strings */
1915281Sslatteng char *endstring;		/* points to the end of the id strings */
2014682Sslatteng double	fixtowdth;		/* "fix" and magnification conversion factor */
2114682Sslatteng glyph_dir g[DIRSIZ];		/* directory of glyph definitions */
2214682Sslatteng preamble p;			/* set of variables for preamble */
2314682Sslatteng 
2418120Sslatteng char	*fontdir = BITDIR;	/* place to look for fonts */
2514682Sslatteng char	IName[100];		/* input file name put here */
2614682Sslatteng char	*rdchar ();		/* function makes strings for ascii */
2715281Sslatteng FILE *	FID;			/* input file number */
2814682Sslatteng 
2915281Sslatteng char	defascii[DIRSIZ];	/* list of ascii characters - in order */
3014682Sslatteng char	*charswanted = defascii;/* list of characters to print info for */
3114682Sslatteng int	verbose = 0;		/* flag - whether to actually show chars */
3214682Sslatteng char	charbits[10000];	/* place to store bits for a glyph */
3314682Sslatteng int	gbase;			/* base address of glyphs in RST file */
3414682Sslatteng int	H, W, WB, base;
3514682Sslatteng int 	zoom = 1;
3614682Sslatteng 
3714682Sslatteng char	msgout[24][80];		/* place to store glyphs to print later */
3814682Sslatteng int	msgflag = 0;		/* flag - use msgout and print later? */
3914682Sslatteng int	curline, curcol;	/* cursor, numbered from lower left corner */
4014682Sslatteng int	minline = 24;
4114682Sslatteng int	maxline = 0;
4214682Sslatteng int	maxcol = 0;
4314682Sslatteng 
4414682Sslatteng 
main(argc,argv)4514682Sslatteng main(argc,argv)
4614682Sslatteng int argc;
4714682Sslatteng char **argv;
4814682Sslatteng {
4914682Sslatteng 	register int i;
5014682Sslatteng 	register int j;
5114682Sslatteng 
5214682Sslatteng 	while (argc > 1 && argv[1][0] == '-') {
5314682Sslatteng 		switch(argv[1][1]) {
5416074Sslatteng 		case 'z':
5516074Sslatteng 			zoom = argv[1][2] - '0';  /* zoom implies verbose */
5614682Sslatteng 		case 'v':
5714682Sslatteng 			verbose++;
5814682Sslatteng 			break;
5914682Sslatteng 		case 'm':
6014682Sslatteng 			msgflag = 1;
6114682Sslatteng 			zoom = 2;
6214682Sslatteng 			for (i=0; i<24; i++)
6314682Sslatteng 				for (j=0; j<80; j++)
6414682Sslatteng 					msgout[i][j] = ' ';
6514682Sslatteng 			curline = 5; curcol = 0;
6614682Sslatteng 			break;
6714682Sslatteng 		default:
6815281Sslatteng 			error("bad flag: %s", argv[1]);
6914682Sslatteng 		}
7014682Sslatteng 		argc--; argv++;
7114682Sslatteng 	}
7215281Sslatteng 	if (argc < 2)
7315281Sslatteng 		error("usage: %s filename", argv[0]);
7414682Sslatteng 
7515281Sslatteng 	for (i=0; i<DIRSIZ; i++)
7614682Sslatteng 		defascii[i] = i;
7714682Sslatteng 	if (argc >= 3)
7814682Sslatteng 		charswanted = argv[2];
7914682Sslatteng 
8014682Sslatteng 	sprintf(IName, "%s/%s", fontdir, argv[1]);
8115281Sslatteng 	if ((FID = fopen(argv[1], "r")) == NULL)
8215281Sslatteng 		if ((FID = fopen(IName, "r")) == NULL)
8315281Sslatteng 			error("can't find %s",argv[1]);
8414682Sslatteng 
8515281Sslatteng 	for (i = 0; i < FMARK; filemark[i++] = getc(FID));
8615281Sslatteng 	if (strncmp(filemark, "Rast", 4))
8715281Sslatteng 	    error("bad File Mark in Font file.");
8814682Sslatteng 
8914682Sslatteng 	p.p_size = rd2();
9014682Sslatteng 	p.p_version = rd1();
9114682Sslatteng 	if (p.p_version)
9215281Sslatteng 	    error("wrong version of Font file.");
9314682Sslatteng 	p.p_glyph = rd3();
9414682Sslatteng 	p.p_first = rd2();
9514682Sslatteng 	p.p_last = rd2();
9614682Sslatteng 	p.p_mag = rd4();
9714682Sslatteng 	p.p_desiz = rd4();
9814682Sslatteng 	p.p_linesp = rd4();
9914682Sslatteng 	p.p_wordsp = rd4();
10014682Sslatteng 	p.p_rot = rd2();
10114682Sslatteng 	p.p_cadv = rd1();
10214682Sslatteng 	p.p_ladv = rd1();
10314682Sslatteng 	p.p_id = rd4();
10414682Sslatteng 	p.p_res = rd2();
10514682Sslatteng 
10614682Sslatteng 	i = p.p_glyph - 44;
10715281Sslatteng 	idstrings = (char *) malloc (i);
10815281Sslatteng 	endstring = idstrings;
10915281Sslatteng 	while (i--) if ((*(endstring++) = getc(FID)) == EOF)
11015281Sslatteng 	    error("bad preamble in Font file.");
11114682Sslatteng 
11214682Sslatteng 	for (i = p.p_first; i <= p.p_last; i++) {
11314682Sslatteng 	    g[i].g_height = rd2();
11414682Sslatteng 	    g[i].g_width = rd2();
11514682Sslatteng 	    g[i].g_up = rd2();
11614682Sslatteng 	    g[i].g_left = rd2();
11714682Sslatteng 	    g[i].g_pwidth = rd4();
11814682Sslatteng 	    g[i].g_bitp = rd3();
11914682Sslatteng 	}
12014682Sslatteng 
121*26455Sslatteng 	if ((fixtowdth = FIXIN * p.p_res * p.p_mag / 1000.0) == 0.0)
122*26455Sslatteng 	    fixtowdth = FIXIN * p.p_res;
12314682Sslatteng 
12414682Sslatteng 	if (!msgflag) {
12514682Sslatteng 	printf("Font %s, size %.2f, ", argv[1], p.p_desiz * FIX);
12614682Sslatteng 	printf("first %d, last %d, res %d, ", p.p_first, p.p_last, p.p_res);
127*26455Sslatteng 	printf("mag %.2f\n", fixtowdth / (FIXIN * p.p_res));
12814682Sslatteng 	printf("spacewidth %.2f, rot %d, cadv %d, ladv %d\n",
12914682Sslatteng 		p.p_wordsp * fixtowdth, p.p_rot, p.p_cadv, p.p_ladv);
13014682Sslatteng 	while (idstrings < endstring) {
13114682Sslatteng 	    for (i = *(idstrings++); i--; ) putchar (*(idstrings++));
13215281Sslatteng 	    putchar(':');
13314682Sslatteng 	}
13415281Sslatteng 	putchar('\n');
13514682Sslatteng 
13614682Sslatteng 	for (i = strlen(argv[1]) + 1; i > 0; --i) putchar(' ');
13714682Sslatteng 	printf("ASCII     addr  height  width   up   left   pwidth\n");
13814682Sslatteng 	}
13914682Sslatteng 
14014682Sslatteng 	for (i=p.p_first; i<=p.p_last; i++) {
14114682Sslatteng 		j = charswanted[i];
14214682Sslatteng 		if (i>0 && j==0)
14314682Sslatteng 			break;
14414682Sslatteng 		if ((gbase = g[j].g_bitp) != 0) {
14514682Sslatteng 			if (!msgflag)
14614682Sslatteng 			    printf("%s  %3o  %2s  %4d %6d %6d %5d %5d  %6d\n",
14714682Sslatteng 				argv[1],  j,  rdchar(j),  gbase,  g[j].g_height,
14814682Sslatteng 				g[j].g_width,  g[j].g_up,  g[j].g_left,
14914682Sslatteng 				(int) (g[j].g_pwidth * fixtowdth));
15014682Sslatteng 			if (verbose || msgflag) {
15114682Sslatteng 				int k, l, last;
15214682Sslatteng 
15314682Sslatteng 				H = g[j].g_height;
15414682Sslatteng 				W = g[j].g_width;
15515281Sslatteng 				lseek(fileno(FID), (long) gbase, 0);
15615281Sslatteng 				read(fileno(FID), charbits, (WB = (W+7)/8) * H);
15714682Sslatteng 				base = g[j].g_up;
15814682Sslatteng 				shozoom();
15914682Sslatteng 				if (msgflag) {
16014682Sslatteng 					k = g[j].g_width;
16114682Sslatteng 					if (zoom == 0) k *= 2;
16214682Sslatteng 					else if (zoom == 2) k /= 2;
16314682Sslatteng 					curcol += k;
16414682Sslatteng 				}
16514682Sslatteng 			}
16614682Sslatteng 		}
16714682Sslatteng 	}
16814682Sslatteng 	if (msgflag) {
16914682Sslatteng 		for (i=maxline; i>=minline; i--) {
17014682Sslatteng 			for (j=0; j<maxcol; j++)
17114682Sslatteng 				putchar(msgout[i][j]);
17214682Sslatteng 			putchar('\n');
17314682Sslatteng 		}
17414682Sslatteng 	}
17517908Sslatteng 	exit(0);
17614682Sslatteng }
17714682Sslatteng 
17815281Sslatteng /*VARARGS1*/
error(string,a1,a2,a3,a4)17915281Sslatteng error(string, a1, a2, a3, a4)
18014682Sslatteng char *string;
18114682Sslatteng {
18215281Sslatteng 	fprintf(stderr, "ifontinfo: ");
18315281Sslatteng 	fprintf(stderr, string, a1, a2, a3, a4);
18415281Sslatteng 	fprintf(stderr, "\n");
18514682Sslatteng 	exit(8);
18614682Sslatteng };
18714682Sslatteng 
rdchar(c)18814682Sslatteng char *rdchar(c)
18914682Sslatteng char c;
19014682Sslatteng {
19114682Sslatteng 	static char ret[3];
19214682Sslatteng 	ret[0] = isprint(c) ? ' ' : '^';
19314682Sslatteng 	ret[1] = isprint(c) ?  c  : c^0100;
19414682Sslatteng 	ret[2] = 0;
19514682Sslatteng 	return (ret);
19614682Sslatteng }
19714682Sslatteng 
19814682Sslatteng int
fbit(row,col)19914682Sslatteng fbit(row, col)
20014682Sslatteng int row, col;
20114682Sslatteng {
20214682Sslatteng 	int thisbyte, thisbit, ret;
20314682Sslatteng 
20414682Sslatteng 	if (row<0 || row>=H || col>=W) return(0);
20514682Sslatteng 	thisbyte = charbits[row*WB + (col>>3)] & 0xff;
20614682Sslatteng 	thisbit = 0x80 >> (col&7);
20714682Sslatteng 	ret = thisbyte & thisbit;
20814682Sslatteng 	return (ret != 0);
20914682Sslatteng }
21014682Sslatteng 
21114682Sslatteng 
21214682Sslatteng /*
21314682Sslatteng The implementation would work like this:
21414682Sslatteng 	zoom level	method
21514682Sslatteng 	0		2 chars/pixel, 1 is "[]", 0 is "  ".
21614682Sslatteng 	1		2 pixels/char 2x1, using " " "," "'" "|"
21714682Sslatteng 	2		8 pixels/char 4x2, using 16x16 table
21814682Sslatteng 	3		32 pixels/char 8x4, mapped into (2)
21914682Sslatteng 	4 and up	similar, mapped into (2)
22014682Sslatteng 
22114682Sslatteng The 16x16 table maps a 4x2 pattern into a printing ascii character which
22214682Sslatteng most closely approximates that pattern, e.g. the pattern
22314682Sslatteng 	|'
22414682Sslatteng 	''
22514682Sslatteng would be represented by the character "[".  I have such a table worked out.
22614682Sslatteng 
22714682Sslatteng Grainer zoom levels would take the rule of reducing it into a smaller bitmap,
22814682Sslatteng or-ing the bits together.  (e.g. level 3 would take a 2x2 chunk and map it
22914682Sslatteng into a single pixel: 0 if all 4 are 0, 1 otherwise.)  These pixels would be
23014682Sslatteng displayed as in 2.
23114682Sslatteng */
23214682Sslatteng 
23314682Sslatteng /*
23414682Sslatteng  * graphtab: a table for rudimentary graphics on ordinary terminals.
23514682Sslatteng  * For each 4x2 bit pattern of the form:
23614682Sslatteng  *	ae
23714682Sslatteng  *	bf
23814682Sslatteng  *	cg
23914682Sslatteng  *	dh
24014682Sslatteng  * form the 4 bit quantities abcd and efgh and get table entry
24114682Sslatteng  *	graphtab[abcd][efgh]
24214682Sslatteng  * to display in that character position.
24314682Sslatteng  *
24414682Sslatteng  * General philosophies: the dh bits are intended for descenders where
24514682Sslatteng  * possible.  Characters with radically different appearance on different
24614682Sslatteng  * terminals (e.g. _ and ^) are avoided.
24714682Sslatteng  *
24814682Sslatteng  * Version 1.0, March 1981, Mark Horton.
24914682Sslatteng  */
25014682Sslatteng 
25114682Sslatteng char tab1[4] = {
25214682Sslatteng 	' ', ',', '\'', '|'
25314682Sslatteng };
25414682Sslatteng 
25514682Sslatteng char graphtab[16][16] = {
25614682Sslatteng ' ', '.', '.', ',', '.', ';', ':', 'j', '\'', ':', ':', ';', '\'', ';', '!', '|',
25714682Sslatteng '.', '.', ':', ',', ';', ';', ';', 'j', '/', ';', ';', ';', 'j', 'j', 'j', 'j',
25814682Sslatteng '.', ',', '~', ',', 'r', '<', 'j', 'q', '/', ';', 'I', ';', '/', '|', 'I', '|',
25914682Sslatteng ',', ',', 'r', 'x', '/', '/', '/', 'd', '/', '/', '/', 'd', '/', '/', '/', 'd',
26014682Sslatteng '.', ':', '\\', ';', '-', '=', 'v', 'q', '\'', ':', '<', '|', '\'', ':', '+', '+',
26114682Sslatteng ';', ';', '>', ';', '=', '=', 'g', 'g', '\'', ':', 'S', 'S', '/', '/', '/', '+',
26214682Sslatteng ':', '\\', '\\', '\\', 'r', '<', 'w', 'q', '/', '<', '6', '4', '/', '/', 'd', '+',
26314682Sslatteng 'l', 'L', '+', 'b', 'y', '[', 'p', 'g', '/', '<', '/', '6', '/', '/', '/', '+',
26414682Sslatteng '`', ':', ':', ';', '`', '\\', '\\', '\\', '"', ':', ':', ';', '`', '\\', 'Y', 'T',
26514682Sslatteng ';', ';', ';', ';', '`', '2', '>', '\\', ':', '=', ';', ';', '?', '?', ']', ']',
26614682Sslatteng ':', ';', ';', ';', '>', '2', '>', '\\', 'F', ';', 'O', ';', '7', '?', ']', '7',
26714682Sslatteng ';', ';', ';', ';', '?', '2', '>', 'b', ';', ';', ';', ';', '?', '?', ']', '#',
26814682Sslatteng '\'', '\\', '\\', '\\', '`', '\\', '\\', '\\', '\'', '\'', '<', '5', '"', '"', 'v', 'q',
26914682Sslatteng ';', '\\', '\\', '\\', '`', '=', '\\', '\\', '\'', '\'', '5', '5', '"', '?', 'g', 'g',
27014682Sslatteng 'I', 'L', 'L', 'L', 'D', '\\', 'b', 'f', 'F', '[', '[', '[', 'P', '?', '#', 'M',
27114682Sslatteng '|', '|', '|', '|', '|', '#', '+', '#', 'T', '[', 'F', 'F', 'P', '?', 'P', 'M'
27214682Sslatteng };
27314682Sslatteng 
27414682Sslatteng 
shozoom()27514682Sslatteng shozoom()
27614682Sslatteng {
27714682Sslatteng 	register i;
27814682Sslatteng 
27914682Sslatteng 	if (zoom == 0)
28014682Sslatteng 		sho0();
28114682Sslatteng 	else if (zoom == 1)
28214682Sslatteng 		sho1();
28314682Sslatteng 	else if (zoom == 2)
28414682Sslatteng 		sho2();
28514682Sslatteng }
28614682Sslatteng 
sho0()28714682Sslatteng sho0()
28814682Sslatteng {
28914682Sslatteng 	register k,l;
29014682Sslatteng 
29114682Sslatteng 	for (k=0; k<H; k++) {
29214682Sslatteng 		for (l=0; l<W; l++)
29314682Sslatteng 			printf("%s", fbit(k,l)?"[]": "  ");
29414682Sslatteng 		printf("\n");
29514682Sslatteng 	}
29614682Sslatteng 	printf("\n");
29714682Sslatteng }
29814682Sslatteng 
sho1()29914682Sslatteng sho1()
30014682Sslatteng {
30114682Sslatteng 	register i,k,l;
30214682Sslatteng 
30314682Sslatteng 	for (k = 0; k < H; k += 2) {
30414682Sslatteng 		for(l = 0; l < W; l++) {
30514682Sslatteng 			putchar(tab1[(fbit(k,l) << 1) | fbit(k+1,l)]);
30614682Sslatteng 		}
30714682Sslatteng 		putchar('\n');
30814682Sslatteng 	}
30914682Sslatteng 	putchar('\n');
31014682Sslatteng }
31114682Sslatteng 
sho2()31214682Sslatteng sho2()
31314682Sslatteng {
31414682Sslatteng 	register i,j,k,l;
31514682Sslatteng 	int line = curline + (base+3)/4;
31614682Sslatteng 	int col;
31714682Sslatteng 
31814682Sslatteng 	k = base%4;
31914682Sslatteng 	if (k > 0) k -= 4;
32014682Sslatteng 	while (k < H) {
32114682Sslatteng 		l = 0;
32214682Sslatteng 		col = curcol;
32314682Sslatteng 		while (l<W) {
32414682Sslatteng 			i = fbit(k,l)*8 + fbit(k+1,l)*4 +
32514682Sslatteng 			    fbit(k+2,l)*2 + fbit(k+3,l);
32614682Sslatteng 			l++;
32714682Sslatteng 			j = fbit(k,l)*8 + fbit(k+1,l)*4 +
32814682Sslatteng 			    fbit(k+2,l)*2 + fbit(k+3,l);
32914682Sslatteng 
33014682Sslatteng 			if (msgflag) {
33114682Sslatteng 				if (graphtab[i][j] != ' ') {
33214682Sslatteng 					if (line > maxline) maxline = line;
33314682Sslatteng 					if (line < minline) minline = line;
33414682Sslatteng 					if (col > maxcol)   maxcol  = col;
33514682Sslatteng 				}
33614682Sslatteng 				msgout[line][col] = graphtab[i][j];
33714682Sslatteng 			} else
33814682Sslatteng 				printf("%c",graphtab[i][j]);
33914682Sslatteng 			l++;
34014682Sslatteng 			col++;
34114682Sslatteng 		}
34214682Sslatteng 		if (msgflag == 0)
34314682Sslatteng 			printf("\n");
34414682Sslatteng 		k += 4;
34514682Sslatteng 		line--;
34614682Sslatteng 	}
34714682Sslatteng 	if (msgflag == 0)
34814682Sslatteng 		printf("\n");
34914682Sslatteng }
35014682Sslatteng 
rd1()35114682Sslatteng rd1()
35214682Sslatteng {
35315281Sslatteng     int i;
35414682Sslatteng 
35515281Sslatteng     if((i = getc(FID)) == EOF) error("file read error");
35615281Sslatteng     return i;
35714682Sslatteng }
35814682Sslatteng 
rd2()35914682Sslatteng rd2()
36014682Sslatteng {
36114682Sslatteng     register int i = rd1() << 8;
36214682Sslatteng 
36314682Sslatteng     return i + rd1();
36414682Sslatteng }
36514682Sslatteng 
rd3()36614682Sslatteng rd3()
36714682Sslatteng {
36814682Sslatteng     register int i = rd2() << 8;
36914682Sslatteng 
37014682Sslatteng     return i + rd1();
37114682Sslatteng }
37214682Sslatteng 
rd4()37314682Sslatteng rd4()
37414682Sslatteng {
37514682Sslatteng     register int i = rd2() << 16;
37614682Sslatteng 
37714682Sslatteng     return i + rd2();
37814682Sslatteng }
379