upload webpage to other dir.
[mftrace.git] / tfm.py
blob673537f3a0c1df926953b6c3273520a28a029b14
1 # this file is part of mftrace - a tool to generate scalable fonts from bitmaps
2 # This program is free software; you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License version 2
4 # as published by the Free Software Foundation
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc.,
14 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Copyright (c) 2001--2006 by
17 # Han-Wen Nienhuys, Jan Nieuwenhuizen
19 import sys
21 def compose_tfm_number (seq):
22 shift = (len (seq)-1)*8
24 cs = 0L
25 for b in seq:
26 cs = cs + (long (ord (b)) << shift)
27 shift = shift - 8
28 return cs
32 # Read params, ligatures, kernings.
35 class Tfm_reader:
36 def get_string (self):
37 b = ord (self.left[0])
38 s =self.left[1:1 + b]
39 self.left = self.left[1+b:]
41 return s
42 def get_byte (self):
43 b = self.left [0]
44 self.left= self.left[1:]
45 return ord(b)
47 def extract_fixps (self, count):
48 fs = [0.0] * count
50 for c in range (0,count):
51 fs[c] = self.get_fixp_number ()
53 return fs
55 def extract_chars (self):
56 count = self.end_code - self.start_code + 1
57 fs = [None] * count
59 for c in range (0,count):
60 w = self.get_byte()
61 b = self.get_byte()
62 h = (b & 0xf0) >> 4
63 d = (b & 0x0f)
65 b = self.get_byte ()
67 # huh? why >> 6 ?
68 i = (b & 0xfc) >> 6
69 tag = (b & 0x3)
70 rem = self.get_byte ()
72 # rem is used as index for the ligature table.
73 # TODO.
74 lig = None
76 fs[c] = (w, h, d, i, lig)
78 return fs
80 def get_ligatures(self):
81 return None
82 def get_kern_program (self):
83 return None
85 def __init__ (self, f):
86 self.string = f
87 self.left = f
89 self.file_length = self.get_number (2);
90 self.head_length = self.get_number (2);
91 self.start_code = self.get_number (2);
92 self.end_code = self.get_number (2);
93 self.width_count = self.get_number (2);
94 self.height_count =self.get_number(2);
95 self.depth_count = self.get_number (2);
96 self.italic_corr_count = self.get_number(2);
97 self.ligature_kern_count = self.get_number (2);
98 self.kern_count = self.get_number (2)
99 self.extensible_word_count =self.get_number (2);
100 self.parameter_count =self.get_number (2);
102 self.checksum = self.get_number (4)
103 self.design_size = self.get_fixp_number ()
104 self.coding = self.get_string ()
106 self.left =f[(6 + self.head_length) * 4:]
107 self.chars = self.extract_chars ()
108 self.widths = self.extract_fixps (self.width_count)
109 self.heights = self.extract_fixps (self.height_count)
110 self.depths = self.extract_fixps (self.depth_count)
111 self.italic_corrections = self.extract_fixps (self.italic_corr_count)
112 self.ligatures = self.get_ligatures ()
113 self.kern_program = self.get_kern_program()
115 del self.left
117 def get_number (self, len):
118 n = compose_tfm_number (self.left [0:len])
119 self.left = self.left[len:]
120 return n
122 def get_fixp_number (self):
123 n = self.get_number (4)
124 n = n /16.0 / (1<<16);
126 return n
128 def get_tfm (self):
129 keys = ['start_code', 'end_code', 'checksum', 'design_size', 'coding', 'chars', 'widths', 'heights', 'depths', 'italic_corrections', 'ligatures', 'kern_program']
130 tfm = Tex_font_metric ()
131 for k in keys:
132 tfm.__dict__[k] = self.__dict__[k]
133 return tfm
137 class Char_metric:
138 def __init__(self, tfm, tup):
139 (w, h, d, i, lig) = tup
140 ds = tfm.design_size
141 self.width = tfm.widths[w] *ds
142 self.height = tfm.heights[h] *ds
143 self.depth = tfm.depths [d] * ds
144 self.italic_correction = tfm.italic_corrections[i]*ds
148 class Tex_font_metric:
150 Bare bones wrapper around the TFM format.
154 def __init__ (self):
155 pass
157 def has_char (self, code):
158 if code < self.start_code or code > self.end_code:
159 return 0
161 tup = self.chars[code - self.start_code]
162 return tup[0] <> 0
164 def get_char (self,code):
165 tup = self.chars[code - self.start_code]
166 return Char_metric (self, tup)
168 def __str__ (self):
169 return r"""#<TFM file
170 char: %d, %d
171 checksum: %d
172 design_size: %f
173 coding: %s>""" % (self.start_code, self.end_code,
174 self.checksum, self.design_size, self.coding)
178 def read_tfm_file (fn):
179 reader =Tfm_reader (open (fn).read ())
180 return reader.get_tfm ()
182 if __name__=='__main__':
183 t = read_tfm_file (sys.argv[1])
184 print t, t.design_size, t.coding