|
From: <md...@us...> - 2007-08-06 20:53:37
|
Revision: 3677
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3677&view=rev
Author: mdboom
Date: 2007-08-06 13:53:11 -0700 (Mon, 06 Aug 2007)
Log Message:
-----------
Expose Unicode font functionality for mathtext through rcParams
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/_mathtext_data.py
trunk/matplotlib/lib/matplotlib/mathtext.py
trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc
trunk/matplotlib/lib/matplotlib/rcsetup.py
trunk/matplotlib/matplotlibrc.template
Modified: trunk/matplotlib/lib/matplotlib/_mathtext_data.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2007-08-06 18:52:07 UTC (rev 3676)
+++ trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2007-08-06 20:53:11 UTC (rev 3677)
@@ -2211,7 +2211,7 @@
'$': 36,
'{': 123,
'}': 125,
-'imath': 0xfd,
+'imath': 0x131,
'circumflexaccent' : 770,
'combiningbreve' : 774,
'combiningoverline' : 772,
Modified: trunk/matplotlib/lib/matplotlib/mathtext.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-06 18:52:07 UTC (rev 3676)
+++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-06 20:53:11 UTC (rev 3677)
@@ -133,7 +133,7 @@
from cStringIO import StringIO
from math import floor, ceil
from sets import Set
-from unicodedata import category
+import unicodedata
from warnings import warn
from numpy import inf, isinf
@@ -462,7 +462,7 @@
cached_font = self.fonts.get(basename)
if cached_font is None:
- font = FT2Font(os.path.join(self.basepath, basename + ".ttf"))
+ font = FT2Font(basename)
cached_font = self.CachedFont(font)
self.fonts[basename] = cached_font
self.fonts[font.postscript_name] = cached_font
@@ -545,15 +545,24 @@
"""
Use the Bakoma true type fonts for rendering
"""
- fontmap = { 'cal' : 'cmsy10',
- 'rm' : 'cmr10',
- 'tt' : 'cmtt10',
- 'it' : 'cmmi10',
- 'bf' : 'cmb10',
- 'sf' : 'cmss10',
- 'ex' : 'cmex10'
- }
-
+ _fontmap = { 'cal' : 'cmsy10',
+ 'rm' : 'cmr10',
+ 'tt' : 'cmtt10',
+ 'it' : 'cmmi10',
+ 'bf' : 'cmb10',
+ 'sf' : 'cmss10',
+ 'ex' : 'cmex10'
+ }
+ fontmap = {}
+
+ def __init__(self, *args, **kwargs):
+ TruetypeFonts.__init__(self, *args, **kwargs)
+ if not len(self.fontmap):
+ for key, val in self._fontmap.items():
+ fullpath = os.path.join(self.basepath, val + ".ttf")
+ self.fontmap[key] = fullpath
+ self.fontmap[val] = fullpath
+
def _get_offset(self, cached_font, glyph, fontsize, dpi):
if cached_font.font.postscript_name == 'Cmex10':
return glyph.height/64.0/2.0 + 256.0/64.0 * dpi/72.0
@@ -564,7 +573,7 @@
def _get_glyph(self, fontname, sym, fontsize):
if fontname in self.fontmap and latex_to_bakoma.has_key(sym):
basename, num = latex_to_bakoma[sym]
- slanted = basename == "cmmi10" or sym in self._slanted_symbols
+ slanted = (basename == "cmmi10") or sym in self._slanted_symbols
cached_font = self._get_font(basename)
symbol_name = cached_font.font.get_glyph_name(num)
num = cached_font.glyphmap[num]
@@ -638,15 +647,24 @@
class UnicodeFonts(TruetypeFonts):
"""An abstract base class for handling Unicode fonts.
"""
- fontmap = { 'cal' : 'cmsy10',
- 'rm' : 'DejaVuSerif',
- 'tt' : 'DejaVuSansMono',
- 'it' : 'DejaVuSerif-Italic',
- 'bf' : 'DejaVuSerif-Bold',
- 'sf' : 'DejaVuSans',
- None : 'DejaVuSerif-Italic'
- }
+ fontmap = {}
+
+ def __init__(self, *args, **kwargs):
+ # This must come first so the backend's owner is set correctly
+ if rcParams['mathtext.fallback_to_cm']:
+ self.cm_fallback = BakomaFonts(*args, **kwargs)
+ else:
+ self.cm_fallback = None
+ TruetypeFonts.__init__(self, *args, **kwargs)
+ if not len(self.fontmap):
+ for texfont in "cal rm tt it bf sf".split():
+ setting = rcParams['mathtext.' + texfont]
+ family, weight, style = setting
+ prop = FontProperties(family=family, weight=weight, style=style)
+ font = fontManager.findfont(prop)
+ self.fontmap[texfont] = font
+
def _get_offset(self, cached_font, glyph, fontsize, dpi):
return 0.
@@ -662,34 +680,66 @@
uniindex = get_unicode_index(sym[4:])
fontsize *= GROW_FACTOR
else:
- warn("No TeX to unicode mapping for '%s'" % sym,
+ uniindex = ord('?')
+ warn("No TeX to unicode mapping for '%s'" % sym.encode('ascii', 'replace'),
MathTextWarning)
# Only characters in the "Letter" class should be italicized in 'it'
- # mode. This class includes greek letters, of course.
- if (fontname == 'it'
- and not category(unichr(uniindex)).startswith("L")):
- fontname = 'rm'
+ # mode. Greek capital letters should be Roman.
+ if found_symbol:
+ new_fontname = fontname
- slanted = (fontname == 'it')
-
- cached_font = self._get_font(fontname)
- if found_symbol:
+ if fontname == 'it':
+ unistring = unichr(uniindex)
+ if (not unicodedata.category(unistring).startswith("L")
+ or unicodedata.name(unistring).startswith("GREEK CAPITAL")):
+ new_fontname = 'rm'
+
+ slanted = (new_fontname == 'it')
+ cached_font = self._get_font(new_fontname)
try:
glyphindex = cached_font.charmap[uniindex]
except KeyError:
warn("Font '%s' does not have a glyph for '%s'" %
- (cached_font.font.postscript_name, sym),
+ (cached_font.font.postscript_name, sym.encode('ascii', 'replace')),
MathTextWarning)
found_symbol = False
if not found_symbol:
- uniindex = 0xA4 # currency character, for lack of anything better
- glyphindex = cached_font.charmap[uniindex]
+ if self.cm_fallback:
+ warn("Substituting with a symbol from the Computer Modern family.",
+ MathTextWarning)
+ return self.cm_fallback._get_glyph(fontname, sym, fontsize)
+ else:
+ new_fontname = fontname
+ cached_font = self._get_font(fontname)
+ uniindex = 0xA4 # currency character, for lack of anything better
+ glyphindex = cached_font.charmap[uniindex]
+ slanted = False
symbol_name = cached_font.font.get_glyph_name(glyphindex)
return cached_font, uniindex, symbol_name, fontsize, slanted
+
+ def set_canvas_size(self, w, h):
+ 'Dimension the drawing canvas; may be a noop'
+ TruetypeFonts.set_canvas_size(self, w, h)
+ if self.cm_fallback:
+ self.cm_fallback.set_canvas_size(w, h)
+ def get_used_characters(self):
+ used_characters = dict(self.used_characters)
+ if self.cm_fallback:
+ fallback_characters = self.cm_fallback.get_used_characters()
+ for key, val in fallback_characters:
+ used_characters.setdefault(key, Set()).update(val)
+ return used_characters
+
+ def get_fonts(self):
+ fonts = [x.font for x in self.fonts.values()]
+ if self.cm_fallback:
+ fonts.extend(self.cm_fallback.get_fonts())
+ return list(set(fonts))
+
class StandardPsFonts(Fonts):
"""
Use the standard postscript fonts for rendering to backend_ps
@@ -750,7 +800,7 @@
# This class includes greek letters, so we're ok
if (fontname == 'it' and
(len(sym) > 1 or
- not category(unicode(sym)).startswith("L"))):
+ not unicodedata.category(unicode(sym)).startswith("L"))):
fontname = 'rm'
found_symbol = False
@@ -2302,10 +2352,10 @@
font_output = StandardPsFonts(prop)
else:
backend = self._backend_mapping[self.output]()
- font_output = BakomaFonts(prop, backend)
- # When we have a decent Unicode font, we should test and
- # then make this available as an option
- #~ font_output = UnicodeFonts(prop, backend)
+ if rcParams['mathtext.use_cm']:
+ font_output = BakomaFonts(prop, backend)
+ else:
+ font_output = UnicodeFonts(prop, backend)
fontsize = prop.get_size_in_points()
if self._parser is None:
Modified: trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc
===================================================================
--- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-08-06 18:52:07 UTC (rev 3676)
+++ trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-08-06 20:53:11 UTC (rev 3677)
@@ -159,6 +159,22 @@
# In that case, all text will be sent to TeX for
# processing.
+# The following settings allow you to select the fonts in math mode.
+# They map from a TeX font name to a 3-tuple of the form:
+# (family, weight, style)
+# These settings are only used if mathtext.use_cm is False, otherwise, the
+# Bakoma TeX Computer Modern fonts are used.
+#mathtext.cal : (['cursive'], 'normal', 'normal')
+#mathtext.rm : (['serif'], 'normal', 'normal')
+#mathtext.tt : (['monospace'], 'normal', 'normal')
+#mathtext.it : (['serif'], 'normal', 'oblique')
+#mathtext.bf : (['serif'], 'bold', 'normal')
+#mathtext.sf : (['sans-serif'], 'normal', 'normal')
+#mathtext.use_cm : True
+#mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern
+ # fonts when a symbol can not be found in one of
+ # the user-specified math fonts.
+
### AXES
# default face and edge color, default tick sizes,
# default fontsizes for ticklabels, and so on. See
Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-06 18:52:07 UTC (rev 3676)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-06 20:53:11 UTC (rev 3677)
@@ -198,6 +198,12 @@
except ValueError:
raise ValueError('not a valid font size')
+def validate_mathtext_font(s):
+ s = eval(s)
+ if type(s) in (list, tuple) and len(s) == 3:
+ return s
+ raise ValueError('Mathtext font specifier must be a 3-tuple of (family, weight, style)')
+
validate_markup = ValidateInStrings(
'markup',
['plain', 'tex'],
@@ -357,6 +363,15 @@
'text.fontsize' : ['medium', validate_fontsize],
'text.markup' : ['plain', validate_markup],
+ 'mathtext.cal' : [(['cursive'], 'normal', 'normal'), validate_mathtext_font],
+ 'mathtext.rm' : [(['serif'], 'normal', 'normal'), validate_mathtext_font],
+ 'mathtext.tt' : [(['monospace'], 'normal', 'normal'), validate_mathtext_font],
+ 'mathtext.it' : [(['serif'], 'normal', 'oblique'), validate_mathtext_font],
+ 'mathtext.bf' : [(['serif'], 'bold', 'normal'), validate_mathtext_font],
+ 'mathtext.sf' : [(['sans-serif'], 'normal', 'normal'), validate_mathtext_font],
+ 'mathtext.use_cm' : [True, validate_bool],
+ 'mathtext.fallback_to_cm' : [True, validate_bool],
+
'image.aspect' : ['equal', validate_aspect], # equal, auto, a number
'image.interpolation' : ['bilinear', str],
'image.cmap' : ['jet', str], # one of gray, jet, etc
Modified: trunk/matplotlib/matplotlibrc.template
===================================================================
--- trunk/matplotlib/matplotlibrc.template 2007-08-06 18:52:07 UTC (rev 3676)
+++ trunk/matplotlib/matplotlibrc.template 2007-08-06 20:53:11 UTC (rev 3677)
@@ -159,6 +159,22 @@
# In that case, all text will be sent to TeX for
# processing.
+# The following settings allow you to select the fonts in math mode.
+# They map from a TeX font name to a 3-tuple of the form:
+# (family, weight, style)
+# These settings are only used if mathtext.use_cm is False, otherwise, the
+# Bakoma TeX Computer Modern fonts are used.
+#mathtext.cal : (['cursive'], 'normal', 'normal')
+#mathtext.rm : (['serif'], 'normal', 'normal')
+#mathtext.tt : (['monospace'], 'normal', 'normal')
+#mathtext.it : (['serif'], 'normal', 'oblique')
+#mathtext.bf : (['serif'], 'bold', 'normal')
+#mathtext.sf : (['sans-serif'], 'normal', 'normal')
+#mathtext.use_cm : True
+#mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern
+ # fonts when a symbol can not be found in one of
+ # the user-specified math fonts.
+
### AXES
# default face and edge color, default tick sizes,
# default fontsizes for ticklabels, and so on. See
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|