|
From: <md...@us...> - 2009-11-12 20:53:44
|
Revision: 7956
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7956&view=rev
Author: mdboom
Date: 2009-11-12 20:53:36 +0000 (Thu, 12 Nov 2009)
Log Message:
-----------
Fix a number of font manager issues:
1) AFM fonts now store stretch information in the FontManager database
2) pdf.use14corefonts and ps.useafm will now only use the afm files for their respective formats
3) The fontList.cache file is now versioned -- if the version doesn't match the current version of matplotlib it is thrown away and regenerated
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
trunk/matplotlib/lib/matplotlib/font_manager.py
trunk/matplotlib/lib/matplotlib/mathtext.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-12 17:57:13 UTC (rev 7955)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-12 20:53:36 UTC (rev 7956)
@@ -363,6 +363,8 @@
else:
raise ValueError("filename must be a path or a file-like object")
+ self._core14fontdir = os.path.join(
+ rcParams['datapath'], 'fonts', 'pdfcorefonts')
self.fh = fh
self.currentstream = None # stream object to write to, if any
fh.write("%PDF-1.4\n") # 1.4 is the first version to have alpha
@@ -507,7 +509,11 @@
if is_string_like(fontprop):
filename = fontprop
elif rcParams['pdf.use14corefonts']:
- filename = findfont(fontprop, fontext='afm')
+ filename = findfont(
+ fontprop, fontext='afm', directory=self._core14fontdir)
+ if filename is None:
+ filename = findfont(
+ "Helvetica", fontext='afm', directory=self._core14fontdir)
else:
filename = findfont(fontprop)
@@ -1743,7 +1749,12 @@
key = hash(prop)
font = self.afm_font_cache.get(key)
if font is None:
- filename = findfont(prop, fontext='afm')
+ filename = findfont(
+ prop, fontext='afm', directory=self.file._core14fontdir)
+ if filename is None:
+ filename = findfont(
+ "Helvetica", fontext='afm',
+ directory=self.file._core14fontdir)
font = self.afm_font_cache.get(filename)
if font is None:
fh = file(filename)
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-11-12 17:57:13 UTC (rev 7955)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-11-12 20:53:36 UTC (rev 7956)
@@ -170,6 +170,9 @@
self.used_characters = {}
self.mathtext_parser = MathTextParser("PS")
+ self._afm_font_dir = os.path.join(
+ rcParams['datapath'], 'fonts', 'afm')
+
def track_characters(self, font, s):
"""Keeps track of which characters are required from
each font."""
@@ -312,10 +315,13 @@
key = hash(prop)
font = self.afmfontd.get(key)
if font is None:
- fname = findfont(prop, fontext='afm')
+ fname = findfont(prop, fontext='afm', directory=self._afm_font_dir)
+ if fname is None:
+ fname = findfont(
+ "Helvetica", fontext='afm', directory=self._afm_font_dir)
font = self.afmfontd.get(fname)
if font is None:
- font = AFM(file(findfont(prop, fontext='afm')))
+ font = AFM(file(fname))
self.afmfontd[fname] = font
self.afmfontd[key] = font
return font
Modified: trunk/matplotlib/lib/matplotlib/font_manager.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/font_manager.py 2009-11-12 17:57:13 UTC (rev 7955)
+++ trunk/matplotlib/lib/matplotlib/font_manager.py 2009-11-12 20:53:36 UTC (rev 7956)
@@ -301,7 +301,7 @@
except OSError:
# Calling fc-list did not work, so we'll just return nothing
return fontfiles
-
+
if pipe.returncode == 0:
for line in output.split('\n'):
fname = line.split(':')[0]
@@ -463,8 +463,7 @@
# Relative stretches are: wider, narrower
# Child value is: inherit
- # !!!! Incomplete
- if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \
+ if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \
sfnt4.find('cond') >= 0:
stretch = 'condensed'
elif sfnt4.find('demi cond') >= 0:
@@ -502,6 +501,7 @@
"""
name = font.get_familyname()
+ fontname = font.get_fontname().lower()
# Styles are: italic, oblique, and normal (default)
@@ -532,10 +532,16 @@
# and ultra-expanded.
# Relative stretches are: wider, narrower
# Child value is: inherit
+ if fontname.find('narrow') >= 0 or fontname.find('condensed') >= 0 or \
+ fontname.find('cond') >= 0:
+ stretch = 'condensed'
+ elif fontname.find('demi cond') >= 0:
+ stretch = 'semi-condensed'
+ elif fontname.find('wide') >= 0 or fontname.find('expanded') >= 0:
+ stretch = 'expanded'
+ else:
+ stretch = 'normal'
- # !!!! Incomplete
- stretch = 'normal'
-
# Sizes can be absolute and relative.
# Absolute sizes are: xx-small, x-small, small, medium, large, x-large,
# and xx-large.
@@ -960,12 +966,20 @@
matches the specification. If no good enough match is found, a
default font is returned.
"""
+ # Increment this version number whenever the font cache data
+ # format or behavior has changed and requires a existing font
+ # cache files to be rebuilt.
+ __version__ = 5
+
def __init__(self, size=None, weight='normal'):
+ self._version = self.__version__
+
self.__default_weight = weight
self.default_size = size
paths = [os.path.join(rcParams['datapath'], 'fonts', 'ttf'),
- os.path.join(rcParams['datapath'], 'fonts', 'afm')]
+ os.path.join(rcParams['datapath'], 'fonts', 'afm'),
+ os.path.join(rcParams['datapath'], 'fonts', 'pdfcorefonts')]
# Create list of font paths
for pathname in ['TTFPATH', 'AFMPATH']:
@@ -982,32 +996,23 @@
# Load TrueType fonts and create font dictionary.
self.ttffiles = findSystemFonts(paths) + findSystemFonts()
+ self.defaultFont = {}
for fname in self.ttffiles:
verbose.report('trying fontname %s' % fname, 'debug')
if fname.lower().find('vera.ttf')>=0:
- self.defaultFont = fname
+ self.defaultFont['ttf'] = fname
break
else:
# use anything
- self.defaultFont = self.ttffiles[0]
+ self.defaultFont['ttf'] = self.ttffiles[0]
self.ttflist = createFontList(self.ttffiles)
- if rcParams['pdf.use14corefonts']:
- # Load only the 14 PDF core fonts. These fonts do not need to be
- # embedded; every PDF viewing application is required to have them:
- # Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique,
- # Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique,
- # Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Symbol,
- # ZapfDingbats.
- afmpath = os.path.join(rcParams['datapath'],'fonts','pdfcorefonts')
- afmfiles = findSystemFonts(afmpath, fontext='afm')
- self.afmlist = createFontList(afmfiles, fontext='afm')
- else:
- self.afmfiles = findSystemFonts(paths, fontext='afm') + \
- findSystemFonts(fontext='afm')
- self.afmlist = createFontList(self.afmfiles, fontext='afm')
+ self.afmfiles = findSystemFonts(paths, fontext='afm') + \
+ findSystemFonts(fontext='afm')
+ self.afmlist = createFontList(self.afmfiles, fontext='afm')
+ self.defaultFont['afm'] = None
self.ttf_lookup_cache = {}
self.afm_lookup_cache = {}
@@ -1151,7 +1156,7 @@
return 1.0
return abs(sizeval1 - sizeval2) / 72.0
- def findfont(self, prop, fontext='ttf'):
+ def findfont(self, prop, fontext='ttf', directory=None):
"""
Search the font list for the font that most closely matches
the :class:`FontProperties` *prop*.
@@ -1162,6 +1167,9 @@
returned. If no matches below a certain threshold are found,
the default font (usually Vera Sans) is returned.
+ `directory`, is specified, will only return fonts from the
+ given directory (or subdirectory of that directory).
+
The result is cached, so subsequent lookups don't have to
perform the O(n) nearest neighbor search.
@@ -1194,6 +1202,10 @@
best_font = None
for font in fontlist:
+ if (directory is not None and
+ os.path.commonprefix([font.fname, directory]) != directory):
+ print directory, font.fname, os.path.commonprefix([font.fname, directory])
+ continue
# Matching family should have highest priority, so it is multiplied
# by 10.0
score = \
@@ -1211,8 +1223,8 @@
if best_font is None or best_score >= 10.0:
verbose.report('findfont: Could not match %s. Returning %s' %
- (prop, self.defaultFont))
- result = self.defaultFont
+ (prop, self.defaultFont[fontext]))
+ result = self.defaultFont[fontext]
else:
verbose.report('findfont: Matching %s to %s (%s) with score of %f' %
(prop, best_font.name, best_font.fname, best_score))
@@ -1289,16 +1301,16 @@
try:
fontManager = pickle_load(_fmcache)
- fontManager.default_size = None
- verbose.report("Using fontManager instance from %s" % _fmcache)
+ if (not hasattr(fontManager, '_version') or
+ fontManager._version != FontManager.__version__):
+ _rebuild()
+ else:
+ fontManager.default_size = None
+ verbose.report("Using fontManager instance from %s" % _fmcache)
except:
_rebuild()
def findfont(prop, **kw):
global fontManager
font = fontManager.findfont(prop, **kw)
- if not os.path.exists(font):
- verbose.report("%s returned by pickled fontManager does not exist" % font)
- _rebuild()
- font = fontManager.findfont(prop, **kw)
return font
Modified: trunk/matplotlib/lib/matplotlib/mathtext.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mathtext.py 2009-11-12 17:57:13 UTC (rev 7955)
+++ trunk/matplotlib/lib/matplotlib/mathtext.py 2009-11-12 20:53:36 UTC (rev 7956)
@@ -1032,7 +1032,11 @@
self.glyphd = {}
self.fonts = {}
- filename = findfont(default_font_prop, fontext='afm')
+ filename = findfont(default_font_prop, fontext='afm',
+ directory=self.basepath)
+ if filename is None:
+ filename = findfont('Helvetica', fontext='afm',
+ directory=self.basepath)
default_font = AFM(file(filename, 'r'))
default_font.fname = filename
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|