@@ -815,7 +815,7 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
815815 def _adjust_char_id (self , char_id ):
816816 return char_id .replace (u"%20" , u"_" )
817817
818- def _draw_text_as_path (self , gc , x , y , s , prop , angle , ismath ):
818+ def _draw_text_as_path (self , gc , x , y , s , prop , angle , ismath , mtext = None ):
819819 """
820820 draw the text by converting them to paths using textpath module.
821821
@@ -940,7 +940,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
940940
941941 writer .end ('g' )
942942
943- def _draw_text_as_text (self , gc , x , y , s , prop , angle , ismath ):
943+ def _draw_text_as_text (self , gc , x , y , s , prop , angle , ismath , mtext = None ):
944944 writer = self .writer
945945
946946 color = rgb2hex (gc .get_rgb ())
@@ -953,7 +953,8 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath):
953953 if not ismath :
954954 font = self ._get_font (prop )
955955 font .set_text (s , 0.0 , flags = LOAD_NO_HINTING )
956- y -= font .get_descent () / 64.0
956+ descent = font .get_descent () / 64.0
957+ y -= descent
957958
958959 fontsize = prop .get_size_in_points ()
959960
@@ -967,11 +968,40 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath):
967968 style [u'font-style' ] = prop .get_style ().lower ()
968969 attrib [u'style' ] = generate_css (style )
969970
970- attrib [u'transform' ] = generate_transform ([
971- (u'translate' , (x , y )),
972- (u'rotate' , (- angle ,))])
971+ if angle == 0 or mtext .get_rotation_mode () == "anchor" :
972+ # If text anchoring can be supported, get the original
973+ # coordinates and add alignment information.
974+
975+ # Get anchor coordinates.
976+ transform = mtext .get_transform ()
977+ ax , ay = transform .transform_point (mtext .get_position ())
978+ ay = self .height - ay
979+
980+ # Don't do vertical anchor alignment. Most applications do not
981+ # support 'alignment-baseline' yet. Apply the vertical layout
982+ # to the anchor point manually for now.
983+ angle_rad = angle * np .pi / 180.
984+ dir_vert = np .array ([np .sin (angle_rad ), np .cos (angle_rad )])
985+ y += descent # Undo inappropriate text descent handling
986+ v_offset = np .dot (dir_vert , [(x - ax ), (y - ay )])
987+ ax = ax + (v_offset - descent ) * dir_vert [0 ]
988+ ay = ay + (v_offset - descent ) * dir_vert [1 ]
989+
990+ ha_mpl_to_svg = {'left' : 'start' , 'right' : 'end' ,
991+ 'center' : 'middle' }
992+ style [u'text-anchor' ] = ha_mpl_to_svg [mtext .get_ha ()]
993+
994+ attrib [u'x' ] = str (ax )
995+ attrib [u'y' ] = str (ay )
996+ attrib [u'style' ] = generate_css (style )
997+ attrib [u'transform' ] = u"rotate(%f, %f, %f)" % (- angle , ax , ay )
998+ writer .element (u'text' , s , attrib = attrib )
999+ else :
1000+ attrib [u'transform' ] = generate_transform ([
1001+ (u'translate' , (x , y )),
1002+ (u'rotate' , (- angle ,))])
9731003
974- writer .element (u'text' , s , attrib = attrib )
1004+ writer .element (u'text' , s , attrib = attrib )
9751005
9761006 if rcParams ['svg.fonttype' ] == 'svgfont' :
9771007 fontset = self ._fonts .setdefault (font .fname , set ())
@@ -1065,9 +1095,9 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
10651095 u'g' , attrib = {u'clip-path' : u'url(#%s)' % clipid })
10661096
10671097 if rcParams ['svg.fonttype' ] == 'path' :
1068- self ._draw_text_as_path (gc , x , y , s , prop , angle , ismath )
1098+ self ._draw_text_as_path (gc , x , y , s , prop , angle , ismath , mtext )
10691099 else :
1070- self ._draw_text_as_text (gc , x , y , s , prop , angle , ismath )
1100+ self ._draw_text_as_text (gc , x , y , s , prop , angle , ismath , mtext )
10711101
10721102 if clipid is not None :
10731103 self .writer .end (u'g' )
0 commit comments