1*32583Sbostic /*
2*32583Sbostic * Copyright (c) 1983 Regents of the University of California.
3*32583Sbostic * All rights reserved. The Berkeley software License Agreement
4*32583Sbostic * specifies the terms and conditions for redistribution.
5*32583Sbostic */
6*32583Sbostic
7*32583Sbostic #ifndef lint
8*32583Sbostic static char sccsid[] = "@(#)vfontinfo.c 5.1 (Berkeley) 11/04/87";
9*32583Sbostic #endif /* not lint */
10*32583Sbostic
111153Sbill /* Font Information for VCat-style fonts
123820Smark * Andy Hertzfeld 4/79
131153Sbill *
141153Sbill * Modified to print Ascii chars 1/80 by Mark Horton
153820Smark * Zoom option added 5/81 by Steve Stone with tables from Mark Horton.
163821Smark * Message option added 5/31 by Mark Horton
171153Sbill */
181153Sbill #include <stdio.h>
191153Sbill #include <ctype.h>
201153Sbill #include <vfont.h>
211153Sbill
221153Sbill struct header FontHeader;
23*32583Sbostic struct dispatch disptable[256];
241153Sbill
251153Sbill char IName[100];
261153Sbill char * rdchar();
271153Sbill long fbase;
281153Sbill
291153Sbill char defascii[256];
301153Sbill char *charswanted = defascii;
311153Sbill int verbose;
321153Sbill char charbits[4000];
333821Smark int H, W, WB, base;
343821Smark int zoom = 1;
351153Sbill
363821Smark char msgout[24][80];
373821Smark int msgflag = 0;
383821Smark int curline, curcol; /* cursor, numbered from lower left corner */
393821Smark int minline=24, maxline=0, maxcol=0;
403821Smark
main(argc,argv)411153Sbill main(argc,argv)
421153Sbill int argc;
431153Sbill char **argv;
441153Sbill
451153Sbill {
461153Sbill int FID,i,j;
471153Sbill
483820Smark while (argc > 1 && argv[1][0] == '-') {
491153Sbill switch(argv[1][1]) {
501153Sbill case 'v':
511153Sbill verbose++;
521153Sbill break;
533820Smark case 'z':
543820Smark zoom = argv[1][2] - '0';
553820Smark break;
563821Smark case 'm':
573821Smark msgflag = 1;
583821Smark zoom = 2;
593821Smark for (i=0; i<24; i++)
603821Smark for (j=0; j<80; j++)
613821Smark msgout[i][j] = ' ';
623821Smark curline = 5; curcol = 0;
633821Smark break;
641153Sbill default:
651153Sbill printf("Bad flag: %s\n", argv[1]);
661153Sbill }
671153Sbill argc--; argv++;
681153Sbill }
691153Sbill if (argc < 2) {
701153Sbill fprintf(stderr,"Usage: %s filename", argv[0]);
711153Sbill exit(2);
721153Sbill }
731153Sbill
741153Sbill for (i=0; i<128; i++)
751153Sbill defascii[i] = i;
761153Sbill if (argc >= 3)
771153Sbill charswanted = argv[2];
781153Sbill
791153Sbill sprintf(IName,"/usr/lib/vfont/%s",argv[1]);
801153Sbill if ((FID = open(argv[1],0)) < 0)
811153Sbill if ((FID = open(IName,0)) < 0) {
821153Sbill printf("Can't find %s\n",argv[1]);
831153Sbill exit(8);
841153Sbill };
851153Sbill
861153Sbill if (read(FID,&FontHeader,sizeof FontHeader) != sizeof FontHeader)
871153Sbill error("Bad header in Font file.");
881153Sbill
891153Sbill if (read(FID,&disptable[0],sizeof disptable) != sizeof disptable)
901153Sbill error("Bad dispatch table in Font file");
911153Sbill
921153Sbill fbase = sizeof FontHeader + sizeof disptable;
931153Sbill
941153Sbill if (FontHeader.magic != 0436)
953821Smark printf("Magic number %o wrong\n", FontHeader.magic);
963821Smark if (!msgflag) {
973821Smark printf("Font %s, ",argv[1]);
983821Smark printf("raster size %d, ",FontHeader.size);
993821Smark printf("max width %d, max height %d, xtend %d\n",
1003821Smark FontHeader.maxx, FontHeader.maxy,FontHeader.xtend);
101*32583Sbostic printf("\n");
102*32583Sbostic for (i = strlen(argv[1]) + 1; i > 0; --i)
103*32583Sbostic printf(" ");
104*32583Sbostic printf("ASCII offset size left right up down width \n");
1053821Smark }
1061153Sbill
1071153Sbill for (i=0; i<256; i++) {
1081153Sbill j = charswanted[i];
1091153Sbill if (i>0 && j==0)
1101153Sbill break;
1111153Sbill if (disptable[j].nbytes != 0) {
1123821Smark if (!msgflag)
113*32583Sbostic printf("%s %3o %2s %4d %4d %4d %4d %4d %4d %5d\n",
114*32583Sbostic argv[1],
1153821Smark j, rdchar(j),
1163821Smark disptable[j].addr,
1173821Smark disptable[j].nbytes,
1183821Smark disptable[j].left,
1193821Smark disptable[j].right,
1203821Smark disptable[j].up,
1213821Smark disptable[j].down,
1223821Smark disptable[j].width);
1233821Smark if (verbose || msgflag) {
1241153Sbill int len = disptable[j].nbytes;
1251153Sbill int k, l, last;
1261153Sbill
1271153Sbill lseek(FID, fbase+disptable[j].addr, 0);
1281153Sbill read(FID, charbits, len);
1291153Sbill H = (disptable[j].up) + (disptable[j].down);
1301153Sbill W = (disptable[j].left) + (disptable[j].right);
1313821Smark base = disptable[j].up;
1321153Sbill WB = (W+7)/8;
1333820Smark if (zoom < 0) {
1343821Smark /*
1353821Smark * Old 1 for 1 code. The aspect ratio
1363821Smark * is awful, so we don't use it.
1373821Smark */
1383820Smark for (k=0; k<H; k++) {
1393820Smark for (last=W-1; last >= 0; last--)
1403820Smark if (fbit(k, last))
1413820Smark break;
1423820Smark for (l=0; l<=W-1; l++) {
1433820Smark printf("%c", fbit(k,l)?'M':' ');
1443820Smark }
1453820Smark printf("\n");
1461153Sbill }
1471153Sbill printf("\n");
1483821Smark } else {
1493820Smark shozoom();
1503821Smark if (msgflag) {
1513821Smark k = disptable[j].width;
1523821Smark if (zoom == 0) k *= 2;
1533821Smark else if (zoom == 2) k /= 2;
1543821Smark curcol += k;
1553821Smark }
1563821Smark }
1571153Sbill }
1581153Sbill }
1593820Smark }
1603821Smark if (msgflag) {
1613821Smark for (i=maxline; i>=minline; i--) {
1623821Smark for (j=0; j<maxcol; j++)
1633821Smark putchar(msgout[i][j]);
1643821Smark putchar('\n');
1653821Smark }
1663821Smark }
1671153Sbill }
1681153Sbill
error(string)1691153Sbill error(string)
1701153Sbill char *string;
1711153Sbill
1721153Sbill {
1731153Sbill printf("\nvfontinfo: %s\n",string);
1741153Sbill exit(8);
1751153Sbill };
1761153Sbill
rdchar(c)1771153Sbill char *rdchar(c)
1781153Sbill char c;
1791153Sbill {
1801153Sbill static char ret[3];
1811153Sbill ret[0] = isprint(c) ? ' ' : '^';
1821153Sbill ret[1] = isprint(c) ? c : c^0100;
1831153Sbill ret[2] = 0;
1841153Sbill return (ret);
1851153Sbill }
1861153Sbill
1871153Sbill int
fbit(row,col)1881153Sbill fbit(row, col)
1891153Sbill int row, col;
1901153Sbill {
1911153Sbill int thisbyte, thisbit, ret;
1921153Sbill
1933821Smark if (row<0 || row>=H || col>=W) return(0);
1941153Sbill thisbyte = charbits[row*WB + (col>>3)] & 0xff;
1951153Sbill thisbit = 0x80 >> (col&7);
1961153Sbill ret = thisbyte & thisbit;
1971153Sbill return (ret != 0);
1981153Sbill }
1993820Smark
2003820Smark
2013820Smark /*
2023820Smark The implementation would work like this:
2033820Smark zoom level method
2043820Smark 0 2 chars/pixel, 1 is "[]", 0 is " ".
2053820Smark 1 2 pixels/char 2x1, using " " "," "'" "|"
2063820Smark 2 8 pixels/char 4x2, using 16x16 table
2073820Smark 3 32 pixels/char 8x4, mapped into (2)
2083820Smark 4 and up similar, mapped into (2)
2093820Smark
2103820Smark The 16x16 table maps a 4x2 pattern into a printing ascii character which
2113820Smark most closely approximates that pattern, e.g. the pattern
2123820Smark |'
2133820Smark ''
2143820Smark would be represented by the character "[". I have such a table worked out.
2153820Smark
2163820Smark Grainer zoom levels would take the rule of reducing it into a smaller bitmap,
2173820Smark or-ing the bits together. (e.g. level 3 would take a 2x2 chunk and map it
2183820Smark into a single pixel: 0 if all 4 are 0, 1 otherwise.) These pixels would be
2193820Smark displayed as in 2.
2203820Smark */
2213820Smark
2223820Smark /*
2233820Smark * graphtab: a table for rudimentary graphics on ordinary terminals.
2243820Smark * For each 4x2 bit pattern of the form:
2253820Smark * ae
2263820Smark * bf
2273820Smark * cg
2283820Smark * dh
2293820Smark * form the 4 bit quantities abcd and efgh and get table entry
2303820Smark * graphtab[abcd][efgh]
2313820Smark * to display in that character position.
2323820Smark *
2333820Smark * General philosophies: the dh bits are intended for descenders where
2343820Smark * possible. Characters with radically different appearance on different
2353820Smark * terminals (e.g. _ and ^) are avoided.
2363820Smark *
2373820Smark * Version 1.0, March 1981, Mark Horton.
2383820Smark */
2393820Smark
2403820Smark char tab1[4] = {
2413820Smark ' ', ',', '\'', '|'
2423820Smark };
2433820Smark
2443820Smark char graphtab[16][16] = {
2453820Smark ' ', '.', '.', ',', '.', ';', ':', 'j', '\'', ':', ':', ';', '\'', ';', '!', '|',
2463820Smark '.', '.', ':', ',', ';', ';', ';', 'j', '/', ';', ';', ';', 'j', 'j', 'j', 'j',
2473820Smark '.', ',', '~', ',', 'r', '<', 'j', 'q', '/', ';', 'I', ';', '/', '|', 'I', '|',
2483820Smark ',', ',', 'r', 'x', '/', '/', '/', 'd', '/', '/', '/', 'd', '/', '/', '/', 'd',
2493820Smark '.', ':', '\\', ';', '-', '=', 'v', 'q', '\'', ':', '<', '|', '\'', ':', '+', '+',
2503820Smark ';', ';', '>', ';', '=', '=', 'g', 'g', '\'', ':', 'S', 'S', '/', '/', '/', '+',
2513820Smark ':', '\\', '\\', '\\', 'r', '<', 'w', 'q', '/', '<', '6', '4', '/', '/', 'd', '+',
2523820Smark 'l', 'L', '+', 'b', 'y', '[', 'p', 'g', '/', '<', '/', '6', '/', '/', '/', '+',
2533820Smark '`', ':', ':', ';', '`', '\\', '\\', '\\', '"', ':', ':', ';', '`', '\\', 'Y', 'T',
2543820Smark ';', ';', ';', ';', '`', '2', '>', '\\', ':', '=', ';', ';', '?', '?', ']', ']',
2553820Smark ':', ';', ';', ';', '>', '2', '>', '\\', 'F', ';', 'O', ';', '7', '?', ']', '7',
2563820Smark ';', ';', ';', ';', '?', '2', '>', 'b', ';', ';', ';', ';', '?', '?', ']', '#',
2573820Smark '\'', '\\', '\\', '\\', '`', '\\', '\\', '\\', '\'', '\'', '<', '5', '"', '"', 'v', 'q',
2583820Smark ';', '\\', '\\', '\\', '`', '=', '\\', '\\', '\'', '\'', '5', '5', '"', '?', 'g', 'g',
2593820Smark 'I', 'L', 'L', 'L', 'D', '\\', 'b', 'f', 'F', '[', '[', '[', 'P', '?', '#', 'M',
2603820Smark '|', '|', '|', '|', '|', '#', '+', '#', 'T', '[', 'F', 'F', 'P', '?', 'P', 'M'
2613820Smark };
2623820Smark
2633820Smark
shozoom()2643820Smark shozoom()
2653820Smark {
2663820Smark register i;
2673820Smark
2683820Smark if (zoom == 0)
2693820Smark sho0();
2703820Smark else if (zoom == 1)
2713820Smark sho1();
2723820Smark else if (zoom == 2)
2733820Smark sho2();
2743820Smark }
2753820Smark
sho0()2763820Smark sho0()
2773820Smark {
2783820Smark register k,l;
2793820Smark
2803820Smark for (k=0; k<H; k++) {
2813820Smark for (l=0; l<W; l++)
2823820Smark printf("%s", fbit(k,l)?"[]": " ");
2833820Smark printf("\n");
2843820Smark }
2853820Smark printf("\n");
2863820Smark }
2873820Smark
sho1()2883820Smark sho1()
2893820Smark {
2903820Smark register i,k,l;
2913820Smark
2923820Smark k = 0;
2933820Smark while (k < H) {
2943820Smark for(l=0;l<W;l++) {
2953820Smark i = fbit(k,l)*2 + fbit(k+1,l);
2963820Smark printf("%c",tab1[i]);
2973820Smark l++;
2983820Smark }
2993820Smark printf("\n");
3003820Smark k += 2;
3013820Smark }
3023820Smark printf("\n");
3033820Smark }
3043820Smark
sho2()3053820Smark sho2()
3063820Smark {
3073820Smark register i,j,k,l;
3083821Smark int line = curline + (base+3)/4;
3093821Smark int col;
3103820Smark
3113821Smark k = base%4;
3123821Smark if (k > 0) k -= 4;
3133820Smark while (k < H) {
3143820Smark l = 0;
3153821Smark col = curcol;
3163820Smark while (l<W) {
3173820Smark i = fbit(k,l)*8 + fbit(k+1,l)*4 +
3183820Smark fbit(k+2,l)*2 + fbit(k+3,l);
3193820Smark l++;
3203820Smark j = fbit(k,l)*8 + fbit(k+1,l)*4 +
3213820Smark fbit(k+2,l)*2 + fbit(k+3,l);
3223820Smark
3233821Smark if (msgflag) {
3243821Smark if (graphtab[i][j] != ' ') {
3253821Smark if (line > maxline) maxline = line;
3263821Smark if (line < minline) minline = line;
3273821Smark if (col > maxcol) maxcol = col;
3283821Smark }
3293821Smark msgout[line][col] = graphtab[i][j];
3303821Smark } else
3313821Smark printf("%c",graphtab[i][j]);
3323820Smark l++;
3333821Smark col++;
3343820Smark }
3353821Smark if (msgflag == 0)
3363821Smark printf("\n");
3373820Smark k += 4;
3383821Smark line--;
3393820Smark }
3403821Smark if (msgflag == 0)
3413821Smark printf("\n");
3423820Smark }
343