|
21 | 21 |
|
22 | 22 | family_punc = r'\\\-:,'
|
23 | 23 | _family_unescape = partial(re.compile(r'\\(?=[%s])' % family_punc).sub, '')
|
24 |
| -family_escape = re.compile(r'([%s])' % family_punc).sub |
| 24 | +_family_escape = partial(re.compile(r'(?=[%s])' % family_punc).sub, r'\\') |
25 | 25 |
|
26 | 26 | value_punc = r'\\=_:,'
|
27 | 27 | _value_unescape = partial(re.compile(r'\\(?=[%s])' % value_punc).sub, '')
|
28 |
| -value_escape = re.compile(r'([%s])' % value_punc).sub |
| 28 | +_value_escape = partial(re.compile(r'(?=[%s])' % value_punc).sub, r'\\') |
29 | 29 |
|
30 | 30 | # Remove after module deprecation elapses (3.8); then remove underscores
|
31 |
| -# from _family_unescape and _value_unescape. |
| 31 | +# from _{family,value}_{un,}escape. |
32 | 32 | family_unescape = re.compile(r'\\([%s])' % family_punc).sub
|
33 | 33 | value_unescape = re.compile(r'\\([%s])' % value_punc).sub
|
| 34 | +family_escape = re.compile(r'([%s])' % family_punc).sub |
| 35 | +value_escape = re.compile(r'([%s])' % value_punc).sub |
34 | 36 |
|
35 | 37 |
|
36 | 38 | class FontconfigPatternParser:
|
@@ -127,36 +129,12 @@ def parse(self, pattern):
|
127 | 129 | parse_fontconfig_pattern = lru_cache()(FontconfigPatternParser().parse)
|
128 | 130 |
|
129 | 131 |
|
130 |
| -def _escape_val(val, escape_func): |
131 |
| - """ |
132 |
| - Given a string value or a list of string values, run each value through |
133 |
| - the input escape function to make the values into legal font config |
134 |
| - strings. The result is returned as a string. |
135 |
| - """ |
136 |
| - if not np.iterable(val) or isinstance(val, str): |
137 |
| - val = [val] |
138 |
| - |
139 |
| - return ','.join(escape_func(r'\\\1', str(x)) for x in val |
140 |
| - if x is not None) |
141 |
| - |
142 |
| - |
143 | 132 | def generate_fontconfig_pattern(d):
|
144 |
| - """ |
145 |
| - Given a dictionary of key/value pairs, generates a fontconfig |
146 |
| - pattern string. |
147 |
| - """ |
148 |
| - props = [] |
149 |
| - |
150 |
| - # Family is added first w/o a keyword |
151 |
| - family = d.get_family() |
152 |
| - if family is not None and family != []: |
153 |
| - props.append(_escape_val(family, family_escape)) |
154 |
| - |
155 |
| - # The other keys are added as key=value |
156 |
| - for key in ['style', 'variant', 'weight', 'stretch', 'file', 'size']: |
157 |
| - val = getattr(d, 'get_' + key)() |
158 |
| - # Don't use 'if not val' because 0 is a valid input. |
159 |
| - if val is not None and val != []: |
160 |
| - props.append(":%s=%s" % (key, _escape_val(val, value_escape))) |
161 |
| - |
162 |
| - return ''.join(props) |
| 133 | + """Convert a `.FontProperties` to a fontconfig pattern string.""" |
| 134 | + kvs = [(k, getattr(d, f"get_{k}")()) |
| 135 | + for k in ["style", "variant", "weight", "stretch", "file", "size"]] |
| 136 | + # Families is given first without a leading keyword. Other entries (which |
| 137 | + # are necessarily scalar) are given as key=value, skipping Nones. |
| 138 | + return (",".join(_family_escape(f) for f in d.get_family()) |
| 139 | + + "".join(f":{k}={_value_escape(str(v))}" |
| 140 | + for k, v in kvs if v is not None)) |
0 commit comments