""" A module for parsing and generating fontconfig patterns.
See the `fontconfig pattern specification <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_ for more information. """
# This class is defined here because it must be available in: # - The old-style config framework (:file:`rcsetup.py`) # - The font manager (:file:`font_manager.py`)
# It probably logically belongs in :file:`font_manager.py`, but placing it # there would have created cyclical dependency problems.
ParseException, Suppress)
"""A simple pyparsing-based parser for fontconfig-style patterns.
See the `fontconfig pattern specification <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_ for more information. """
'thin' : ('weight', 'light'), 'extralight' : ('weight', 'light'), 'ultralight' : ('weight', 'light'), 'light' : ('weight', 'light'), 'book' : ('weight', 'book'), 'regular' : ('weight', 'regular'), 'normal' : ('weight', 'normal'), 'medium' : ('weight', 'medium'), 'demibold' : ('weight', 'demibold'), 'semibold' : ('weight', 'semibold'), 'bold' : ('weight', 'bold'), 'extrabold' : ('weight', 'extra bold'), 'black' : ('weight', 'black'), 'heavy' : ('weight', 'heavy'), 'roman' : ('slant', 'normal'), 'italic' : ('slant', 'italic'), 'oblique' : ('slant', 'oblique'), 'ultracondensed' : ('width', 'ultra-condensed'), 'extracondensed' : ('width', 'extra-condensed'), 'condensed' : ('width', 'condensed'), 'semicondensed' : ('width', 'semi-condensed'), 'expanded' : ('width', 'expanded'), 'extraexpanded' : ('width', 'extra-expanded'), 'ultraexpanded' : ('width', 'ultra-expanded') }
(family_punc, family_punc)) \ .setParseAction(self._family) .setParseAction(self._size) .setParseAction(self._name) (value_punc, value_punc)) \ .setParseAction(self._value)
+ ZeroOrMore( Literal(',') + family) ).setParseAction(self._families)
+ ZeroOrMore( Literal(',') + size) ).setParseAction(self._point_sizes)
+ Suppress(Literal('=')) + value + ZeroOrMore( Suppress(Literal(',')) + value) ) | name ).setParseAction(self._property)
families) + Optional( Literal('-') + point_sizes) + ZeroOrMore( Literal(':') + property) + StringEnd() )
""" Parse the given fontconfig *pattern* and return a dictionary of key/value pairs useful for initializing a :class:`font_manager.FontProperties` object. """ except self.ParseException as e: raise ValueError( "Could not parse font string: '%s'\n%s" % (pattern, e))
return [float(tokens[0])]
self._properties['size'] = [str(x) for x in tokens] return []
else:
# `parse_fontconfig_pattern` is a bottleneck during the tests because it is # repeatedly called when the rcParams are reset (to validate the default # fonts). In practice, the cache size doesn't grow beyond a few dozen entries # during the test suite.
""" Given a dictionary of key/value pairs, generates a fontconfig pattern string. """ props = [] families = '' size = '' for key in 'family style variant weight stretch file size'.split(): val = getattr(d, 'get_' + key)() if val is not None and val != []: if type(val) == list: val = [value_escape(r'\\\1', str(x)) for x in val if x is not None] if val != []: val = ','.join(val) props.append(":%s=%s" % (key, val)) return ''.join(props) |