|
62 | 62 | parse_fontconfig_pattern, generate_fontconfig_pattern
|
63 | 63 |
|
64 | 64 | USE_FONTCONFIG = False
|
65 |
| - |
66 | 65 | verbose = matplotlib.verbose
|
67 | 66 |
|
68 | 67 | font_scalings = {
|
@@ -269,16 +268,20 @@ def get_fontconfig_fonts(fontext='ttf'):
|
269 | 268 |
|
270 | 269 | fontfiles = {}
|
271 | 270 | try:
|
272 |
| - pipe = subprocess.Popen(['fc-list', '', 'file'], stdout=subprocess.PIPE) |
| 271 | + pipe = subprocess.Popen(['fc-list', '--format=%{file}\\n'], stdout=subprocess.PIPE) |
273 | 272 | output = pipe.communicate()[0]
|
274 | 273 | except (OSError, IOError):
|
275 | 274 | # Calling fc-list did not work, so we'll just return nothing
|
276 | 275 | return fontfiles
|
277 | 276 |
|
278 | 277 | if pipe.returncode == 0:
|
279 |
| - output = str(output) |
280 |
| - for line in output.split('\n'): |
281 |
| - fname = line.split(':')[0] |
| 278 | + # The line breaks between results are in ascii, but each entry |
| 279 | + # is in in sys.filesystemencoding(). |
| 280 | + for fname in output.split(b'\n'): |
| 281 | + try: |
| 282 | + fname = six.text_type(fname, sys.getfilesystemencoding()) |
| 283 | + except UnicodeDecodeError: |
| 284 | + continue |
282 | 285 | if (os.path.splitext(fname)[1][1:] in fontext and
|
283 | 286 | os.path.exists(fname)):
|
284 | 287 | fontfiles[fname] = 1
|
@@ -570,7 +573,7 @@ def createFontList(fontfiles, fontext='ttf'):
|
570 | 573 | continue
|
571 | 574 | else:
|
572 | 575 | try:
|
573 |
| - font = ft2font.FT2Font(str(fpath)) |
| 576 | + font = ft2font.FT2Font(fpath) |
574 | 577 | except RuntimeError:
|
575 | 578 | verbose.report("Could not open font file %s"%fpath)
|
576 | 579 | continue
|
@@ -720,7 +723,7 @@ def get_name(self):
|
720 | 723 | Return the name of the font that best matches the font
|
721 | 724 | properties.
|
722 | 725 | """
|
723 |
| - return ft2font.FT2Font(str(findfont(self))).family_name |
| 726 | + return ft2font.FT2Font(findfont(self)).family_name |
724 | 727 |
|
725 | 728 | def get_style(self):
|
726 | 729 | """
|
@@ -1246,7 +1249,7 @@ def findfont(self, prop, fontext='ttf', directory=None,
|
1246 | 1249 | else:
|
1247 | 1250 | verbose.report(
|
1248 | 1251 | 'findfont: Matching %s to %s (%s) with score of %f' %
|
1249 |
| - (prop, best_font.name, best_font.fname, best_score)) |
| 1252 | + (prop, best_font.name, repr(best_font.fname), best_score)) |
1250 | 1253 | result = best_font.fname
|
1251 | 1254 |
|
1252 | 1255 | if not os.path.isfile(result):
|
@@ -1292,19 +1295,26 @@ def fc_match(pattern, fontext):
|
1292 | 1295 | fontexts = get_fontext_synonyms(fontext)
|
1293 | 1296 | ext = "." + fontext
|
1294 | 1297 | try:
|
1295 |
| - pipe = subprocess.Popen(['fc-match', '-sv', pattern], stdout=subprocess.PIPE) |
| 1298 | + pipe = subprocess.Popen( |
| 1299 | + ['fc-match', '-s', '--format=%{file}\\n', pattern], |
| 1300 | + stdout=subprocess.PIPE) |
1296 | 1301 | output = pipe.communicate()[0]
|
1297 | 1302 | except (OSError, IOError):
|
1298 | 1303 | return None
|
| 1304 | + |
| 1305 | + # The bulk of the output from fc-list is ascii, so we keep the |
| 1306 | + # result in bytes and parse it as bytes, until we extract the |
| 1307 | + # filename, which is in sys.filesystemencoding(). |
1299 | 1308 | if pipe.returncode == 0:
|
1300 |
| - for match in _fc_match_regex.finditer(output): |
1301 |
| - file = match.group(1) |
1302 |
| - file = file.decode(sys.getfilesystemencoding()) |
1303 |
| - if os.path.splitext(file)[1][1:] in fontexts: |
1304 |
| - return file |
| 1309 | + for fname in output.split(b'\n'): |
| 1310 | + try: |
| 1311 | + fname = six.text_type(fname, sys.getfilesystemencoding()) |
| 1312 | + except UnicodeDecodeError: |
| 1313 | + continue |
| 1314 | + if os.path.splitext(fname)[1][1:] in fontexts: |
| 1315 | + return fname |
1305 | 1316 | return None
|
1306 | 1317 |
|
1307 |
| - _fc_match_regex = re.compile(br'\sfile:\s+"([^"]*)"') |
1308 | 1318 | _fc_match_cache = {}
|
1309 | 1319 |
|
1310 | 1320 | def findfont(prop, fontext='ttf'):
|
|
0 commit comments