summaryrefslogtreecommitdiff
path: root/dviware/umddvi/misc/showtfmwidth.c
blob: 71c2f27cc8afe4ec38c491bd1d6a1661f6a58e19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#ifndef lint
static char rcsid[] = "$Header$";
#endif

FIXME (use new tfm library routines)

#include <stdio.h>
#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);
}