Skip to content

Commit fb58962

Browse files
authored
Merge pull request matplotlib#14869 from anntzer/svgtext
Deduplicate code for text-to-path conversion in svg backend.
2 parents 053703f + da94d6a commit fb58962

File tree

1 file changed

+32
-62
lines changed

1 file changed

+32
-62
lines changed

lib/matplotlib/backends/backend_svg.py

Lines changed: 32 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -881,27 +881,37 @@ def draw_image(self, gc, x, y, im, transform=None):
881881
if clipid is not None:
882882
self.writer.end('g')
883883

884+
def _update_glyph_map_defs(self, glyph_map_new):
885+
"""
886+
Emit definitions for not-yet-defined glyphs, and record them as having
887+
been defined.
888+
"""
889+
writer = self.writer
890+
if glyph_map_new:
891+
writer.start('defs')
892+
for char_id, (vertices, codes) in glyph_map_new.items():
893+
char_id = self._adjust_char_id(char_id)
894+
path_data = self._convert_path(
895+
Path(vertices, codes), simplify=False)
896+
writer.element('path', id=char_id, d=path_data)
897+
writer.end('defs')
898+
self._glyph_map.update(glyph_map_new)
899+
884900
def _adjust_char_id(self, char_id):
885901
return char_id.replace("%20", "_")
886902

887903
def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
888904
"""
889-
draw the text by converting them to paths using textpath module.
905+
Draw the text by converting them to paths using the textpath module.
890906
891907
Parameters
892908
----------
893-
prop : `matplotlib.font_manager.FontProperties`
894-
font property
895-
896909
s : str
897910
text to be converted
898-
899-
usetex : bool
900-
If True, use matplotlib usetex mode.
901-
911+
prop : `matplotlib.font_manager.FontProperties`
912+
font property
902913
ismath : bool
903914
If True, use mathtext parser. If "TeX", use *usetex* mode.
904-
905915
"""
906916
writer = self.writer
907917

@@ -916,86 +926,46 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
916926
style = {}
917927
if color != '#000000':
918928
style['fill'] = color
919-
920929
alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3]
921930
if alpha != 1:
922931
style['opacity'] = short_float_fmt(alpha)
932+
font_scale = fontsize / text2path.FONT_SCALE
933+
attrib = {
934+
'style': generate_css(style),
935+
'transform': generate_transform([
936+
('translate', (x, y)),
937+
('rotate', (-angle,)),
938+
('scale', (font_scale, -font_scale))]),
939+
}
940+
writer.start('g', attrib=attrib)
923941

924942
if not ismath:
925943
font = text2path._get_font(prop)
926944
_glyphs = text2path.get_glyphs_with_font(
927945
font, s, glyph_map=glyph_map, return_new_glyphs_only=True)
928946
glyph_info, glyph_map_new, rects = _glyphs
947+
self._update_glyph_map_defs(glyph_map_new)
929948

930-
if glyph_map_new:
931-
writer.start('defs')
932-
for char_id, glyph_path in glyph_map_new.items():
933-
path = Path(*glyph_path)
934-
path_data = self._convert_path(path, simplify=False)
935-
writer.element('path', id=char_id, d=path_data)
936-
writer.end('defs')
937-
938-
glyph_map.update(glyph_map_new)
939-
940-
attrib = {}
941-
attrib['style'] = generate_css(style)
942-
font_scale = fontsize / text2path.FONT_SCALE
943-
attrib['transform'] = generate_transform([
944-
('translate', (x, y)),
945-
('rotate', (-angle,)),
946-
('scale', (font_scale, -font_scale))])
947-
948-
writer.start('g', attrib=attrib)
949949
for glyph_id, xposition, yposition, scale in glyph_info:
950950
attrib = {'xlink:href': '#%s' % glyph_id}
951951
if xposition != 0.0:
952952
attrib['x'] = short_float_fmt(xposition)
953953
if yposition != 0.0:
954954
attrib['y'] = short_float_fmt(yposition)
955-
writer.element(
956-
'use',
957-
attrib=attrib)
955+
writer.element('use', attrib=attrib)
958956

959-
writer.end('g')
960957
else:
961958
if ismath == "TeX":
962959
_glyphs = text2path.get_glyphs_tex(
963960
prop, s, glyph_map=glyph_map, return_new_glyphs_only=True)
964961
else:
965962
_glyphs = text2path.get_glyphs_mathtext(
966963
prop, s, glyph_map=glyph_map, return_new_glyphs_only=True)
967-
968964
glyph_info, glyph_map_new, rects = _glyphs
965+
self._update_glyph_map_defs(glyph_map_new)
969966

970-
# We store the character glyphs w/o flipping. Instead, the
971-
# coordinate will be flipped when these characters are used.
972-
if glyph_map_new:
973-
writer.start('defs')
974-
for char_id, glyph_path in glyph_map_new.items():
975-
char_id = self._adjust_char_id(char_id)
976-
# Some characters are blank
977-
if not len(glyph_path[0]):
978-
path_data = ""
979-
else:
980-
path = Path(*glyph_path)
981-
path_data = self._convert_path(path, simplify=False)
982-
writer.element('path', id=char_id, d=path_data)
983-
writer.end('defs')
984-
985-
glyph_map.update(glyph_map_new)
986-
987-
attrib = {}
988-
font_scale = fontsize / text2path.FONT_SCALE
989-
attrib['style'] = generate_css(style)
990-
attrib['transform'] = generate_transform([
991-
('translate', (x, y)),
992-
('rotate', (-angle,)),
993-
('scale', (font_scale, -font_scale))])
994-
995-
writer.start('g', attrib=attrib)
996967
for char_id, xposition, yposition, scale in glyph_info:
997968
char_id = self._adjust_char_id(char_id)
998-
999969
writer.element(
1000970
'use',
1001971
transform=generate_transform([
@@ -1009,7 +979,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
1009979
path_data = self._convert_path(path, simplify=False)
1010980
writer.element('path', d=path_data)
1011981

1012-
writer.end('g')
982+
writer.end('g')
1013983

1014984
def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
1015985
writer = self.writer

0 commit comments

Comments
 (0)