@@ -20,7 +20,8 @@ def _fn_name(): return sys._getframe(1).f_code.co_name
20
20
21
21
from matplotlib .font_manager import fontManager
22
22
from matplotlib .ft2font import FT2Font , KERNING_UNFITTED , KERNING_DEFAULT , KERNING_UNSCALED
23
- from matplotlib .mathtext import math_parse_s_ps , bakoma_fonts
23
+ from matplotlib .ttf2ps import convert_ttf_to_ps
24
+ from matplotlib .mathtext import math_parse_s_ps
24
25
from matplotlib .text import Text
25
26
26
27
from matplotlib .transforms import get_vec6_scales
@@ -29,6 +30,7 @@ def _fn_name(): return sys._getframe(1).f_code.co_name
29
30
fromstring , nonzero , ones , put , take , where , isnan
30
31
import binascii
31
32
import re
33
+ import sets
32
34
33
35
if sys .platform .startswith ('win' ): cmd_split = '&'
34
36
else : cmd_split = ';'
@@ -97,11 +99,6 @@ def quote_ps_string(s):
97
99
return s
98
100
99
101
100
- _fontd = {}
101
- _afmfontd = {}
102
- _type42 = []
103
-
104
-
105
102
def seq_allequal (seq1 , seq2 ):
106
103
"""
107
104
seq1 and seq2 are either None or sequences or numerix arrays
@@ -145,6 +142,17 @@ def __init__(self, width, height, pswriter, dpi=72):
145
142
self .hatch = None
146
143
self .image_magnification = dpi / 72.0
147
144
145
+ self .fontd = {}
146
+ self .afmfontd = {}
147
+ self .used_characters = {}
148
+
149
+ def track_characters (self , font , s ):
150
+ """Keeps track of which characters are required from
151
+ each font."""
152
+ fname = font .fname
153
+ used_characters = self .used_characters .setdefault (fname , sets .Set ())
154
+ used_characters .update (s )
155
+
148
156
def set_color (self , r , g , b , store = 1 ):
149
157
if (r ,g ,b ) != self .color :
150
158
if r == g and r == b :
@@ -264,7 +272,7 @@ def get_text_width_height(self, s, prop, ismath):
264
272
265
273
if ismath :
266
274
width , height , pswriter = math_parse_s_ps (
267
- s , 72 , prop .get_size_in_points ())
275
+ s , 72 , prop .get_size_in_points (), 0 , self . track_characters )
268
276
return width , height
269
277
270
278
if rcParams ['ps.useafm' ]:
@@ -291,21 +299,19 @@ def flipy(self):
291
299
292
300
def _get_font_afm (self , prop ):
293
301
key = hash (prop )
294
- font = _afmfontd .get (key )
302
+ font = self . afmfontd .get (key )
295
303
if font is None :
296
304
font = AFM (file (fontManager .findfont (prop , fontext = 'afm' )))
297
- _afmfontd [key ] = font
305
+ self . afmfontd [key ] = font
298
306
return font
299
307
300
308
def _get_font_ttf (self , prop ):
301
309
key = hash (prop )
302
- font = _fontd .get (key )
310
+ font = self . fontd .get (key )
303
311
if font is None :
304
312
fname = fontManager .findfont (prop )
305
313
font = FT2Font (str (fname ))
306
- _fontd [key ] = font
307
- if fname not in _type42 :
308
- _type42 .append (fname )
314
+ self .fontd [key ] = font
309
315
font .clear ()
310
316
size = prop .get_size_in_points ()
311
317
font .set_size (size , 72.0 )
@@ -727,6 +733,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath):
727
733
else :
728
734
font = self ._get_font_ttf (prop )
729
735
font .set_text (s ,0 )
736
+ self .track_characters (font , s )
730
737
731
738
self .set_color (* gc .get_rgb ())
732
739
self .set_font (font .get_sfnt ()[(1 ,0 ,0 ,6 )], prop .get_size_in_points ())
@@ -753,6 +760,7 @@ def draw_unicode(self, gc, x, y, s, prop, angle):
753
760
754
761
self .set_color (* gc .get_rgb ())
755
762
self .set_font (font .get_sfnt ()[(1 ,0 ,0 ,6 )], prop .get_size_in_points ())
763
+ self .track_characters (font , s )
756
764
757
765
cmap = font .get_charmap ()
758
766
lastgind = None
@@ -800,7 +808,7 @@ def draw_mathtext(self, gc,
800
808
self ._pswriter .write ("% mathtext\n " )
801
809
802
810
fontsize = prop .get_size_in_points ()
803
- width , height , pswriter = math_parse_s_ps (s , 72 , fontsize )
811
+ width , height , pswriter = math_parse_s_ps (s , 72 , fontsize , angle , self . track_characters )
804
812
self .set_color (* gc .get_rgb ())
805
813
thetext = pswriter .getvalue ()
806
814
ps = """gsave
@@ -873,7 +881,6 @@ def push_gc(self, gc, store=1):
873
881
874
882
## write("\n")
875
883
876
-
877
884
class GraphicsContextPS (GraphicsContextBase ):
878
885
def get_capstyle (self ):
879
886
return {'butt' :0 ,
@@ -893,85 +900,6 @@ def new_figure_manager(num, *args, **kwargs):
893
900
manager = FigureManagerPS (canvas , num )
894
901
return manager
895
902
896
- def encodeTTFasPS (fontfile ):
897
- """
898
- Encode a TrueType font file for embedding in a PS file.
899
- """
900
- font = file (fontfile , 'rb' )
901
- hexdata , data = [], font .read (65520 )
902
- b2a_hex = binascii .b2a_hex
903
- while data :
904
- hexdata .append ('<%s>\n ' %
905
- '\n ' .join ([b2a_hex (data [j :j + 36 ]).upper ()
906
- for j in range (0 , len (data ), 36 )]) )
907
- data = font .read (65520 )
908
-
909
- hexdata = '' .join (hexdata )[:- 2 ] + '00>'
910
- font = FT2Font (str (fontfile ))
911
-
912
- headtab = font .get_sfnt_table ('head' )
913
- version = '%d.%d' % headtab ['version' ]
914
- revision = '%d.%d' % headtab ['fontRevision' ]
915
-
916
- dictsize = 8
917
- fontname = font .postscript_name
918
- encoding = 'StandardEncoding'
919
- fontbbox = '[%d %d %d %d]' % font .bbox
920
-
921
- posttab = font .get_sfnt_table ('post' )
922
- minmemory = posttab ['minMemType42' ]
923
- maxmemory = posttab ['maxMemType42' ]
924
-
925
- infosize = 7
926
- sfnt = font .get_sfnt ()
927
- notice = sfnt [(1 ,0 ,0 ,0 )]
928
- family = sfnt [(1 ,0 ,0 ,1 )]
929
- fullname = sfnt [(1 ,0 ,0 ,4 )]
930
- iversion = sfnt [(1 ,0 ,0 ,5 )]
931
- fixpitch = str (bool (posttab ['isFixedPitch' ])).lower ()
932
- ulinepos = posttab ['underlinePosition' ]
933
- ulinethk = posttab ['underlineThickness' ]
934
- italicang = '(%d.%d)' % posttab ['italicAngle' ]
935
-
936
- numglyphs = font .num_glyphs
937
- glyphs = []
938
- for j in range (numglyphs ):
939
- glyphs .append ('/%s %d def' % (font .get_glyph_name (j ), j ))
940
- if j != 0 and j % 4 == 0 :
941
- glyphs .append ('\n ' )
942
- else :
943
- glyphs .append (' ' )
944
- glyphs = '' .join (glyphs )
945
- data = ['%%!PS-TrueType-%(version)s-%(revision)s\n ' % locals ()]
946
- if maxmemory :
947
- data .append ('%%%%VMusage: %(minmemory)d %(maxmemory)d' % locals ())
948
- data .append ("""%(dictsize)d dict begin
949
- /FontName /%(fontname)s def
950
- /FontMatrix [1 0 0 1 0 0] def
951
- /FontType 42 def
952
- /Encoding %(encoding)s def
953
- /FontBBox %(fontbbox)s def
954
- /PaintType 0 def
955
- /FontInfo %(infosize)d dict dup begin
956
- /Notice (%(notice)s) def
957
- /FamilyName (%(family)s) def
958
- /FullName (%(fullname)s) def
959
- /version (%(iversion)s) def
960
- /isFixedPitch %(fixpitch)s def
961
- /UnderlinePosition %(ulinepos)s def
962
- /UnderlineThickness %(ulinethk)s def
963
- end readonly def
964
- /sfnts [
965
- %(hexdata)s
966
- ] def
967
- /CharStrings %(numglyphs)d dict dup begin
968
- %(glyphs)s
969
- end readonly def
970
- FontName currentdict end definefont pop""" % locals ())
971
- return '' .join (data )
972
-
973
-
974
-
975
903
class FigureCanvasPS (FigureCanvasBase ):
976
904
def draw (self ):
977
905
pass
@@ -1091,20 +1019,24 @@ def print_figure(self, outfile, dpi=72, facecolor='w', edgecolor='w',
1091
1019
1092
1020
Ndict = len (psDefs )
1093
1021
print >> fh , "%%BeginProlog"
1094
- type42 = _type42 + bakoma_fonts
1095
1022
if not rcParams ['ps.useafm' ]:
1096
- Ndict += len (type42 )
1023
+ Ndict += len (renderer . used_characters )
1097
1024
print >> fh , "/mpldict %d dict def" % Ndict
1098
1025
print >> fh , "mpldict begin"
1099
1026
for d in psDefs :
1100
1027
d = d .strip ()
1101
1028
for l in d .split ('\n ' ):
1102
1029
print >> fh , l .strip ()
1103
1030
if not rcParams ['ps.useafm' ]:
1104
- for font in type42 :
1105
- print >> fh , "%%BeginFont: " + FT2Font (str (font )).postscript_name
1106
- print >> fh , encodeTTFasPS (font )
1107
- print >> fh , "%%EndFont"
1031
+ for font_filename , chars in renderer .used_characters .items ():
1032
+ font = FT2Font (font_filename )
1033
+ cmap = font .get_charmap ()
1034
+ glyph_ids = []
1035
+ for c in chars :
1036
+ ccode = ord (c )
1037
+ gind = cmap .get (ccode ) or 0
1038
+ glyph_ids .append (gind )
1039
+ convert_ttf_to_ps (font_filename , fh , rcParams ['ps.fonttype' ], glyph_ids )
1108
1040
print >> fh , "end"
1109
1041
print >> fh , "%%EndProlog"
1110
1042
0 commit comments