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

Skip to content

Fix FontProperties conversion to/from strings #15601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 3, 2019
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
33 changes: 25 additions & 8 deletions lib/matplotlib/fontconfig_pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from functools import lru_cache
import re

import numpy as np
from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
ParseException, Suppress)

Expand Down Expand Up @@ -177,19 +177,36 @@ def _property(self, s, loc, tokens):
parse_fontconfig_pattern = lru_cache()(FontconfigPatternParser().parse)


def _escape_val(val, escape_func):
"""
Given a string value or a list of string values, run each value through
the input escape function to make the values into legal font config
strings. The result is returned as a string.
"""
if not np.iterable(val) or isinstance(val, str):
val = [val]

return ','.join(escape_func(r'\\\1', str(x)) for x in val
if x is not None)


def generate_fontconfig_pattern(d):
"""
Given a dictionary of key/value pairs, generates a fontconfig
pattern string.
"""
props = []
for key in 'family style variant weight stretch file size'.split():

# Family is added first w/o a keyword
family = d.get_family()
if family is not None and family != []:
props.append(_escape_val(family, family_escape))

# The other keys are added as key=value
for key in ['style', 'variant', 'weight', 'stretch', 'file', 'size']:
val = getattr(d, 'get_' + key)()
# Don't use 'if not val' because 0 is a valid input.
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))
props.append(":%s=%s" % (key, _escape_val(val, value_escape)))

return ''.join(props)
70 changes: 70 additions & 0 deletions lib/matplotlib/tests/test_fontconfig_pattern.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from matplotlib.font_manager import FontProperties


# Attributes on FontProperties object to check for consistency
keys = [
"get_family",
"get_style",
"get_variant",
"get_weight",
"get_size",
]


def test_fontconfig_pattern():
"Test converting a FontProperties to string then back."

# Defaults
test = "defaults "
f1 = FontProperties()
s = str(f1)

f2 = FontProperties(s)
for k in keys:
assert getattr(f1, k)() == getattr(f2, k)(), test + k

# Basic inputs
test = "basic "
f1 = FontProperties(family="serif", size=20, style="italic")
s = str(f1)

f2 = FontProperties(s)
for k in keys:
assert getattr(f1, k)() == getattr(f2, k)(), test + k

# Full set of inputs.
test = "full "
f1 = FontProperties(family="sans-serif", size=24, weight="bold",
style="oblique", variant="small-caps",
stretch="expanded")
s = str(f1)

f2 = FontProperties(s)
for k in keys:
assert getattr(f1, k)() == getattr(f2, k)(), test + k


def test_fontconfig_str():
"Test FontProperties string conversions for correctness"

# Known good strings taken from actual font config specs on a linux box
# and modified for MPL defaults.

# Default values found by inspection.
test = "defaults "
s = ("sans\\-serif:style=normal:variant=normal:weight=normal"
":stretch=normal:size=12.0")
font = FontProperties(s)
right = FontProperties()
for k in keys:
assert getattr(font, k)() == getattr(right, k)(), test + k

test = "full "
s = ("serif:size=24:style=oblique:variant=small-caps:weight=bold"
":stretch=expanded")
font = FontProperties(s)
right = FontProperties(family="serif", size=24, weight="bold",
style="oblique", variant="small-caps",
stretch="expanded")
for k in keys:
assert getattr(font, k)() == getattr(right, k)(), test + k