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.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to