@@ -88,6 +88,13 @@ def escape_attrib(s):
8888 s = s .replace (">" , ">" )
8989 return s
9090
91+ def short_float_fmt (x ):
92+ """
93+ Create a short string representation of a float, which is %f
94+ formatting with trailing zeros and the decimal point removed.
95+ """
96+ return '{0:f}' .format (x ).rstrip ('0' ).rstrip ('.' )
97+
9198##
9299# XML writer class.
93100#
@@ -232,7 +239,8 @@ def generate_transform(transform_list=[]):
232239 if type == 'matrix' and isinstance (value , Affine2DBase ):
233240 value = value .to_values ()
234241
235- output .write ('%s(%s)' % (type , ' ' .join ('%f' % x for x in value )))
242+ output .write ('%s(%s)' % (
243+ type , ' ' .join (short_float_fmt (x ) for x in value )))
236244 return output .getvalue ()
237245 return ''
238246
@@ -401,32 +409,32 @@ def _get_style_dict(self, gc, rgbFace):
401409 if gc .get_hatch () is not None :
402410 attrib ['fill' ] = "url(#%s)" % self ._get_hatch (gc , rgbFace )
403411 if rgbFace is not None and len (rgbFace ) == 4 and rgbFace [3 ] != 1.0 and not forced_alpha :
404- attrib ['fill-opacity' ] = "%f" % rgbFace [3 ]
412+ attrib ['fill-opacity' ] = short_float_fmt ( rgbFace [3 ])
405413 else :
406414 if rgbFace is None :
407415 attrib ['fill' ] = 'none'
408416 else :
409417 if tuple (rgbFace [:3 ]) != (0 , 0 , 0 ):
410418 attrib ['fill' ] = rgb2hex (rgbFace )
411419 if len (rgbFace ) == 4 and rgbFace [3 ] != 1.0 and not forced_alpha :
412- attrib ['fill-opacity' ] = "%f" % rgbFace [3 ]
420+ attrib ['fill-opacity' ] = short_float_fmt ( rgbFace [3 ])
413421
414422 if forced_alpha and gc .get_alpha () != 1.0 :
415- attrib ['opacity' ] = "%f" % gc .get_alpha ()
423+ attrib ['opacity' ] = short_float_fmt ( gc .get_alpha () )
416424
417425 offset , seq = gc .get_dashes ()
418426 if seq is not None :
419- attrib ['stroke-dasharray' ] = ',' .join (['%f' % val for val in seq ])
420- attrib ['stroke-dashoffset' ] = six . text_type (float (offset ))
427+ attrib ['stroke-dasharray' ] = ',' .join ([short_float_fmt ( val ) for val in seq ])
428+ attrib ['stroke-dashoffset' ] = short_float_fmt (float (offset ))
421429
422430 linewidth = gc .get_linewidth ()
423431 if linewidth :
424432 rgb = gc .get_rgb ()
425433 attrib ['stroke' ] = rgb2hex (rgb )
426434 if not forced_alpha and rgb [3 ] != 1.0 :
427- attrib ['stroke-opacity' ] = "%f" % rgb [3 ]
435+ attrib ['stroke-opacity' ] = short_float_fmt ( rgb [3 ])
428436 if linewidth != 1.0 :
429- attrib ['stroke-width' ] = "%f" % linewidth
437+ attrib ['stroke-width' ] = short_float_fmt ( linewidth )
430438 if gc .get_joinstyle () != 'round' :
431439 attrib ['stroke-linejoin' ] = gc .get_joinstyle ()
432440 if gc .get_capstyle () != 'butt' :
@@ -474,8 +482,12 @@ def _write_clips(self):
474482 writer .element ('path' , d = path_data )
475483 else :
476484 x , y , w , h = clip
477- writer .element ('rect' , x = six .text_type (x ), y = six .text_type (y ),
478- width = six .text_type (w ), height = six .text_type (h ))
485+ writer .element (
486+ 'rect' ,
487+ x = short_float_fmt (x ),
488+ y = short_float_fmt (y ),
489+ width = short_float_fmt (w ),
490+ height = short_float_fmt (h ))
479491 writer .end ('clipPath' )
480492 writer .end ('defs' )
481493
@@ -496,7 +508,8 @@ def _write_svgfonts(self):
496508 'font-family' : font .family_name ,
497509 'font-style' : font .style_name .lower (),
498510 'units-per-em' : '72' ,
499- 'bbox' : ' ' .join (six .text_type (x / 64.0 ) for x in font .bbox )})
511+ 'bbox' : ' ' .join (
512+ short_float_fmt (x / 64.0 ) for x in font .bbox )})
500513 for char in chars :
501514 glyph = font .load_char (char , flags = LOAD_NO_HINTING )
502515 verts , codes = font .get_path ()
@@ -509,7 +522,8 @@ def _write_svgfonts(self):
509522 attrib = {
510523 # 'glyph-name': name,
511524 'unicode' : unichr (char ),
512- 'horiz-adv-x' : six .text_type (glyph .linearHoriAdvance / 65536.0 )})
525+ 'horiz-adv-x' :
526+ short_float_fmt (glyph .linearHoriAdvance / 65536.0 )})
513527 writer .end ('font' )
514528 writer .end ('defs' )
515529
@@ -605,8 +619,8 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
605619 trans_and_flip , clip = clip , simplify = False ):
606620 if len (vertices ):
607621 x , y = vertices [- 2 :]
608- attrib ['x' ] = six . text_type (x )
609- attrib ['y' ] = six . text_type (y )
622+ attrib ['x' ] = short_float_fmt (x )
623+ attrib ['y' ] = short_float_fmt (y )
610624 attrib ['style' ] = self ._get_style (gc , rgbFace )
611625 writer .element ('use' , attrib = attrib )
612626 writer .end ('g' )
@@ -657,8 +671,8 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
657671 writer .start ('g' , attrib = {'clip-path' : 'url(#%s)' % clipid })
658672 attrib = {
659673 'xlink:href' : '#%s' % path_id ,
660- 'x' : six . text_type (xo ),
661- 'y' : six . text_type (self .height - yo ),
674+ 'x' : short_float_fmt (xo ),
675+ 'y' : short_float_fmt (self .height - yo ),
662676 'style' : self ._get_style (gc0 , rgbFace )
663677 }
664678 writer .element ('use' , attrib = attrib )
@@ -727,13 +741,13 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
727741 writer .start (
728742 'linearGradient' ,
729743 id = "GR%x_%d" % (self ._n_gradients , i ),
730- x1 = six . text_type (x1 ), y1 = six . text_type (y1 ),
731- x2 = six . text_type (xb ), y2 = six . text_type (yb ))
744+ x1 = short_float_fmt (x1 ), y1 = short_float_fmt (y1 ),
745+ x2 = short_float_fmt (xb ), y2 = short_float_fmt (yb ))
732746 writer .element (
733747 'stop' ,
734748 offset = '0' ,
735749 style = generate_css ({'stop-color' : rgb2hex (c ),
736- 'stop-opacity' : six . text_type (c [- 1 ])}))
750+ 'stop-opacity' : short_float_fmt (c [- 1 ])}))
737751 writer .element (
738752 'stop' ,
739753 offset = '1' ,
@@ -744,7 +758,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
744758 writer .element (
745759 'polygon' ,
746760 id = 'GT%x' % self ._n_gradients ,
747- points = " " .join ([six . text_type (x )
761+ points = " " .join ([short_float_fmt (x )
748762 for x in (x1 , y1 , x2 , y2 , x3 , y3 )]))
749763 writer .end ('defs' )
750764
@@ -754,7 +768,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
754768 'use' ,
755769 attrib = {'xlink:href' : href ,
756770 'fill' : rgb2hex (avg_color ),
757- 'fill-opacity' : "%f" % avg_color [- 1 ]})
771+ 'fill-opacity' : short_float_fmt ( avg_color [- 1 ]) })
758772 for i in range (3 ):
759773 writer .element (
760774 'use' ,
@@ -840,16 +854,16 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
840854
841855 alpha = gc .get_alpha ()
842856 if alpha != 1.0 :
843- attrib ['opacity' ] = "%f" % alpha
857+ attrib ['opacity' ] = short_float_fmt ( alpha )
844858
845859 attrib ['id' ] = oid
846860
847861 if transform is None :
848862 self .writer .element (
849863 'image' ,
850- x = six . text_type (x / trans [0 ]),
851- y = six . text_type ((self .height - y )/ trans [3 ]- h ),
852- width = six . text_type (w ), height = six . text_type (h ),
864+ x = short_float_fmt (x / trans [0 ]),
865+ y = short_float_fmt ((self .height - y )/ trans [3 ]- h ),
866+ width = short_float_fmt (w ), height = short_float_fmt (h ),
853867 attrib = attrib )
854868 else :
855869 flipped = self ._make_flip_transform (transform )
@@ -862,8 +876,8 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
862876 [('matrix' , flipped )])
863877 self .writer .element (
864878 'image' ,
865- x = six . text_type (x ), y = six . text_type (y ),
866- width = six . text_type (dx ), height = six . text_type (abs (dy )),
879+ x = short_float_fmt (x ), y = short_float_fmt (y ),
880+ width = short_float_fmt (dx ), height = short_float_fmt (abs (dy )),
867881 attrib = attrib )
868882
869883 if url is not None :
@@ -904,7 +918,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
904918 if color != '#000000' :
905919 style ['fill' ] = color
906920 if gc .get_alpha () != 1.0 :
907- style ['opacity' ] = six . text_type (gc .get_alpha ())
921+ style ['opacity' ] = short_float_fmt (gc .get_alpha ())
908922
909923 if not ismath :
910924 font = text2path ._get_font (prop )
@@ -934,9 +948,9 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
934948 for glyph_id , xposition , yposition , scale in glyph_info :
935949 attrib = {'xlink:href' : '#%s' % glyph_id }
936950 if xposition != 0.0 :
937- attrib ['x' ] = six . text_type (xposition )
951+ attrib ['x' ] = short_float_fmt (xposition )
938952 if yposition != 0.0 :
939- attrib ['y' ] = six . text_type (yposition )
953+ attrib ['y' ] = short_float_fmt (yposition )
940954 writer .element (
941955 'use' ,
942956 attrib = attrib )
@@ -1005,7 +1019,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10051019 if color != '#000000' :
10061020 style ['fill' ] = color
10071021 if gc .get_alpha () != 1.0 :
1008- style ['opacity' ] = six . text_type (gc .get_alpha ())
1022+ style ['opacity' ] = short_float_fmt (gc .get_alpha ())
10091023
10101024 if not ismath :
10111025 font = self ._get_font (prop )
@@ -1018,7 +1032,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10181032
10191033 attrib = {}
10201034 # Must add "px" to workaround a Firefox bug
1021- style ['font-size' ] = six . text_type (fontsize ) + 'px'
1035+ style ['font-size' ] = short_float_fmt (fontsize ) + 'px'
10221036 style ['font-family' ] = six .text_type (fontfamily )
10231037 style ['font-style' ] = prop .get_style ().lower ()
10241038 style ['font-weight' ] = six .text_type (prop .get_weight ()).lower ()
@@ -1046,10 +1060,13 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10461060 'center' : 'middle' }
10471061 style ['text-anchor' ] = ha_mpl_to_svg [mtext .get_ha ()]
10481062
1049- attrib ['x' ] = "%f" % ax
1050- attrib ['y' ] = "%f" % ay
1063+ attrib ['x' ] = short_float_fmt ( ax )
1064+ attrib ['y' ] = short_float_fmt ( ay )
10511065 attrib ['style' ] = generate_css (style )
1052- attrib ['transform' ] = "rotate(%f, %f, %f)" % (- angle , ax , ay )
1066+ attrib ['transform' ] = "rotate(%s, %s, %s)" % (
1067+ short_float_fmt (- angle ),
1068+ short_float_fmt (ax ),
1069+ short_float_fmt (ay ))
10531070 writer .element ('text' , s , attrib = attrib )
10541071 else :
10551072 attrib ['transform' ] = generate_transform ([
@@ -1088,7 +1105,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10881105 spans = OrderedDict ()
10891106 for font , fontsize , thetext , new_x , new_y , metrics in svg_glyphs :
10901107 style = generate_css ({
1091- 'font-size' : six . text_type (fontsize ) + 'px' ,
1108+ 'font-size' : short_float_fmt (fontsize ) + 'px' ,
10921109 'font-family' : font .family_name ,
10931110 'font-style' : font .style_name .lower (),
10941111 'font-weight' : font .style_name .lower ()})
@@ -1118,7 +1135,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11181135
11191136 attrib = {
11201137 'style' : style ,
1121- 'x' : ' ' .join (six . text_type (c [0 ]) for c in chars ),
1138+ 'x' : ' ' .join (short_float_fmt (c [0 ]) for c in chars ),
11221139 'y' : ys
11231140 }
11241141
@@ -1133,8 +1150,10 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11331150 for x , y , width , height in svg_rects :
11341151 writer .element (
11351152 'rect' ,
1136- x = six .text_type (x ), y = six .text_type (- y + height ),
1137- width = six .text_type (width ), height = six .text_type (height )
1153+ x = short_float_fmt (x ),
1154+ y = short_float_fmt (- y + height ),
1155+ width = short_float_fmt (width ),
1156+ height = short_float_fmt (height )
11381157 )
11391158
11401159 writer .end ('g' )
0 commit comments