2 # mftrace - Generate Type1 or TrueType font from Metafont source.
4 # Copyright (c) 2001--2006 by
5 # Han-Wen Nienhuys, Jan Nieuwenhuizen
7 # Distributed under terms of the GNU General Public License. It comes with
13 def compose_tfm_number (seq
):
14 shift
= (len (seq
)-1)*8
18 cs
= cs
+ (long (ord (b
)) << shift
)
24 # Read params, ligatures, kernings.
28 def get_string (self
):
29 b
= ord (self
.left
[0])
31 self
.left
= self
.left
[1+b
:]
36 self
.left
= self
.left
[1:]
39 def extract_fixps (self
, count
):
42 for c
in range (0,count
):
43 fs
[c
] = self
.get_fixp_number ()
47 def extract_chars (self
):
48 count
= self
.end_code
- self
.start_code
+ 1
51 for c
in range (0,count
):
62 rem
= self
.get_byte ()
64 # rem is used as index for the ligature table.
68 fs
[c
] = (w
, h
, d
, i
, lig
)
72 def get_ligatures(self
):
74 def get_kern_program (self
):
77 def __init__ (self
, f
):
81 self
.file_length
= self
.get_number (2);
82 self
.head_length
= self
.get_number (2);
83 self
.start_code
= self
.get_number (2);
84 self
.end_code
= self
.get_number (2);
85 self
.width_count
= self
.get_number (2);
86 self
.height_count
=self
.get_number(2);
87 self
.depth_count
= self
.get_number (2);
88 self
.italic_corr_count
= self
.get_number(2);
89 self
.ligature_kern_count
= self
.get_number (2);
90 self
.kern_count
= self
.get_number (2)
91 self
.extensible_word_count
=self
.get_number (2);
92 self
.parameter_count
=self
.get_number (2);
94 self
.checksum
= self
.get_number (4)
95 self
.design_size
= self
.get_fixp_number ()
96 self
.coding
= self
.get_string ()
98 self
.left
=f
[(6 + self
.head_length
) * 4:]
99 self
.chars
= self
.extract_chars ()
100 self
.widths
= self
.extract_fixps (self
.width_count
)
101 self
.heights
= self
.extract_fixps (self
.height_count
)
102 self
.depths
= self
.extract_fixps (self
.depth_count
)
103 self
.italic_corrections
= self
.extract_fixps (self
.italic_corr_count
)
104 self
.ligatures
= self
.get_ligatures ()
105 self
.kern_program
= self
.get_kern_program()
109 def get_number (self
, len):
110 n
= compose_tfm_number (self
.left
[0:len])
111 self
.left
= self
.left
[len:]
114 def get_fixp_number (self
):
115 n
= self
.get_number (4)
116 n
= n
/16.0 / (1<<16);
121 keys
= ['start_code', 'end_code', 'checksum', 'design_size', 'coding', 'chars', 'widths', 'heights', 'depths', 'italic_corrections', 'ligatures', 'kern_program']
122 tfm
= Tex_font_metric ()
124 tfm
.__dict
__[k
] = self
.__dict
__[k
]
130 def __init__(self
, tfm
, tup
):
131 (w
, h
, d
, i
, lig
) = tup
133 self
.width
= tfm
.widths
[w
] *ds
134 self
.height
= tfm
.heights
[h
] *ds
135 self
.depth
= tfm
.depths
[d
] * ds
136 self
.italic_correction
= tfm
.italic_corrections
[i
]*ds
140 class Tex_font_metric
:
142 Bare bones wrapper around the TFM format.
149 def has_char (self
, code
):
150 if code
< self
.start_code
or code
> self
.end_code
:
153 tup
= self
.chars
[code
- self
.start_code
]
156 def get_char (self
,code
):
157 tup
= self
.chars
[code
- self
.start_code
]
158 return Char_metric (self
, tup
)
161 return r
"""#<TFM file
165 coding: %s>""" % (self
.start_code
, self
.end_code
,
166 self
.checksum
, self
.design_size
, self
.coding
)
170 def read_tfm_file (fn
):
171 reader
=Tfm_reader (open (fn
).read ())
172 return reader
.get_tfm ()
174 if __name__
=='__main__':
175 t
= read_tfm_file (sys
.argv
[1])
176 print t
, t
.design_size
, t
.coding