From: Yasushi M. <ym...@et...> - 2005-03-18 09:32:38
|
Hello, This problem seems to caused by (unhandled) ft2font.pyd crash for some kind of third-party TTF fonts. In font_manager.py, createFontDict: try: font = ft2font.FT2Font(str(fpath)) # <---- HERE except RuntimeError: verbose.report_error("Could not open font file %s"%fpath) continue For any 'clean' Japanese WinXP box having only MS-bundled TTFfonts, matplotlib 0.72.1 runs fine, but with some third-party fonts are problematic even though they seem to have no problem with other Windows applications. In my case, two Japanese fonts were wrong. (I don't think this is Japanese-font specific problem, because I have many Japanese fonts in my C:/WINDOWS/Fonts directory.) I'm now looking into ft2pyd sources to find exact cause, but it will take a while (I'm not expert in font handling). Instead, you may find fonts causing problem with following script: --------------- import os from matplotlib import rcParams from matplotlib.ft2font import FT2Font from matplotlib.font_manager import findSystemFonts 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() for fpath in ttffiles: print "probing %s" %(str(fpath)) font = FT2Font(str(fpath)) print "all fine.' ------------- This program will crash at the problematic font. Remove it from font directory and run again untill it says all fine. After removing all problematic fonts, Your matplotlib will work. Thanks. 2005-03-17 01:31, Natsu wrote: > Hi, > After resolving the font_manager.py issue, I could fire up pylab on > Japanese Win 2K. However, on my Win XP Japanese PCs, there seems > some trouble remaining. > > The following result was obtained with Enthogut python 2.3.3 on XP > professional Version 2002 SP1, Japanese. > On other PC with XP SP2, Japanese, I got a similar error. > So I"m afraid it is repeatable to any Japanese Win XP. > > Maybe, my WinXPs are not fresh and clean. What do you think? > I"m ready to test the special debugging build which was mentioned in the > list earlier, if the binaries are sent to me. > --- Yasushi Masuda http://www.cubelab.com/ymasuda/ |
From: John H. <jdh...@ac...> - 2005-03-18 14:48:44
|
>>>>> "Yasushi" == Yasushi MASUDA <ym...@et...> writes: Yasushi> Hello, This problem seems to caused by (unhandled) Yasushi> ft2font.pyd crash for some kind of third-party TTF fonts. I will try and send you a debug build today so you can identify where the problem font is. Also, if you send me a problem ttf font file and I can replicate the problem on my system, I can probably diagnose it and fix it myself, which would be more efficient. Thanks for working on this. JDH |
From: John H. <jdh...@ac...> - 2005-03-18 19:30:58
|
>>>>> "Natsu" == Natsu <nat...@ya...> writes: Natsu> Hi, Thanks to MASUDA-san's advice, I could find the Natsu> problematic TTF font. Natsu> 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 |
From: Natsu <nat...@ya...> - 2005-03-19 02:06:14
|
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." |