Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 43 additions & 52 deletions lib/matplotlib/backends/backend_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,12 +1066,13 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
self._update_glyph_map_defs(glyph_map_new)

for glyph_id, xposition, yposition, scale in glyph_info:
attrib = {'xlink:href': f'#{glyph_id}'}
if xposition != 0.0:
attrib['x'] = _short_float_fmt(xposition)
if yposition != 0.0:
attrib['y'] = _short_float_fmt(yposition)
writer.element('use', attrib=attrib)
writer.element(
'use',
transform=_generate_transform([
('translate', (xposition, yposition)),
('scale', (scale,)),
]),
attrib={'xlink:href': f'#{glyph_id}'})

else:
if ismath == "TeX":
Expand Down Expand Up @@ -1109,25 +1110,26 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
writer = self.writer

color = rgb2hex(gc.get_rgb())
style = {}
font_style = {}
color_style = {}
if color != '#000000':
style['fill'] = color
color_style['fill'] = color

alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3]
if alpha != 1:
style['opacity'] = _short_float_fmt(alpha)
color_style['opacity'] = _short_float_fmt(alpha)

if not ismath:
attrib = {}

font_parts = []
# Separate font style in their separate attributes
if prop.get_style() != 'normal':
font_parts.append(prop.get_style())
font_style['font-style'] = prop.get_style()
if prop.get_variant() != 'normal':
font_parts.append(prop.get_variant())
font_style['font-variant'] = prop.get_variant()
weight = fm.weight_dict[prop.get_weight()]
if weight != 400:
font_parts.append(f'{weight}')
font_style['font-weight'] = f'{weight}'

def _normalize_sans(name):
return 'sans-serif' if name in ['sans', 'sans serif'] else name
Expand All @@ -1150,15 +1152,15 @@ def _get_all_quoted_names(prop):
for entry in prop.get_family()
for name in _expand_family_entry(entry)]

font_parts.extend([
f'{_short_float_fmt(prop.get_size())}px',
# ensure expansion, quoting, and dedupe of font names
", ".join(dict.fromkeys(_get_all_quoted_names(prop)))
])
style['font'] = ' '.join(font_parts)
font_style['font-size'] = f'{_short_float_fmt(prop.get_size())}px'
# ensure expansion, quoting, and dedupe of font names
font_style['font-family'] = ", ".join(
dict.fromkeys(_get_all_quoted_names(prop))
)

if prop.get_stretch() != 'normal':
style['font-stretch'] = prop.get_stretch()
attrib['style'] = _generate_css(style)
font_style['font-stretch'] = prop.get_stretch()
attrib['style'] = _generate_css({**font_style, **color_style})

if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"):
# If text anchoring can be supported, get the original
Expand All @@ -1180,11 +1182,11 @@ def _get_all_quoted_names(prop):

ha_mpl_to_svg = {'left': 'start', 'right': 'end',
'center': 'middle'}
style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()]
font_style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()]

attrib['x'] = _short_float_fmt(ax)
attrib['y'] = _short_float_fmt(ay)
attrib['style'] = _generate_css(style)
attrib['style'] = _generate_css({**font_style, **color_style})
attrib['transform'] = _generate_transform([
("rotate", (-angle, ax, ay))])

Expand All @@ -1204,7 +1206,7 @@ def _get_all_quoted_names(prop):
# Apply attributes to 'g', not 'text', because we likely have some
# rectangles as well with the same style and transformation.
writer.start('g',
style=_generate_css(style),
style=_generate_css({**font_style, **color_style}),
transform=_generate_transform([
('translate', (x, y)),
('rotate', (-angle,))]),
Expand All @@ -1216,43 +1218,32 @@ def _get_all_quoted_names(prop):
spans = {}
for font, fontsize, thetext, new_x, new_y in glyphs:
entry = fm.ttfFontProperty(font)
font_parts = []
font_style = {}
# Separate font style in its separate attributes
if entry.style != 'normal':
font_parts.append(entry.style)
font_style['font-style'] = entry.style
if entry.variant != 'normal':
font_parts.append(entry.variant)
font_style['font-variant'] = entry.variant
if entry.weight != 400:
font_parts.append(f'{entry.weight}')
font_parts.extend([
f'{_short_float_fmt(fontsize)}px',
f'{entry.name!r}', # ensure quoting
])
style = {'font': ' '.join(font_parts)}
font_style['font-weight'] = f'{entry.weight}'
font_style['font-size'] = f'{_short_float_fmt(fontsize)}px'
font_style['font-family'] = f'{entry.name!r}' # ensure quoting
if entry.stretch != 'normal':
style['font-stretch'] = entry.stretch
style = _generate_css(style)
font_style['font-stretch'] = entry.stretch
style = _generate_css({**font_style, **color_style})
if thetext == 32:
thetext = 0xa0 # non-breaking space
spans.setdefault(style, []).append((new_x, -new_y, thetext))

for style, chars in spans.items():
chars.sort()

if len({y for x, y, t in chars}) == 1: # Are all y's the same?
ys = str(chars[0][1])
else:
ys = ' '.join(str(c[1]) for c in chars)

attrib = {
'style': style,
'x': ' '.join(_short_float_fmt(c[0]) for c in chars),
'y': ys
}

writer.element(
'tspan',
''.join(chr(c[2]) for c in chars),
attrib=attrib)
chars.sort() # Sort by increasing x position
for x, y, t in chars: # Output one tspan for each character
writer.element(
'tspan',
chr(t),
x=_short_float_fmt(x),
y=_short_float_fmt(y),
style=style)

writer.end('text')

Expand Down
11 changes: 10 additions & 1 deletion lib/matplotlib/testing/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import sys
from tempfile import TemporaryDirectory, TemporaryFile
import weakref
import re

import numpy as np
from PIL import Image
Expand Down Expand Up @@ -305,7 +306,15 @@ def convert(filename, cache):
# re-generate any SVG test files using this mode, or else such tests will
# fail to use the converter for the expected images (but will for the
# results), and the tests will fail strangely.
if 'style="font:' in contents:
if re.search(
# searches for attributes :
# style=[font|font-size|font-weight|
# font-family|font-variant|font-style]
# taking care of the possibility of multiple style attributes
# before the font styling (i.e. opacity)
r'style="[^"]*font(|-size|-weight|-family|-variant|-style):',
contents # raw contents of the svg file
):
# for svg.fonttype = none, we explicitly patch the font search
# path so that fonts shipped by Matplotlib are found.
convert = _svg_with_matplotlib_fonts_converter
Expand Down
Loading