From ec55cba9510d49654b6f3479ae36de3f2561ca6c Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 1 Oct 2022 20:38:25 +0200 Subject: [PATCH] Simplify svg font expansion logic. We can delay quoting and deduplication until quite late. --- lib/matplotlib/backends/backend_svg.py | 56 +++++++++----------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 721fb43ee6c6..9d714739c081 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -1154,47 +1154,31 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None): if weight != 400: font_parts.append(f'{weight}') - def _format_font_name(fn): - normalize_names = { - 'sans': 'sans-serif', - 'sans serif': 'sans-serif' - } - # A generic font family. We need to do two things: - # 1. list all of the configured fonts with quoted names - # 2. append the generic name unquoted + def _normalize_sans(name): + return 'sans-serif' if name in ['sans', 'sans serif'] else name + + def _expand_family_entry(fn): + fn = _normalize_sans(fn) + # prepend generic font families with all configured font names if fn in fm.font_family_aliases: - # fix spelling of sans-serif - # we accept 3 ways CSS only supports 1 - fn = normalize_names.get(fn, fn) # get all of the font names and fix spelling of sans-serif - # if it comes back - aliases = [ - normalize_names.get(_, _) for _ in - fm.FontManager._expand_aliases(fn) - ] - # make sure the generic name appears at least once - # duplicate is OK, next layer will deduplicate - aliases.append(fn) - - for a in aliases: - # generic font families must not be quoted - if a in fm.font_family_aliases: - yield a - # specific font families must be quoted - else: - yield repr(a) - # specific font families must be quoted - else: - yield repr(fn) - - def _get_all_names(prop): - for f in prop.get_family(): - yield from _format_font_name(f) + # (we accept 3 ways CSS only supports 1) + for name in fm.FontManager._expand_aliases(fn): + yield _normalize_sans(name) + # whether a generic name or a family name, it must appear at + # least once + yield fn + + def _get_all_quoted_names(prop): + # only quote specific names, not generic names + return [name if name in fm.font_family_aliases else repr(name) + 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 quoting and expansion of font names - ", ".join(dict.fromkeys(_get_all_names(prop))) + # ensure expansion, quoting, and dedupe of font names + ", ".join(dict.fromkeys(_get_all_quoted_names(prop))) ]) style['font'] = ' '.join(font_parts) if prop.get_stretch() != 'normal':