Could not fire up pylab in Japanese Win XP (the font attached)

Hi, Thanks to MASUDA-san's advice, I could find the

    > problematic TTF font.

    > Please see attached font JRLM00M.TTF

OK, I can replicate the bug on windows and linux -- thanks for the
test file. Even though I've found where the bug is occurring -- the
call to

  setattr("family_name", Py::String(face->family_name);

in ft2font.cpp, the fix is not immediately obvious, so we'll continue
to work on it and I'll keep you posted. In the interim, hopefully you
can remove the troublesome files from your font path and still use
matplotlib.

JDH

John Hunter wrote:

OK, I can replicate the bug on windows and linux -- thanks for the
test file. Even though I've found where the bug is occurring -- the
call to

  setattr("family_name", Py::String(face->family_name);

in ft2font.cpp, the fix is not immediately obvious, so we'll continue
to work on it and I'll keep you posted. In the interim, hopefully you
can remove the troublesome files from your font path and still use
matplotlib.

John,
Thank you for your immidiate response.

As I had to modify Yasushi's script to find the troublesome fonts,
for the sake of possible followers, I post the modified script here as
'font_test.py'.
With this script, I did not remove the font from the system,
just added to the list 'exlude' defined in the bottom part of
the script.

The same idea worked for function createFontDict in font_manager.py,
though its a very clumsy work-around for the problem, I know.
Maybe, you can list the dangerous font in somewhere in the .rcfile, until the problem in ft2font.cpp is solved.

Anyway, thanks a lot. I'll start to do the plotting.

Natsu

···

---

def createFontDict(fontfiles, fontext='ttf'):
     """A function to create a dictionary of font file paths. The
default is to create a dictionary for TrueType fonts. An AFM font
dictionary can optionally be created.
"""
     fontdict = {}
     exclude = ['JRLM00M.TTF', ] ## modified
     # Add fonts from list of known font files.
     seen = {}
     for fpath in fontfiles:
         fname = os.path.split(fpath)[-1] ## modified
         if seen.has_key(fname): continue
         else: seen[fname] = 1
         if fontext == 'ttf':
             if fname in exclude: continue ## modified
             try:
                 font = ft2font.FT2Font(str(fpath))
             except RuntimeError:
                 verbose.report_error("Could not open font file %s"%fpath)
                 continue
             prop = ttfFontProperty(font)
--- snip ---

----- font_test.py -----
import os
import glob
import sys

from matplotlib import rcParams
from matplotlib.ft2font import FT2Font
## from matplotlib.font_manager import findSystemFonts
## Original script failed here.

MSFolders = \
     r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'

MSFontDirectories = [
     r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
     r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']

def win32FontDirectory():
     """Return the user-specified font directory for Win32."""

     try:
         import _winreg
     except ImportError:
         return os.path.join(os.environ['WINDIR'], 'Fonts')
     else:
         user = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, MSFolders)
         try:
             return _winreg.QueryValueEx(user, 'Fonts')[0]
         finally:
             _winreg.CloseKey(user)
     return None

def findSystemFonts(fontpaths=None, fontext='ttf'):
     """Search for fonts in the specified font paths, or use the system
paths if none given. A list of TrueType fonts are returned by default
with AFM fonts as an option.
"""
     fontfiles = {}

     if fontpaths is None:

         if sys.platform == 'win32':
             fontdir = win32FontDirectory()

             fontpaths = [fontdir]
             # now get all installed fonts directly...
             for f in win32InstalledFonts(fontdir):
                 base, ext = os.path.splitext(f)
                 if len(ext)>1 and ext[1:].lower()==fontext:
                     fontfiles[f] = 1
         else:
             fontpaths = x11FontDirectory()
     elif isinstance(fontpaths, (str, unicode)):
         fontpaths = [fontpaths]
     for path in fontpaths:
         for fname in glob.glob(os.path.join(path, '*.'+fontext)):

             fontfiles[os.path.abspath(fname)] = 1
     return [fname for fname in fontfiles.keys() if os.path.exists(fname)]

def win32InstalledFonts(directory=None, fontext='ttf'):
     """Search for fonts in the specified font directory, or use the
system directories if none given. A list of TrueType fonts are
returned by default with AFM fonts as an option.
"""
     import _winreg
     if directory is None:
         directory = win32FontDirectory()

     key, items = None, {}
     for fontdir in MSFontDirectories:
         try:
             local = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, fontdir)
         except OSError:
             continue
         local = None

         if not local:
             return glob.glob(os.path.join(directory, '*.'+fontext))
         try:
             for j in range(_winreg.QueryInfoKey(local)[1]):
                 try:
                     key, direc, any = _winreg.EnumValue( local, j)
                     if not os.path.dirname(direc):
                         direc = os.path.join(directory, direc)
                     direc = os.path.abspath(direc).lower()
                     if direc[-4:] == '.'+fontext:
                         items[direc] = 1
                 except EnvironmentError:
                     pass
             return items.keys()
         finally:
             _winreg.CloseKey(local)
     return None

paths = [rcParams['datapath']]
if os.environ.has_key('TTFPATH'):
     ttfpath = os.environ['TTFPATH']
     if ttfpath.find(';') >= 0: #win32 style
         paths.extend(ttfpath.split(';'))
     else:
         paths.append(ttfpath)

ttffiles = findSystemFonts(paths) + findSystemFonts()

exclude = ['JRLM00M.TTF', ]

for fpath in ttffiles:
     fname = os.path.split(fpath)[-1]
     if fname in exclude:
         pass
     else:
         print "probing %s" %(str(fpath))
         font = FT2Font(str(fpath))
print "all fine."