66from __future__ import division
77import sys , os , time
88from cStringIO import StringIO
9- from matplotlib import verbose , __version__
9+ from matplotlib import verbose , __version__ , rcParams
1010from matplotlib ._pylab_helpers import Gcf
11+ from matplotlib .afm import AFM
1112from matplotlib .backend_bases import RendererBase , GraphicsContextBase ,\
1213 FigureManagerBase , FigureCanvasBase
1314
3435
3536def _num_to_str (val ):
3637 if is_string_like (val ): return val
38+
3739 ival = int (val )
3840 if val == ival : return str (ival )
41+
3942 s = "%1.3f" % val
4043 s = s .rstrip ("0" )
4144 s = s .rstrip ("." )
@@ -54,6 +57,7 @@ def quote_ps_string(s):
5457
5558
5659_fontd = {}
60+ _afmfontd = {}
5761_type42 = []
5862
5963
@@ -130,6 +134,7 @@ def set_linedash(self, offset, seq):
130134 self .linedash = (offset ,seq )
131135
132136 def set_font (self , fontname , fontsize ):
137+ if rcParams ['ps.useafm' ]: return
133138 if (fontname ,fontsize ) != (self .fontname ,self .fontsize ):
134139 out = ("/%s findfont\n "
135140 "%1.3f scalefont\n "
@@ -147,12 +152,23 @@ def get_text_width_height(self, s, prop, ismath):
147152 get the width and height in display coords of the string s
148153 with FontPropertry prop
149154 """
155+
156+ if rcParams ['ps.useafm' ]:
157+ if ismath : s = s [1 :- 1 ]
158+ font = self ._get_font_afm (prop )
159+ l ,b ,w ,h = font .get_str_bbox (s )
160+
161+ fontsize = prop .get_size_in_points ()
162+ w *= 0.001 * fontsize
163+ h *= 0.001 * fontsize
164+ return w , h
165+
150166 if ismath :
151167 width , height , pswriter = math_parse_s_ps (
152168 s , 72 , prop .get_size_in_points ())
153169 return width , height
154170
155- font = self ._get_font (prop )
171+ font = self ._get_font_ttf (prop )
156172 font .set_text (s , 0.0 )
157173 w , h = font .get_width_height ()
158174 w /= 64.0 # convert from subpixels
@@ -163,7 +179,15 @@ def flipy(self):
163179 'return true if small y numbers are top for renderer'
164180 return False
165181
166- def _get_font (self , prop ):
182+ def _get_font_afm (self , prop ):
183+ key = hash (prop )
184+ font = _afmfontd .get (key )
185+ if font is None :
186+ font = AFM (file (fontManager .findfont (prop , fontext = 'afm' )))
187+ _afmfontd [key ] = font
188+ return font
189+
190+ def _get_font_ttf (self , prop ):
167191 key = hash (prop )
168192 font = _fontd .get (key )
169193 if font is None :
@@ -381,26 +405,63 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath):
381405 """
382406 # local to avoid repeated attribute lookups
383407 write = self ._pswriter .write
384- if ismath :
385- return self .draw_mathtext (gc , x , y , s , prop , angle )
386408 if debugPS :
387409 write ("% text\n " )
388-
389- font = self ._get_font (prop )
390- font .set_text (s ,0 )
391410
392- self .set_color (* gc .get_rgb ())
393- self .set_font (font .get_sfnt ()[(1 ,0 ,0 ,6 )], prop .get_size_in_points ())
394- write ("%s m\n " % _nums_to_str (x ,y ))
395- if angle :
396- write ("gsave\n " )
397- write ("%s rotate\n " % _num_to_str (angle ))
398- descent = font .get_descent () / 64.0
399- if descent :
400- write ("0 %s rmoveto\n " % _num_to_str (descent ))
401- write ("(%s) show\n " % quote_ps_string (s ))
402- if angle :
403- write ("grestore\n " )
411+ if rcParams ['ps.useafm' ]:
412+ if ismath : s = s [1 :- 1 ]
413+ font = self ._get_font_afm (prop )
414+
415+ l ,b ,w ,h = font .get_str_bbox (s )
416+
417+ fontsize = prop .get_size_in_points ()
418+ l *= 0.001 * fontsize
419+ b *= 0.001 * fontsize
420+ w *= 0.001 * fontsize
421+ h *= 0.001 * fontsize
422+
423+ if angle == 90 : l ,b = - b , l # todo generalize for arb rotations
424+
425+ pos = _nums_to_str (x - l , y - b )
426+ thetext = '(%s)' % s
427+ fontname = font .get_fontname ()
428+ fontsize = prop .get_size_in_points ()
429+ rotate = '%1.1f rotate' % angle
430+ setcolor = '%1.3f %1.3f %1.3f setrgbcolor' % gc .get_rgb ()
431+ #h = 0
432+ ps = """\
433+ gsave
434+ /%(fontname)s findfont
435+ %(fontsize)s scalefont
436+ setfont
437+ %(pos)s moveto
438+ %(rotate)s
439+ %(thetext)s
440+ %(setcolor)s
441+ show
442+ grestore
443+ """ % locals ()
444+ self ._draw_ps (ps , gc , None )
445+
446+ else :
447+ if ismath :
448+ return self .draw_mathtext (gc , x , y , s , prop , angle )
449+
450+ font = self ._get_font_ttf (prop )
451+ font .set_text (s ,0 )
452+
453+ self .set_color (* gc .get_rgb ())
454+ self .set_font (font .get_sfnt ()[(1 ,0 ,0 ,6 )], prop .get_size_in_points ())
455+ write ("%s m\n " % _nums_to_str (x ,y ))
456+ if angle :
457+ write ("gsave\n " )
458+ write ("%s rotate\n " % _num_to_str (angle ))
459+ descent = font .get_descent () / 64.0
460+ if descent :
461+ write ("0 %s rmoveto\n " % _num_to_str (descent ))
462+ write ("(%s) show\n " % quote_ps_string (s ))
463+ if angle :
464+ write ("grestore\n " )
404465
405466 def new_gc (self ):
406467 return GraphicsContextPS ()
@@ -657,18 +718,23 @@ def print_figure(self, outfile, dpi=72,
657718 type42 = _type42 + [os .path .join (self .basepath , name ) + '.ttf' \
658719 for name in bakoma_fonts ]
659720 print >> fh , "%%BeginProlog"
660- print >> fh , "/mpldict %d dict def" % (len (_psDefs )+ len (type42 ))
721+ Ndict = len (_psDefs )
722+ if not rcParams ['ps.useafm' ]:
723+ Ndict += len (type42 )
724+ print >> fh , "/mpldict %d dict def" % Ndict
661725 print >> fh , "mpldict begin"
726+
662727 for d in _psDefs :
663728 d = d .strip ()
664729 for l in d .split ('\n ' ):
665730 print >> fh , l .strip ()
666- for font in type42 :
667- font = str (font ) # TODO: handle unicode filenames
668- print >> fh , "%%BeginFont: " + FT2Font (font ).postscript_name
669- print >> fh , encodeTTFasPS (font )
670- print >> fh , "%%EndFont"
671- print >> fh , "%%EndProlog"
731+ if not rcParams ['ps.useafm' ]:
732+ for font in type42 :
733+ font = str (font ) # TODO: handle unicode filenames
734+ print >> fh , "%%BeginFont: " + FT2Font (font ).postscript_name
735+ print >> fh , encodeTTFasPS (font )
736+ print >> fh , "%%EndFont"
737+ print >> fh , "%%EndProlog"
672738
673739 if not isEPSF : print >> fh , "%%Page: 1 1"
674740 print >> fh , "mpldict begin"
0 commit comments