8000 Merge pull request #2433 from mdboom/unicode-font-filenames · matplotlib/matplotlib@b060f7c · GitHub
[go: up one dir, main page]

Skip to content

Commit b060f7c

Browse files
committed
Merge pull request #2433 from mdboom/unicode-font-filenames
Handle Unicode font filenames correctly/Fix crashing MacOSX backend
2 parents 46b5123 + e2a49e0 commit b060f7c

File tree

11 files changed

+95
-72
lines changed
  • src
  • 11 files changed

    +95
    -72
    lines changed

    lib/matplotlib/backends/backend_agg.py

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -262,7 +262,7 @@ def _get_agg_font(self, prop):
    262262
    font = RendererAgg._fontd.get(fname)
    263263
    if font is None:
    264264
    font = FT2Font(
    265-
    str(fname),
    265+
    fname,
    266266
    hinting_factor=rcParams['text.hinting_factor'])
    267267
    RendererAgg._fontd[fname] = font
    268268
    RendererAgg._fontd[key] = font

    lib/matplotlib/backends/backend_pdf.py

    Lines changed: 6 additions & 5 deletions
    Original file line numberDiff line numberDiff line change
    @@ -585,7 +585,7 @@ def fontName(self, fontprop):
    585585
    self.fontNames[filename] = Fx
    586586
    self.nextFont += 1
    587587
    matplotlib.verbose.report(
    588-
    'Assigning font %s = %s' % (Fx, filename),
    588+
    'Assigning font %s = %r' % (Fx, filename),
    589589
    'debug')
    590590

    591591
    return Fx
    @@ -701,7 +701,7 @@ def createType1Descriptor(self, t1font, fontfile):
    701701
    if 0: flags |= 1 << 17 # TODO: small caps
    702702
    if 0: flags |= 1 << 18 # TODO: force bold
    703703

    704-
    ft2font = FT2Font(str(fontfile))
    704+
    ft2font = FT2Font(fontfile)
    705705

    706706
    descriptor = {
    707707
    'Type': Name('FontDescriptor'),
    @@ -761,7 +761,7 @@ def _get_xobject_symbol_name(self, filename, symbol_name):
    761761
    def embedTTF(self, filename, characters):
    762762
    """Embed the TTF font from the named file into the document."""
    763763

    764-
    font = FT2Font(str(filename))
    764+
    font = FT2Font(filename)
    765765
    fonttype = rcParams['pdf.fonttype']
    766766

    767767
    def cvt(length, upe=font.units_per_EM, nearest=True):
    @@ -845,7 +845,8 @@ def get_char_width(charcode):
    845845

    846846
    # Make the charprocs array (using ttconv to generate the
    847847
    # actual outlines)
    848-
    rawcharprocs = ttconv.get_pdf_charprocs(filename, glyph_ids)
    848+
    rawcharprocs = ttconv.get_pdf_charprocs(
    849+
    filename.encode(sys.getfilesystemencoding()), glyph_ids)
    849850
    charprocs = {}
    850851
    charprocsRef = {}
    851852
    for charname, stream in six.iteritems(rawcharprocs):
    @@ -2003,7 +2004,7 @@ def _get_font_ttf(self, prop):
    20032004
    filename = findfont(prop)
    20042005
    font = self.truetype_font_cache.get(filename)
    20052006
    if font is None:
    2006-
    font = FT2Font(str(filename))
    2007+
    font = FT2Font(filename)
    20072008
    self.truetype_font_cache[filename] = font
    20082009
    self.truetype_font_cache[key] = font
    20092010
    font.clear()

    lib/matplotlib/backends/backend_pgf.py

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -33,7 +33,7 @@
    3333
    system_fonts = []
    3434
    for f in font_manager.findSystemFonts():
    3535
    try:
    36-
    system_fonts.append(FT2Font(str(f)).family_name)
    36+
    system_fonts.append(FT2Font(f).family_name)
    3737
    except RuntimeError:
    3838
    pass # some fonts on osx are known to fail, print?
    3939
    except:

    lib/matplotlib/backends/backend_ps.py

    Lines changed: 5 additions & 3 deletions
    Original file line numberDiff line numberDiff line change
    @@ -391,7 +391,7 @@ def _get_font_ttf(self, prop):
    391391
    fname = findfont(prop)
    392392
    font = self.fontd.get(fname)
    393393
    if font is None:
    394-
    font = FT2Font(str(fname))
    394+
    font = FT2Font(fname)
    395395
    self.fontd[fname] = font
    396396
    self.fontd[key] = font
    397397
    font.clear()
    @@ -1131,7 +1131,7 @@ def print_figure_impl():
    11311131
    if not rcParams['ps.useafm']:
    11321132
    for font_filename, chars in six.itervalues(ps_renderer.used_characters):
    11331133
    if len(chars):
    1134-
    font = FT2Font(str(font_filename))
    1134+
    font = FT2Font(font_filename)
    11351135
    cmap = font.get_charmap()
    11361136
    glyph_ids = []
    11371137
    for c in chars:
    @@ -1153,7 +1153,9 @@ def print_figure_impl():
    11531153
    raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.")
    11541154
    else:
    11551155
    fh.flush()
    1156-
    convert_ttf_to_ps(font_filename, raw_fh, fonttype, glyph_ids)
    1156+
    convert_ttf_to_ps(
    1157+
    font_filename.encode(sys.getfilesystemencoding()),
    1158+
    raw_fh, fonttype, glyph_ids)
    11571159
    print("end", file=fh)
    11581160
    print("%%EndProlog", file=fh)
    11591161

    lib/matplotlib/backends/backend_svg.py

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -323,7 +323,7 @@ def _get_font(self, prop):
    323323
    fname = findfont(prop)
    324324
    font = self.fontd.get(fname)
    325325
    if font is None:
    326-
    font = FT2Font(str(fname))
    326+
    font = FT2Font(fname)
    327327
    self.fontd[fname] = font
    328328
    self.fontd[key] = font
    329329
    font.clear()

    lib/matplotlib/font_manager.py

    Lines changed: 25 additions & 15 deletions
    Original file line numberDiff line numberDiff line change
    @@ -62,7 +62,6 @@
    6262
    parse_fontconfig_pattern, generate_fontconfig_pattern
    6363

    6464
    USE_FONTCONFIG = False
    65-
    6665
    verbose = matplotlib.verbose
    6766

    6867
    font_scalings = {
    @@ -269,16 +268,20 @@ def get_fontconfig_fonts(fontext='ttf'):
    269268

    270269
    fontfiles = {}
    271270
    try:
    272-
    pipe = subprocess.Popen(['fc-list', '', 'file'], stdout=subprocess.PIPE)
    271+
    pipe = subprocess.Popen(['fc-list', '--format=%{file}\\n'], stdout=subprocess.PIPE)
    273272
    output = pipe.communicate()[0]
    274273
    except (OSError, IOError):
    275274
    # Calling fc-list did not work, so we'll just return nothing
    276275
    return fontfiles
    277276

    278277
    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
    282285
    if (os.path.splitext(fname)[1][1:] in fontext and
    283286
    os.path.exists(fname)):
    284287
    fontfiles[fname] = 1
    @@ -570,7 +573,7 @@ def createFontList(fontfiles, fontext='ttf'):
    570573
    continue
    571574
    else:
    572575
    try:
    573-
    font = ft2font.FT2Font(str(fpath))
    576+
    font = ft2font.FT2Font(fpath)
    574577
    except RuntimeError:
    575578
    verbose.report("Could not open font file %s"%fpath)
    576579
    continue
    @@ -720,7 +723,7 @@ def get_name(self):
    720723
    Return the name of the font that best matches the font
    721724
    properties.
    722725
    """
    723-
    return ft2font.FT2Font(str(findfont(self))).family_name
    726+
    return ft2font.FT2Font(findfont(self)).family_name
    724727

    725728
    def get_style(self):
    726729
    """
    @@ -1246,7 +1249,7 @@ def findfont(self, prop, fontext='ttf', directory=None,
    12461249
    else:
    12471250
    verbose.report(
    12481251
    '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))
    12501253
    result = best_font.fname
    12511254

    12521255
    if not os.path.isfile(result):
    @@ -1292,19 +1295,26 @@ def fc_match(pattern, fontext):
    12921295
    fontexts = get_fontext_synonyms(fontext)
    12931296
    ext = "." + fontext
    12941297
    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)
    12961301
    output = pipe.communicate()[0]
    12971302
    except (OSError, IOError):
    12981303
    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().
    12991308
    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
    13051316
    return None
    13061317

    1307-
    _fc_match_regex = re.compile(br'\sfile:\s+"([^"]*)"')
    13081318
    _fc_match_cache = {}
    13091319

    13101320
    def findfont(prop, fontext='ttf'):

    lib/matplotlib/mathtext.py

    Lines changed: 9 additions & 18 deletions
    Original file line numberDiff line numberDiff line change
    @@ -566,7 +566,7 @@ def __init__(self, default_font_prop, mathtext_backend):
    566566
    self._fonts = {}
    567567

    568568
    filename = findfont(default_font_prop)
    569-
    default_font = self.CachedFont(FT2Font(str(filename)))
    569+
    default_font = self.CachedFont(FT2Font(filename))
    570570
    self._fonts['default'] = default_font
    571571
    self._fonts['regular'] = default_font
    572572

    @@ -581,8 +581,8 @@ def _get_font(self, font):
    581581
    basename = font
    582582

    583583
    cached_font = self._fonts.get(basename)
    584-
    if cached_font is None:
    585-
    font = FT2Font(str(basename))
    584+
    if cached_font is None and os.path.exists(basename):
    585+
    font = FT2Font(basename)
    586586
    cached_font = self.CachedFont(font)
    587587
    self._fonts[basename] = cached_font
    588588
    self._fonts[font.postscript_name] = cached_font
    @@ -697,20 +697,14 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
    697697
    if fontname in self.fontmap and sym in latex_to_bakoma:
    698698
    basename, num = latex_to_bakoma[sym]
    699699
    slanted = (basename == "cmmi10") or sym in self._slanted_symbols
    700-
    try:
    701-
    cached_font = self._get_font(basename)
    702-
    except RuntimeError:
    703-
    pass
    704-
    else:
    700+
    cached_font = self._get_font(basename)
    701+
    if cached_font is not None:
    705702
    symbol_name = cached_font.font.get_glyph_name(num)
    706703
    num = cached_font.glyphmap[num]
    707704
    elif len(sym) == 1:
    708705
    slanted = (fontname == "it")
    709-
    try:
    710-
    cached_font = self._get_font(fontname)
    711-
    except RuntimeError:
    712-
    pass
    713-
    else:
    706+
    cached_font = self._get_font(fontname)
    707+
    if cached_font is not None:
    714708
    num = ord(sym)
    715709
    gid = cached_font.charmap.get(num)
    716710
    if gid is not None:
    @@ -852,11 +846,8 @@ def _get_glyph(self, fontname, font_class, sym, fontsize):
    852846

    853847
    slanted = (new_fontname == 'it') or sym in self._slanted_symbols
    854848
    found_symbol = False
    855-
    try:
    856-
    cached_font = self._get_font(new_fontname)
    857-
    except RuntimeError:
    858-
    pass
    859-
    else:
    849+
    cached_font = self._get_font(new_fontname)
    850+
    if cached_font is not None:
    860851
    try:
    861852
    glyphindex = cached_font.charmap[uniindex]
    862853
    found_symbol = True

    lib/matplotlib/textpath.py

    Lines changed: 2 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -56,7 +56,7 @@ def _get_font(self, prop):
    5656
    find a ttf font.
    5757
    """
    5858
    fname = font_manager.findfont(prop)
    59-
    font = FT2Font(str(fname))
    59+
    font = FT2Font(fname)
    6060
    font.set_size(self.FONT_SCALE, self.DPI)
    6161

    6262
    return font
    @@ -338,7 +338,7 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
    338338
    font_bunch = self.tex_font_map[dvifont.texname]
    339339

    340340
    if font_and_encoding is None:
    341-
    font = FT2Font(str(font_bunch.filename))
    341+
    font = FT2Font(font_bunch.filename)
    342342

    343343
    for charmap_name, charmap_code in [("ADOBE_CUSTOM",
    344344
    1094992451),

    0 commit comments

    Comments
     (0)
    0