#ifndef lint static char rcsid[] = "$Header$"; #endif FIXME (use new tfm library routines) #include #include "../h/types.h" #include "../h/fio.h" char *ProgName; char *getenv (); struct tfmheader { int th_lf; /* length of the file (words) */ int th_lh; /* length of the header data (words) */ int th_bc; /* smallest char code in font */ int th_ec; /* largest char code in font (inclusive) */ int th_nw; /* number of words in width table */ int th_nh; /* number of words in height table */ int th_nd; /* number of words in depth table */ int th_ni; /* number of words in ital. corr. table */ int th_nl; /* number of words in lig/kern table */ int th_nk; /* number of words in kern table */ int th_ne; /* number of words in extensible char table */ int th_np; /* number of font param words */ }; /* * The rest of the TFM file is composed of the following information, * all of which are 32 bit quantities: * * header: array [0..lh-1] of stuff * char_info: array [bc..ec] of char_info_word * width: array [0..nw-1] of fix_word * height: array [0..nh-1] of fix_word * depth: array [0..nd-1] of fix_word * italic: array [0..ni-1] of fix_word * lig_kern: array [0..nl-1] of lig_kern_command * kern: array [0..nk-1] of fix_word * exten: array [0..ne-1] of extensible_recipie * param: array [1..np] of fix_word * * We are interested only in the width information. This can be * found by taking the first byte of each of the char_info_words * and using it as an index in the width table. That is, the * width of character $n$ is width[char_info[$n$-$bc$].width_index]. */ struct char_info_word { char width_index; char height_and_depth_index; char italic_index_and_tag; char remainder; }; char *tfname; FILE *tf; struct tfmheader th; i32 *width; struct char_info_word *char_info; #ifdef notdef extern char *optarg; extern int optind; #endif extern int errno; main (argc, argv) int argc; char **argv; { register int i; ProgName = argv[0]; if (argc != 2) error (1, 0, "usage: %s tfmfile\n", ProgName); tfname = argv[1]; if ((tf = fopen (tfname, "r")) == NULL) error (1, errno, "can't open %s", tfname); ReadTFMHeader (); if (th.th_ec < th.th_bc) error (1, 0, "no characters in %s!?", tfname); if (th.th_bc < 0 || th.th_ec > 127) error (1, 0, "I don't see how %s can correspond to a PXL file.", tfname); AllocateCharTable (th.th_ec - th.th_bc + 1); AllocateWidthTable (th.th_nw); SkipHeader (); ReadCharInfo (th.th_ec - th.th_bc + 1); ReadWidthTable (th.th_nw); for (i = th.th_bc; i <= th.th_ec; i++) show (i); exit (0); } show (c) register int c; { long w = width[char_info[c - th.th_bc].width_index]; char buf[3]; char *blanks; if (c >= 32 && c < 127) buf[0] = c, buf[1] = 0, blanks = " "; else buf[0] = '^', buf[1] = c ^ 64, buf[2] = 0, blanks = ""; printf ("%3d (%s)%s width = %9ld\n", c, buf, blanks, w); } AllocateCharTable (n) register int n; { char_info = (struct char_info_word *) malloc (n * sizeof *char_info); if (char_info == 0) error (1, errno, "unable to allocate %d char table entries", n); } AllocateWidthTable (n) register int n; { width = (i32 *) malloc (n * sizeof *width); if (width == 0) error (1, errno, "unable to allocate %d width table entries", n); } /* ``cheating'' */ ReadTFMHeader () { register int *ip, i; for (ip = &th.th_lf; ip <= &th.th_np;) { i = UnSign16 (GetWord (tf)); *ip++ = i; } } SkipHeader () { fseek (tf, (long) th.th_lh * sizeof (i32), 1); } ReadCharInfo (n) register int n; { register struct char_info_word *ci; for (ci = char_info; --n >= 0; ci++) { ci -> width_index = getc (tf); ci -> height_and_depth_index = getc (tf); ci -> italic_index_and_tag = getc (tf); ci -> remainder = getc (tf); } if (feof (tf)) error (1, 0, "unexpected EOF -- are you sure %s is a tfm file?", tfname); } ReadWidthTable (n) register int n; { register i32 *ip; for (ip = width; --n >= 0; ip++) fGetLong (tf, *ip); if (feof (tf)) error (1, 0, "unexpected EOF -- are you sure %s is a tfm file?", tfname); }