2 from pyx
import font
, pykpathsea
3 from pyx
.font
import t1file
, afmfile
4 from pyx
.dvi
import encfile
6 class UnsupportedFontFormat(Exception):
9 class UnsupportedPSFragment(Exception):
16 tokenpattern
= re
.compile(r
'"(.*?)("\s+|"$|$)|(.*?)(\s+|$)')
18 def __init__(self
, s
):
19 """ construct font mapping from line s of font mapping file """
20 self
.texname
= self
.basepsname
= self
.fontfilename
= None
23 self
.encodingfilename
= None
25 # supported postscript fragments occuring in psfonts.map
26 # XXX extendfont not yet implemented
27 self
.reencodefont
= self
.extendfont
= self
.slant
= None
29 # cache for openend font and encoding
31 self
._encoding
= _marker
35 match
= self
.tokenpattern
.match(s
)
37 if match
.groups()[0] is not None:
38 tokens
.append('"%s"' % match
.groups()[0])
40 tokens
.append(match
.groups()[2])
43 raise RuntimeError("Cannot tokenize string '%s'" % s
)
45 next_token_is_encfile
= False
47 if next_token_is_encfile
:
48 self
.encodingfilename
= token
49 next_token_is_encfile
= False
50 elif token
.startswith("<"):
52 next_token_is_encfile
= True
53 elif token
.startswith("<<"):
54 # XXX: support non-partial download here
55 self
.fontfilename
= token
[2:]
56 elif token
.startswith("<["):
57 self
.encodingfilename
= token
[2:]
58 elif token
.endswith(".pfa") or token
.endswith(".pfb"):
59 self
.fontfilename
= token
[1:]
60 elif token
.endswith(".enc"):
61 self
.encodingfilename
= token
[1:]
62 elif token
.endswith(".ttf"):
63 raise UnsupportedFontFormat("TrueType font")
65 raise RuntimeError("Unknown token '%s'" % token
)
66 elif token
.startswith('"'):
67 pscode
= token
[1:-1].split()
68 # parse standard postscript code fragments
73 raise UnsupportedPSFragment("Unsupported Postscript fragment '%s'" % pscode
)
75 if cmd
== "ReEncodeFont":
76 self
.reencodefont
= arg
77 elif cmd
== "ExtendFont":
79 elif cmd
== "SlantFont":
80 self
.slant
= float(arg
)
82 raise UnsupportedPSFragment("Unsupported Postscript fragment '%s %s'" % (arg
, cmd
))
84 if self
.texname
is None:
87 self
.basepsname
= token
88 if self
.basepsname
is None:
89 self
.basepsname
= self
.texname
91 def getfontname(self
):
92 return self
.basepsname
95 if self
._font
is None:
96 if self
.fontfilename
is not None:
97 fontpath
= pykpathsea
.find_file(self
.fontfilename
, pykpathsea
.kpse_type1_format
)
99 raise RuntimeError("cannot find type 1 font %s" % self
.fontfilename
)
100 if fontpath
.endswith(".pfb"):
101 t1font
= t1file
.PFBfile(fontpath
)
103 t1font
= t1file
.PFAfile(fontpath
)
104 assert self
.basepsname
== t1font
.name
, "corrupt MAP file"
105 metricpath
= pykpathsea
.find_file(self
.fontfilename
.replace(".pfb", ".afm"), pykpathsea
.kpse_afm_format
)
107 self
._font
= font
.T1font(t1font
, afmfile
.AFMfile(metricpath
))
109 self
._font
= font
.T1font(t1font
, None)
111 afmfilename
= "%s.afm" % self
.basepsname
112 metricpath
= pykpathsea
.find_file(afmfilename
, pykpathsea
.kpse_afm_format
)
114 raise RuntimeError("cannot find type 1 font metric %s" % afmfilename
)
115 self
._font
= font
.T1builtinfont(self
.basepsname
, afmfile
.AFMfile(metricpath
))
118 def getencoding(self
):
119 if self
._encoding
is _marker
:
120 if self
.encodingfilename
is not None:
121 encodingpath
= pykpathsea
.find_file(self
.encodingfilename
, pykpathsea
.kpse_tex_ps_header_format
)
123 raise RuntimeError("cannot find font encoding file %s" % self
.encodingfilename
)
124 ef
= encfile
.ENCfile(encodingpath
)
125 assert ef
.name
== "/%s" % self
.reencodefont
126 self
._encoding
= ef
.vector
129 self
._encoding
= None
130 return self
._encoding
133 return ("'%s' is '%s' read from '%s' encoded as '%s'" %
134 (self
.texname
, self
.basepsname
, self
.fontfile
, repr(self
.encodingfile
)))
138 def readfontmap(filenames
):
139 """ read font map from filename (without path) """
141 for filename
in filenames
:
142 mappath
= pykpathsea
.find_file(filename
, pykpathsea
.kpse_fontmap_format
)
143 # try also the oft-used registration as dvips config file
145 mappath
= pykpathsea
.find_file(filename
, pykpathsea
.kpse_dvips_config_format
)
147 raise RuntimeError("cannot find font mapping file '%s'" % filename
)
148 mapfile
= open(mappath
, "rU")
150 for line
in mapfile
.readlines():
153 if not (line
=="" or line
[0] in (" ", "%", "*", ";" , "#")):
156 except (RuntimeError, UnsupportedPSFragment
), e
:
157 warnings
.warn("Ignoring line %i in mapping file '%s': %s" % (lineno
, mappath
, e
))
158 except UnsupportedFontFormat
, e
:
161 fontmap
[fm
.texname
] = fm