@@ -87,6 +87,13 @@ def escape_attrib(s):
8787 s = s .replace (">" , ">" )
8888 return s
8989
90+ def short_float_fmt (x ):
91+ """
92+ Create a short string representation of a float, which is %f
93+ formatting with trailing zeros and the decimal point removed.
94+ """
95+ return '{0:f}' .format (x ).rstrip ('0' ).rstrip ('.' )
96+
9097##
9198# XML writer class.
9299#
@@ -231,7 +238,8 @@ def generate_transform(transform_list=[]):
231238 if type == 'matrix' and isinstance (value , Affine2DBase ):
232239 value = value .to_values ()
233240
234- output .write ('%s(%s)' % (type , ' ' .join (str (x ) for x in value )))
241+ output .write ('%s(%s)' % (
242+ type , ' ' .join (short_float_fmt (x ) for x in value )))
235243 return output .getvalue ()
236244 return ''
237245
@@ -403,32 +411,32 @@ def _get_style_dict(self, gc, rgbFace):
403411 if gc .get_hatch () is not None :
404412 attrib ['fill' ] = "url(#%s)" % self ._get_hatch (gc , rgbFace )
405413 if rgbFace is not None and len (rgbFace ) == 4 and rgbFace [3 ] != 1.0 and not forced_alpha :
406- attrib ['fill-opacity' ] = str (rgbFace [3 ])
414+ attrib ['fill-opacity' ] = short_float_fmt (rgbFace [3 ])
407415 else :
408416 if rgbFace is None :
409417 attrib ['fill' ] = 'none'
410418 else :
411419 if tuple (rgbFace [:3 ]) != (0 , 0 , 0 ):
412420 attrib ['fill' ] = rgb2hex (rgbFace )
413421 if len (rgbFace ) == 4 and rgbFace [3 ] != 1.0 and not forced_alpha :
414- attrib ['fill-opacity' ] = str (rgbFace [3 ])
422+ attrib ['fill-opacity' ] = short_float_fmt (rgbFace [3 ])
415423
416424 if forced_alpha and gc .get_alpha () != 1.0 :
417- attrib ['opacity' ] = str (gc .get_alpha ())
425+ attrib ['opacity' ] = short_float_fmt (gc .get_alpha ())
418426
419427 offset , seq = gc .get_dashes ()
420428 if seq is not None :
421- attrib ['stroke-dasharray' ] = ',' .join (['%f' % val for val in seq ])
422- attrib ['stroke-dashoffset' ] = six . text_type (float (offset ))
429+ attrib ['stroke-dasharray' ] = ',' .join ([short_float_fmt ( val ) for val in seq ])
430+ attrib ['stroke-dashoffset' ] = short_float_fmt (float (offset ))
423431
424432 linewidth = gc .get_linewidth ()
425433 if linewidth :
426434 rgb = gc .get_rgb ()
427435 attrib ['stroke' ] = rgb2hex (rgb )
428436 if not forced_alpha and rgb [3 ] != 1.0 :
429- attrib ['stroke-opacity' ] = str (rgb [3 ])
437+ attrib ['stroke-opacity' ] = short_float_fmt (rgb [3 ])
430438 if linewidth != 1.0 :
431- attrib ['stroke-width' ] = str (linewidth )
439+ attrib ['stroke-width' ] = short_float_fmt (linewidth )
432440 if gc .get_joinstyle () != 'round' :
433441 attrib ['stroke-linejoin' ] = gc .get_joinstyle ()
434442 if gc .get_capstyle () != 'butt' :
@@ -476,8 +484,12 @@ def _write_clips(self):
476484 writer .element ('path' , d = path_data )
477485 else :
478486 x , y , w , h = clip
479- writer .element ('rect' , x = six .text_type (x ), y = six .text_type (y ),
480- width = six .text_type (w ), height = six .text_type (h ))
487+ writer .element (
488+ 'rect' ,
489+ x = short_float_fmt (x ),
490+ y = short_float_fmt (y ),
491+ width = short_float_fmt (w ),
492+ height = short_float_fmt (h ))
481493 writer .end ('clipPath' )
482494 writer .end ('defs' )
483495
@@ -498,7 +510,8 @@ def _write_svgfonts(self):
498510 'font-family' : font .family_name ,
499511 'font-style' : font .style_name .lower (),
500512 'units-per-em' : '72' ,
501- 'bbox' : ' ' .join (six .text_type (x / 64.0 ) for x in font .bbox )})
513+ 'bbox' : ' ' .join (
514+ short_float_fmt (x / 64.0 ) for x in font .bbox )})
502515 for char in chars :
503516 glyph = font .load_char (char , flags = LOAD_NO_HINTING )
504517 verts , codes = font .get_path ()
@@ -511,7 +524,8 @@ def _write_svgfonts(self):
511524 attrib = {
512525 # 'glyph-name': name,
513526 'unicode' : unichr (char ),
514- 'horiz-adv-x' : six .text_type (glyph .linearHoriAdvance / 65536.0 )})
527+ 'horiz-adv-x' :
528+ short_float_fmt (glyph .linearHoriAdvance / 65536.0 )})
515529 writer .end ('font' )
516530 writer .end ('defs' )
517531
@@ -607,8 +621,8 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
607621 trans_and_flip , clip = clip , simplify = False ):
608622 if len (vertices ):
609623 x , y = vertices [- 2 :]
610- attrib ['x' ] = six . text_type (x )
611- attrib ['y' ] = six . text_type (y )
624+ attrib ['x' ] = short_float_fmt (x )
625+ attrib ['y' ] = short_float_fmt (y )
612626 attrib ['style' ] = self ._get_style (gc , rgbFace )
613627 writer .element ('use' , attrib = attrib )
614628 writer .end ('g' )
@@ -659,8 +673,8 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
659673 writer .start ('g' , attrib = {'clip-path' : 'url(#%s)' % clipid })
660674 attrib = {
661675 'xlink:href' : '#%s' % path_id ,
662- 'x' : six . text_type (xo ),
663- 'y' : six . text_type (self .height - yo ),
676+ 'x' : short_float_fmt (xo ),
677+ 'y' : short_float_fmt (self .height - yo ),
664678 'style' : self ._get_style (gc0 , rgbFace )
665679 }
666680 writer .element ('use' , attrib = attrib )
@@ -729,13 +743,13 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
729743 writer .start (
730744 'linearGradient' ,
731745 id = "GR%x_%d" % (self ._n_gradients , i ),
732- x1 = six . text_type (x1 ), y1 = six . text_type (y1 ),
733- x2 = six . text_type (xb ), y2 = six . text_type (yb ))
746+ x1 = short_float_fmt (x1 ), y1 = short_float_fmt (y1 ),
747+ x2 = short_float_fmt (xb ), y2 = short_float_fmt (yb ))
734748 writer .element (
735749 'stop' ,
736750 offset = '0' ,
737751 style = generate_css ({'stop-color' : rgb2hex (c ),
738- 'stop-opacity' : six . text_type (c [- 1 ])}))
752+ 'stop-opacity' : short_float_fmt (c [- 1 ])}))
739753 writer .element (
740754 'stop' ,
741755 offset = '1' ,
@@ -746,7 +760,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
746760 writer .element (
747761 'polygon' ,
748762 id = 'GT%x' % self ._n_gradients ,
749- points = " " .join ([six . text_type (x )
763+ points = " " .join ([short_float_fmt (x )
750764 for x in (x1 , y1 , x2 , y2 , x3 , y3 )]))
751765 writer .end ('defs' )
752766
@@ -756,7 +770,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
756770 'use' ,
757771 attrib = {'xlink:href' : href ,
758772 'fill' : rgb2hex (avg_color ),
759- 'fill-opacity' : str (avg_color [- 1 ])})
773+ 'fill-opacity' : short_float_fmt (avg_color [- 1 ])})
760774 for i in range (3 ):
761775 writer .element (
762776 'use' ,
@@ -842,16 +856,16 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
842856
843857 alpha = gc .get_alpha ()
844858 if alpha != 1.0 :
845- attrib ['opacity' ] = str (alpha )
859+ attrib ['opacity' ] = short_float_fmt (alpha )
846860
847861 attrib ['id' ] = oid
848862
849863 if transform is None :
850864 self .writer .element (
851865 'image' ,
852- x = six . text_type (x / trans [0 ]),
853- y = six . text_type ((self .height - y )/ trans [3 ]- h ),
854- width = six . text_type (w ), height = six . text_type (h ),
866+ x = short_float_fmt (x / trans [0 ]),
867+ y = short_float_fmt ((self .height - y )/ trans [3 ]- h ),
868+ width = short_float_fmt (w ), height = short_float_fmt (h ),
855869 attrib = attrib )
856870 else :
857871 flipped = self ._make_flip_transform (transform )
@@ -864,8 +878,8 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
864878 [('matrix' , flipped )])
865879 self .writer .element (
866880 'image' ,
867- x = six . text_type (x ), y = six . text_type (y ),
868- width = six . text_type (dx ), height = six . text_type (abs (dy )),
881+ x = short_float_fmt (x ), y = short_float_fmt (y ),
882+ width = short_float_fmt (dx ), height = short_float_fmt (abs (dy )),
869883 attrib = attrib )
870884
871885 if url is not None :
@@ -906,7 +920,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
906920 if color != '#000000' :
907921 style ['fill' ] = color
908922 if gc .get_alpha () != 1.0 :
909- style ['opacity' ] = six . text_type (gc .get_alpha ())
923+ style ['opacity' ] = short_float_fmt (gc .get_alpha ())
910924
911925 if not ismath :
912926 font = text2path ._get_font (prop )
@@ -936,9 +950,9 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
936950 for glyph_id , xposition , yposition , scale in glyph_info :
937951 attrib = {'xlink:href' : '#%s' % glyph_id }
938952 if xposition != 0.0 :
939- attrib ['x' ] = six . text_type (xposition )
953+ attrib ['x' ] = short_float_fmt (xposition )
940954 if yposition != 0.0 :
941- attrib ['y' ] = six . text_type (yposition )
955+ attrib ['y' ] = short_float_fmt (yposition )
942956 writer .element (
943957 'use' ,
944958 attrib = attrib )
@@ -1007,7 +1021,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10071021 if color != '#000000' :
10081022 style ['fill' ] = color
10091023 if gc .get_alpha () != 1.0 :
1010- style ['opacity' ] = six . text_type (gc .get_alpha ())
1024+ style ['opacity' ] = short_float_fmt (gc .get_alpha ())
10111025
10121026 if not ismath :
10131027 font = self ._get_font (prop )
@@ -1020,7 +1034,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10201034
10211035 attrib = {}
10221036 # Must add "px" to workaround a Firefox bug
1023- style ['font-size' ] = six . text_type (fontsize ) + 'px'
1037+ style ['font-size' ] = short_float_fmt (fontsize ) + 'px'
10241038 style ['font-family' ] = six .text_type (fontfamily )
10251039 style ['font-style' ] = prop .get_style ().lower ()
10261040 style ['font-weight' ] = six .text_type (prop .get_weight ()).lower ()
@@ -1048,10 +1062,13 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10481062 'center' : 'middle' }
10491063 style ['text-anchor' ] = ha_mpl_to_svg [mtext .get_ha ()]
10501064
1051- attrib ['x' ] = str (ax )
1052- attrib ['y' ] = str (ay )
1065+ attrib ['x' ] = short_float_fmt (ax )
1066+ attrib ['y' ] = short_float_fmt (ay )
10531067 attrib ['style' ] = generate_css (style )
1054- attrib ['transform' ] = "rotate(%f, %f, %f)" % (- angle , ax , ay )
1068+ attrib ['transform' ] = "rotate(%s, %s, %s)" % (
1069+ short_float_fmt (- angle ),
1070+ short_float_fmt (ax ),
1071+ short_float_fmt (ay ))
10551072 writer .element ('text' , s , attrib = attrib )
10561073 else :
10571074 attrib ['transform' ] = generate_transform ([
@@ -1090,7 +1107,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10901107 spans = {}
10911108 for font , fontsize , thetext , new_x , new_y , metrics in svg_glyphs :
10921109 style = generate_css ({
1093- 'font-size' : six . text_type (fontsize ) + 'px' ,
1110+ 'font-size' : short_float_fmt (fontsize ) + 'px' ,
10941111 'font-family' : font .family_name ,
10951112 'font-style' : font .style_name .lower (),
10961113 'font-weight' : font .style_name .lower ()})
@@ -1120,7 +1137,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11201137
11211138 attrib = {
11221139 'style' : style ,
1123- 'x' : ' ' .join (six . text_type (c [0 ]) for c in chars ),
1140+ 'x' : ' ' .join (short_float_fmt (c [0 ]) for c in chars ),
11241141 'y' : ys
11251142 }
11261143
@@ -1135,8 +1152,10 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11351152 for x , y , width , height in svg_rects :
11361153 writer .element (
11371154 'rect' ,
1138- x = six .text_type (x ), y = six .text_type (- y + height ),
1139- width = six .text_type (width ), height = six .text_type (height )
1155+ x = short_float_fmt (x ),
1156+ y = short_float_fmt (- y + height ),
1157+ width = short_float_fmt (width ),
1158+ height = short_float_fmt (height )
11401159 )
11411160
11421161 writer .end ('g' )
0 commit comments