1 static char *sccsid = "@(#)vfontinfo.c 4.4 (Berkeley) 05/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 FontHeader; 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 } 330