|
21 | 21 | from matplotlib.backends.backend_mixed import MixedModeRenderer
|
22 | 22 | from matplotlib.colors import rgb2hex
|
23 | 23 | from matplotlib.dates import UTC
|
24 |
| -from matplotlib.font_manager import findfont, get_font |
| 24 | +from matplotlib.font_manager import findfont, get_font, ttfFontProperty |
25 | 25 | from matplotlib.ft2font import LOAD_NO_HINTING
|
26 | 26 | from matplotlib.mathtext import MathTextParser
|
27 | 27 | from matplotlib.path import Path
|
@@ -94,6 +94,12 @@ def escape_attrib(s):
|
94 | 94 | return s
|
95 | 95 |
|
96 | 96 |
|
| 97 | +def _quote_escape_attrib(s): |
| 98 | + return ('"' + escape_cdata(s) + '"' if '"' not in s else |
| 99 | + "'" + escape_cdata(s) + "'" if "'" not in s else |
| 100 | + '"' + escape_attrib(s) + '"') |
| 101 | + |
| 102 | + |
97 | 103 | def short_float_fmt(x):
|
98 | 104 | """
|
99 | 105 | Create a short string representation of a float, which is %f
|
@@ -159,8 +165,8 @@ def start(self, tag, attrib={}, **extra):
|
159 | 165 | for k, v in sorted({**attrib, **extra}.items()):
|
160 | 166 | if v:
|
161 | 167 | k = escape_cdata(k)
|
162 |
| - v = escape_attrib(v) |
163 |
| - self.__write(' %s="%s"' % (k, v)) |
| 168 | + v = _quote_escape_attrib(v) |
| 169 | + self.__write(' %s=%s' % (k, v)) |
164 | 170 | self.__open = 1
|
165 | 171 | return len(self.__tags) - 1
|
166 | 172 |
|
@@ -1197,11 +1203,20 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
|
1197 | 1203 | # Sort the characters by font, and output one tspan for each.
|
1198 | 1204 | spans = OrderedDict()
|
1199 | 1205 | for font, fontsize, thetext, new_x, new_y in glyphs:
|
1200 |
| - style = generate_css({ |
1201 |
| - 'font-size': short_float_fmt(fontsize) + 'px', |
1202 |
| - 'font-family': font.family_name, |
1203 |
| - 'font-style': font.style_name.lower(), |
1204 |
| - 'font-weight': font.style_name.lower()}) |
| 1206 | + entry = ttfFontProperty(font) |
| 1207 | + font_parts = ['font:'] |
| 1208 | + if entry.style != 'normal': |
| 1209 | + font_parts.append(entry.style) |
| 1210 | + if entry.variant != 'normal': |
| 1211 | + font_parts.append(entry.variant) |
| 1212 | + font_parts.extend([ |
| 1213 | + f'{entry.weight}', |
| 1214 | + f'{short_float_fmt(fontsize)}px', |
| 1215 | + f'{entry.name!r}', # ensure quoting |
| 1216 | + ]) |
| 1217 | + if entry.stretch != 'normal': |
| 1218 | + font_parts.extend(['; font-stretch:', entry.stretch]) |
| 1219 | + style = ' '.join(font_parts) |
1205 | 1220 | if thetext == 32:
|
1206 | 1221 | thetext = 0xa0 # non-breaking space
|
1207 | 1222 | spans.setdefault(style, []).append((new_x, -new_y, thetext))
|
|
0 commit comments