From: <md...@us...> - 2007-07-18 13:16:38
|
Revision: 3557 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3557&view=rev Author: mdboom Date: 2007-07-18 06:16:35 -0700 (Wed, 18 Jul 2007) Log Message: ----------- Got mixed text/math working for Agg, Ps (non-afm) and Pdf (non-afm). All other backends can be considered horribly broken on this branch. Modified Paths: -------------- branches/mathtext_mgd/lib/matplotlib/backends/backend_agg.py branches/mathtext_mgd/lib/matplotlib/backends/backend_pdf.py branches/mathtext_mgd/lib/matplotlib/backends/backend_ps.py branches/mathtext_mgd/lib/matplotlib/mathtext.py branches/mathtext_mgd/lib/matplotlib/text.py Modified: branches/mathtext_mgd/lib/matplotlib/backends/backend_agg.py =================================================================== --- branches/mathtext_mgd/lib/matplotlib/backends/backend_agg.py 2007-07-18 07:38:05 UTC (rev 3556) +++ branches/mathtext_mgd/lib/matplotlib/backends/backend_agg.py 2007-07-18 13:16:35 UTC (rev 3557) @@ -180,10 +180,9 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - size = prop.get_size_in_points() - width, height, fonts = math_parse_s_ft2font( - s, self.dpi.get(), size, angle) - + width, height, fonts, used_characters = math_parse_s_ft2font( + s, self.dpi.get(), prop, angle) + if angle == 90: width, height = height, width for font in fonts: @@ -232,7 +231,6 @@ # texmanager more efficient. It is not meant to be used # outside the backend """ - if ismath=='TeX': # todo: handle props size = prop.get_size_in_points() @@ -242,8 +240,8 @@ return n,m if ismath: - width, height, fonts = math_parse_s_ft2font( - s, self.dpi.get(), prop.get_size_in_points()) + width, height, fonts, used_characters = math_parse_s_ft2font( + s, self.dpi.get(), prop) return width, height font = self._get_agg_font(prop) font.set_text(s, 0.0) # the width and height of unrotated string Modified: branches/mathtext_mgd/lib/matplotlib/backends/backend_pdf.py =================================================================== --- branches/mathtext_mgd/lib/matplotlib/backends/backend_pdf.py 2007-07-18 07:38:05 UTC (rev 3556) +++ branches/mathtext_mgd/lib/matplotlib/backends/backend_pdf.py 2007-07-18 13:16:35 UTC (rev 3557) @@ -456,8 +456,10 @@ fontdictObject = self._write_afm_font(filename) else: realpath, stat_key = get_realpath_and_stat(filename) - fontdictObject = self.embedTTF( - *self.used_characters[stat_key]) + chars = self.used_characters.get(stat_key) + if chars is not None: + fontdictObject = self.embedTTF( + *self.used_characters[stat_key]) fonts[Fx] = fontdictObject #print >>sys.stderr, filename self.writeObject(self.fontObject, fonts) @@ -932,7 +934,14 @@ used_characters = self.used_characters.setdefault( stat_key, (realpath, sets.Set())) used_characters[1].update(s) + print [(os.path.basename(x), y) for x, y in self.used_characters.values()] + def merge_used_characters(self, other): + for stat_key, (realpath, set) in other.items(): + used_characters = self.used_characters.setdefault( + stat_key, (realpath, sets.Set())) + used_characters[1].update(set) + def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation): """ @@ -1085,8 +1094,9 @@ def draw_mathtext(self, gc, x, y, s, prop, angle): # TODO: fix positioning and encoding - fontsize = prop.get_size_in_points() - width, height, pswriter = math_parse_s_pdf(s, 72, fontsize, 0, self.track_characters) + width, height, pswriter, used_characters = \ + math_parse_s_pdf(s, 72, prop, 0) + self.merge_used_characters(used_characters) self.check_gc(gc, gc._rgb) self.file.output(Op.begin_text) @@ -1094,7 +1104,7 @@ oldx, oldy = 0, 0 for ox, oy, fontname, fontsize, glyph in pswriter: #print ox, oy, glyph - fontname = fontname.lower() + #fontname = fontname.lower() a = angle / 180.0 * pi newx = x + cos(a)*ox - sin(a)*oy newy = y + sin(a)*ox + cos(a)*oy @@ -1199,9 +1209,7 @@ s = s.encode('cp1252', 'replace') if ismath: - fontsize = prop.get_size_in_points() - w, h, pswriter = math_parse_s_pdf( - s, 72, fontsize, 0, self.track_characters) + w, h, pswriter, used_characters = math_parse_s_pdf(s, 72, prop, 0) elif rcParams['pdf.use14corefonts']: font = self._get_font_afm(prop) Modified: branches/mathtext_mgd/lib/matplotlib/backends/backend_ps.py =================================================================== --- branches/mathtext_mgd/lib/matplotlib/backends/backend_ps.py 2007-07-18 07:38:05 UTC (rev 3556) +++ branches/mathtext_mgd/lib/matplotlib/backends/backend_ps.py 2007-07-18 13:16:35 UTC (rev 3557) @@ -154,6 +154,12 @@ stat_key, (realpath, sets.Set())) used_characters[1].update(s) + def merge_used_characters(self, other): + for stat_key, (realpath, set) in other.items(): + used_characters = self.used_characters.setdefault( + stat_key, (realpath, sets.Set())) + used_characters[1].update(set) + def set_color(self, r, g, b, store=1): if (r,g,b) != self.color: if r==g and r==b: @@ -272,8 +278,8 @@ return w, h if ismath: - width, height, pswriter = math_parse_s_ps( - s, 72, prop.get_size_in_points(), 0, self.track_characters) + width, height, pswriter, used_characters = math_parse_s_ps( + s, 72, prop, 0) return width, height if rcParams['ps.useafm']: @@ -808,8 +814,9 @@ if debugPS: self._pswriter.write("% mathtext\n") - fontsize = prop.get_size_in_points() - width, height, pswriter = math_parse_s_ps(s, 72, fontsize, angle, self.track_characters) + width, height, pswriter, used_characters = \ + math_parse_s_ps(s, 72, prop, angle) + self.merge_used_characters(used_characters) self.set_color(*gc.get_rgb()) thetext = pswriter.getvalue() ps = """gsave Modified: branches/mathtext_mgd/lib/matplotlib/mathtext.py =================================================================== --- branches/mathtext_mgd/lib/matplotlib/mathtext.py 2007-07-18 07:38:05 UTC (rev 3556) +++ branches/mathtext_mgd/lib/matplotlib/mathtext.py 2007-07-18 13:16:35 UTC (rev 3557) @@ -119,9 +119,13 @@ KNOWN ISSUES: - - nesting fonts changes in sub/superscript groups not parsing - I would also like to add a few more layout commands, like \frac. +STATUS: + The *Unicode* classes were incomplete when I found them, and have + not been refactored to support intermingling of regular text and + math text yet. They are most likely broken. -- Michael Droettboom, July 2007 + Author : John Hunter <jdh...@ac...> Copyright : John Hunter (2004,2005) License : matplotlib license (PSF compatible) @@ -130,6 +134,7 @@ from __future__ import division import os, sys from cStringIO import StringIO +from sets import Set from matplotlib import verbose from matplotlib.pyparsing import Literal, Word, OneOrMore, ZeroOrMore, \ @@ -138,7 +143,7 @@ operatorPrecedence, opAssoc, ParseResults, Or, Suppress, oneOf from matplotlib.afm import AFM -from matplotlib.cbook import enumerate, iterable, Bunch +from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat from matplotlib.ft2font import FT2Font from matplotlib.font_manager import fontManager, FontProperties from matplotlib._mathtext_data import latex_to_bakoma, cmkern, \ @@ -544,80 +549,111 @@ # Old classes -class BakomaTrueTypeFonts(Fonts): +class BakomaFonts(Fonts): """ Use the Bakoma true type fonts for rendering """ - fnames = ('cmmi10', 'cmsy10', 'cmex10', - 'cmtt10', 'cmr10', 'cmb10', 'cmss10') # allocate a new set of fonts basepath = os.path.join( get_data_path(), 'fonts', 'ttf' ) - fontmap = { 'cal' : 'cmsy10', - 'rm' : 'cmr10', - 'tt' : 'cmtt10', - 'it' : 'cmmi10', - 'bf' : 'cmb10', - 'sf' : 'cmss10', - None : 'cmmi10', + fontmap = { 'cal' : 'Cmsy10', + 'rm' : 'Cmr10', + 'tt' : 'Cmtt10', + 'it' : 'Cmmi10', + 'bf' : 'Cmb10', + 'sf' : 'Cmss10', + None : 'Cmmi10', + 'ex' : 'Cmex10' } - def __init__(self, useSVG=False): - self.glyphd = {} - self.fonts = dict( - [ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) - for name in self.fnames]) + class FontCache: + def __init__(self, font): + self.font = font + self.charmap = font.get_charmap() + self.glyphmap = dict( + [(glyphind, ccode) for ccode, glyphind in self.charmap.items()]) + + def __init__(self): + self.glyphd = {} + self.fonts = {} + self.used_characters = {} + + # MGDTODO: Separate this out into an SVG class +# if useSVG: +# self.svg_glyphs = [] # a list of "glyphs" we need to render this thing in SVG +# else: pass +# self.usingSVG = useSVG - self.charmaps = dict( - [ (name, self.fonts[name].get_charmap()) for name in self.fnames]) - # glyphmaps is a dict names to a dict of glyphindex -> charcode - self.glyphmaps = {} - for name in self.fnames: - cmap = self.charmaps[name] - self.glyphmaps[name] = dict([(glyphind, ccode) for ccode, glyphind in cmap.items()]) + def _get_font(self, font): + """Looks up a FontCache with its charmap and inverse charmap. + font may be a TeX font name (cal, rm, it etc.), a Computer Modern + font name (cmtt10, cmr10, etc.) or an FT2Font object.""" + if isinstance(font, str): + if font not in self.fontmap.values(): + basename = self.fontmap[font] + else: + basename = font + else: + basename = font.postscript_name - for font in self.fonts.values(): - font.clear() - if useSVG: - self.svg_glyphs=[] # a list of "glyphs" we need to render this thing in SVG - else: pass - self.usingSVG = useSVG + font_cache = self.fonts.get(basename) + if font_cache is None: + if isinstance(font, str): + font = FT2Font(os.path.join(self.basepath, basename.lower() + '.ttf')) + basename = font.postscript_name + font_cache = self.FontCache(font) + self.fonts[basename] = font_cache + return basename, font_cache + def get_fonts(self): + return [x.font for x in self.fonts.values()] + def get_metrics(self, font, sym, fontsize, dpi): - cmfont, metrics, glyph, offset = \ + basename, font, metrics, symbol_name, num, glyph, offset = \ self._get_info(font, sym, fontsize, dpi) return metrics + def _get_offset(self, basename, font_cache, glyph, fontsize, dpi): + if basename.lower() == 'cmex10': + return glyph.height/64.0/2 + 256.0/64.0*dpi/72.0 + return 0. + def _get_info (self, font, sym, fontsize, dpi): 'load the cmfont, metrics and glyph with caching' - key = font, sym, fontsize, dpi + if hasattr(font, 'postscript_name'): + fontname = font.postscript_name + else: + fontname = font + + key = fontname, sym, fontsize, dpi tup = self.glyphd.get(key) if tup is not None: return tup - - basename = self.fontmap[font] - - if latex_to_bakoma.has_key(sym): + + if font in self.fontmap and latex_to_bakoma.has_key(sym): basename, num = latex_to_bakoma[sym] - num = self.glyphmaps[basename][num] + basename, font_cache = self._get_font(basename.capitalize()) + symbol_name = font_cache.font.get_glyph_name(num) + num = font_cache.glyphmap[num] elif len(sym) == 1: + basename, font_cache = self._get_font(font) num = ord(sym) + symbol_name = font_cache.font.get_glyph_name(font_cache.charmap[num]) else: num = 0 raise ValueError('unrecognized symbol "%s"' % sym) - #print sym, basename, num - cmfont = self.fonts[basename] - cmfont.set_size(fontsize, dpi) - head = cmfont.get_sfnt_table('head') - glyph = cmfont.load_char(num) + font = font_cache.font + font.set_size(fontsize, dpi) + glyph = font.load_char(num) + realpath, stat_key = get_realpath_and_stat(font.fname) + used_characters = self.used_characters.setdefault( + stat_key, (realpath, Set())) + used_characters[1].update(unichr(num)) + xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox] - if basename == 'cmex10': - offset = glyph.height/64.0/2 + 256.0/64.0*dpi/72.0 - #offset = -(head['yMin']+512)/head['unitsPerEm']*10. - else: - offset = 0. + offset = self._get_offset(basename, font_cache, glyph, fontsize, dpi) metrics = Bunch( advance = glyph.linearHoriAdvance/65536.0, height = glyph.height/64.0, @@ -627,38 +663,37 @@ ymin = ymin+offset, ymax = ymax+offset, ) - - self.glyphd[key] = cmfont, metrics, glyph, offset + + self.glyphd[key] = basename, font, metrics, symbol_name, num, glyph, offset return self.glyphd[key] def set_canvas_size(self, w, h): 'Dimension the drawing canvas; may be a noop' self.width = int(w) self.height = int(h) - for font in self.fonts.values(): - font.set_bitmap_size(int(w), int(h)) + for font_cache in self.fonts.values(): + font_cache.font.set_bitmap_size(int(w), int(h)) def render(self, ox, oy, font, sym, fontsize, dpi): - cmfont, metrics, glyph, offset = \ + basename, font, metrics, symbol_name, num, glyph, offset = \ self._get_info(font, sym, fontsize, dpi) - if not self.usingSVG: - cmfont.draw_glyph_to_bitmap( - int(ox), int(self.height - oy - metrics.ymax), glyph) - else: - oy += offset - 512/2048.*10. - basename = self.fontmap[font] - if latex_to_bakoma.has_key(sym): - basename, num = latex_to_bakoma[sym] - num = self.glyphmaps[basename][num] - elif len(sym) == 1: - num = ord(sym) - else: - num = 0 - print >>sys.stderr, 'unrecognized symbol "%s"' % sym - thetext = unichr(num) - thetext.encode('utf-8') - self.svg_glyphs.append((basename, fontsize, thetext, ox, oy, metrics)) + font.draw_glyph_to_bitmap( + int(ox), int(self.height - oy - metrics.ymax), glyph) +# else: +# oy += offset - 512/2048.*10. +# basename = self.fontmap[font] +# if latex_to_bakoma.has_key(sym): +# basename, num = latex_to_bakoma[sym] +# num = self.glyphmaps[basename][num] +# elif len(sym) == 1: +# num = ord(sym) +# else: +# num = 0 +# print >>sys.stderr, 'unrecognized symbol "%s"' % sym +# thetext = unichr(num) +# thetext.encode('utf-8') +# self.svg_glyphs.append((basename, fontsize, thetext, ox, oy, metrics)) def _old_get_kern(self, font, symleft, symright, fontsize, dpi): @@ -680,153 +715,46 @@ #print basename, symleft, symright, key, kern return kern - def _get_num(self, font, sym): - 'get charcode for sym' - basename = self.fontmap[font] - if latex_to_bakoma.has_key(sym): - basename, num = latex_to_bakoma[sym] - num = self.glyphmaps[basename][num] - elif len(sym) == 1: - num = ord(sym) - else: - num = 0 - return num - -class BakomaPSFonts(Fonts): +class BakomaPSFonts(BakomaFonts): """ Use the Bakoma postscript fonts for rendering to backend_ps """ - facenames = ('cmmi10', 'cmsy10', 'cmex10', - 'cmtt10', 'cmr10', 'cmb10', 'cmss10') - # allocate a new set of fonts - basepath = os.path.join( get_data_path(), 'fonts', 'ttf' ) - fontmap = { 'cal' : 'cmsy10', - 'rm' : 'cmr10', - 'tt' : 'cmtt10', - 'it' : 'cmmi10', - 'bf' : 'cmb10', - 'sf' : 'cmss10', - None : 'cmmi10', - } - - def __init__(self, character_tracker=None): - self.glyphd = {} - self.fonts = dict( - [ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) - for name in self.facenames]) - - self.glyphmaps = {} - for facename in self.facenames: - charmap = self.fonts[facename].get_charmap() - self.glyphmaps[facename] = dict([(glyphind, charcode) - for charcode, glyphind in charmap.items()]) - for font in self.fonts.values(): - font.clear() - self.character_tracker = character_tracker - - def _get_info (self, font, sym, fontsize, dpi): - 'load the cmfont, metrics and glyph with caching' - key = font, sym, fontsize, dpi - tup = self.glyphd.get(key) - - if tup is not None: - return tup - - basename = self.fontmap[font] - - if latex_to_bakoma.has_key(sym): - basename, num = latex_to_bakoma[sym] - sym = self.fonts[basename].get_glyph_name(num) - num = self.glyphmaps[basename][num] - elif len(sym) == 1: - num = ord(sym) - else: - num = 0 - #sym = '.notdef' - raise ValueError('unrecognized symbol "%s, %d"' % (sym, num)) - - cmfont = self.fonts[basename] - cmfont.set_size(fontsize, dpi) - head = cmfont.get_sfnt_table('head') - glyph = cmfont.load_char(num) - - if self.character_tracker: - self.character_tracker(cmfont, unichr(num)) - - xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox] - if basename == 'cmex10': - offset = -(head['yMin']+512)/head['unitsPerEm']*10. - else: - offset = 0. - metrics = Bunch( - advance = glyph.linearHoriAdvance/65536.0, - height = glyph.height/64.0, - width = glyph.width/64.0, - xmin = xmin, - xmax = xmax, - ymin = ymin+offset, - ymax = ymax+offset - ) - - self.glyphd[key] = basename, metrics, sym, offset - return basename, metrics, '/'+sym, offset - + def _get_offset(self, basename, font_cache, glyph, fontsize, dpi): + head = font_cache.font.get_sfnt_table("head") + if basename.lower() == 'cmex10': + return -(head['yMin']+512)/head['unitsPerEm']*10. + return 0. + def set_canvas_size(self, w, h, pswriter): 'Dimension the drawing canvas; may be a noop' self.width = w self.height = h self.pswriter = pswriter - def render(self, ox, oy, font, sym, fontsize, dpi): - fontname, metrics, glyphname, offset = \ + basename, font, metrics, symbol_name, num, glyph, offset = \ self._get_info(font, sym, fontsize, dpi) - fontname = fontname.capitalize() - if fontname == 'Cmex10': + if basename.lower() == 'cmex10': oy += offset - 512/2048.*10. - ps = """/%(fontname)s findfont + ps = """/%(basename)s findfont %(fontsize)s scalefont setfont %(ox)f %(oy)f moveto -/%(glyphname)s glyphshow +/%(symbol_name)s glyphshow """ % locals() self.pswriter.write(ps) - - def get_metrics(self, font, sym, fontsize, dpi): - basename, metrics, sym, offset = \ - self._get_info(font, sym, fontsize, dpi) - return metrics - class BakomaPDFFonts(BakomaPSFonts): """Hack of BakomaPSFonts for PDF support.""" - def _get_filename_and_num (self, font, sym, fontsize, dpi): - 'should be part of _get_info' - basename = self.fontmap[font] - - if latex_to_bakoma.has_key(sym): - basename, num = latex_to_bakoma[sym] - sym = self.fonts[basename].get_glyph_name(num) - num = self.glyphmaps[basename][num] - elif len(sym) == 1: - num = ord(sym) - else: - num = 0 - raise ValueError('unrecognized symbol "%s"' % (sym,)) - - return os.path.join(self.basepath, basename) + '.ttf', num - def render(self, ox, oy, font, sym, fontsize, dpi): - fontname, metrics, glyphname, offset = \ + basename, font, metrics, symbol_name, num, glyph, offset = \ self._get_info(font, sym, fontsize, dpi) - filename, num = self._get_filename_and_num(font, sym, fontsize, dpi) - if self.character_tracker: - self.character_tracker(filename, unichr(num)) - if fontname.lower() == 'cmex10': + filename = font.fname + if basename.lower() == 'cmex10': oy += offset - 512/2048.*10. self.pswriter.append((ox, oy, filename, fontsize, num)) @@ -1256,32 +1184,25 @@ def set_font(self, font): return - - # MGDTODO: The code below is probably now broken - #print 'set fonts' -# for i in range(len(self.elements)-1): -# if not isinstance(self.elements[i], SymbolElement): continue -# if not isinstance(self.elements[i+1], SymbolElement): continue -# symleft = self.elements[i].sym -# symright = self.elements[i+1].sym -# self.elements[i].kern = None -# #self.elements[i].kern = Element.fonts.get_kern(font, symleft, symright, self.fontsize, self.dpi) - def set_size_info(self, fontsize, dpi): - self.elements[0].set_size_info(self._scale*fontsize, dpi) + if len(self.elements): + self.elements[0].set_size_info(self._scale*fontsize, dpi) Element.set_size_info(self, fontsize, dpi) #print 'set size' def set_origin(self, ox, oy): - self.elements[0].set_origin(ox, oy) + if len(self.elements): + self.elements[0].set_origin(ox, oy) Element.set_origin(self, ox, oy) def advance(self): 'get the horiz advance' - return self.elements[-1].xmax() - self.elements[0].ox + if len(self.elements): + return self.elements[-1].xmax() - self.elements[0].ox + return 0 def height(self): @@ -1298,7 +1219,8 @@ def render(self): 'render to the fonts canvas' - self.elements[0].render() + if len(self.elements): + self.elements[0].render() Element.render(self) def xmin(self): @@ -1320,6 +1242,18 @@ def __repr__(self): return 'Group: [ %s ]' % ' '.join([str(e) for e in self.elements]) +class MathGroupElement(GroupElement): + def determine_font(self, font_stack): + font_stack.append('it') + for element in self.elements: + element.determine_font(font_stack) + font_stack.pop() + +class NonMathGroupElement(GroupElement): + def determine_font(self, font_stack): + for element in self.elements: + element.determine_font(font_stack) + class ExpressionElement(GroupElement): """ The entire mathtext expression @@ -1328,8 +1262,7 @@ def __repr__(self): return 'Expression: [ %s ]' % ' '.join([str(e) for e in self.elements]) - def determine_font(self): - font_stack = ['it'] + def determine_font(self, font_stack): GroupElement.determine_font(self, font_stack) class Handler: @@ -1337,12 +1270,24 @@ def clear(self): self.symbols = [] - self.subscript_stack = [] def expression(self, s, loc, toks): + #~ print "expr", toks self.expr = ExpressionElement(toks) return [self.expr] + def math(self, s, loc, toks): + #~ print "math", toks + math = MathGroupElement(toks) + return [math] + + def non_math(self, s, loc, toks): + #~ print "non_math", toks + symbols = [SymbolElement(c) for c in toks[0]] + self.symbols.extend(symbols) + non_math = NonMathGroupElement(symbols) + return [non_math] + def space(self, s, loc, toks): assert(len(toks)==1) @@ -1510,8 +1455,8 @@ latexfont = Forward().setParseAction(handler.latexfont).setName("latexfont") subsuper = Forward().setParseAction(handler.subsuperscript).setName("subsuper") placeable = Forward().setName("placeable") +expression = Forward().setParseAction(handler.expression).setName("expression") - lbrace = Literal('{').suppress() rbrace = Literal('}').suppress() lbrack = Literal('[') @@ -1599,6 +1544,7 @@ r"[:,.;!]", r"[!@%&]", r"[[\]()]", + r"\\\$" ]) + ")" ).setParseAction(handler.symbol).leaveWhitespace() @@ -1670,15 +1616,30 @@ | (( subscript | superscript) + placeable) ) -expression = OneOrMore( +math = OneOrMore( space | font | latexfont | subsuper - ).setParseAction(handler.expression).setName("expression") + ).setParseAction(handler.math).setName("math") - +math_delim =(~bslash + + Literal('$')) +non_math = Regex(r"(?:[^$]|(?:\\\$))*" + ).setParseAction(handler.non_math).setName("non_math").leaveWhitespace() + +expression <<( + non_math + + ZeroOrMore( + Suppress(math_delim) + + math + + Suppress(math_delim) + + non_math + ) + ) + + #### @@ -1700,18 +1661,18 @@ self.output = output self.cache = {} - def __call__(self, s, dpi, fontsize, angle=0, character_tracker=None): - cacheKey = (s, dpi, fontsize, angle) - s = s[1:-1] # strip the $ from front and back + def __call__(self, s, dpi, prop, angle=0): + cacheKey = (s, dpi, hash(prop), angle) if self.cache.has_key(cacheKey): - w, h, fontlike = self.cache[cacheKey] - return w, h, fontlike + w, h, fontlike, used_characters = self.cache[cacheKey] + return w, h, fontlike, used_characters + if self.output == 'SVG': - self.font_object = BakomaTrueTypeFonts(useSVG=True) + self.font_object = BakomaFonts(useSVG=True) #self.font_object = MyUnicodeFonts(output='SVG') Element.fonts = self.font_object elif self.output == 'Agg': - self.font_object = BakomaTrueTypeFonts() + self.font_object = BakomaFonts() #self.font_object = MyUnicodeFonts() Element.fonts = self.font_object elif self.output == 'PS': @@ -1719,17 +1680,22 @@ self.font_object = StandardPSFonts() Element.fonts = self.font_object else: - self.font_object = BakomaPSFonts(character_tracker) + self.font_object = BakomaPSFonts() #self.font_object = MyUnicodeFonts(output='PS') Element.fonts = self.font_object elif self.output == 'PDF': - self.font_object = BakomaPDFFonts(character_tracker) + self.font_object = BakomaPDFFonts() Element.fonts = self.font_object + + fontsize = prop.get_size_in_points() handler.clear() expression.parseString( s ) - - handler.expr.determine_font() + + fname = fontManager.findfont(prop) + default_font = FT2Font(str(fname)) + + handler.expr.determine_font([default_font]) handler.expr.set_size_info(fontsize, dpi) # set the origin once to allow w, h compution @@ -1738,7 +1704,7 @@ xmax = max([e.xmax() for e in handler.symbols]) ymin = min([e.ymin() for e in handler.symbols]) ymax = max([e.ymax() for e in handler.symbols]) - + # now set the true origin - doesn't affect with and height w, h = xmax-xmin, ymax-ymin # a small pad for the canvas size @@ -1758,20 +1724,18 @@ handler.expr.render() handler.clear() - + if self.output == 'SVG': # The empty list at the end is for lines svg_elements = Bunch(svg_glyphs=self.font_object.svg_glyphs, svg_lines=[]) - self.cache[cacheKey] = w, h, svg_elements - return w, h, svg_elements + self.cache[cacheKey] = w, h, svg_elements, Element.fonts.used_characters elif self.output == 'Agg': - self.cache[cacheKey] = w, h, self.font_object.fonts.values() - return w, h, self.font_object.fonts.values() + self.cache[cacheKey] = w, h, self.font_object.get_fonts(), Element.fonts.used_characters elif self.output in ('PS', 'PDF'): - self.cache[cacheKey] = w, h, pswriter - return w, h, pswriter - + self.cache[cacheKey] = w, h, pswriter, Element.fonts.used_characters + return self.cache[cacheKey] + if rcParams["mathtext.mathtext2"]: from matplotlib.mathtext2 import math_parse_s_ft2font from matplotlib.mathtext2 import math_parse_s_ft2font_svg Modified: branches/mathtext_mgd/lib/matplotlib/text.py =================================================================== --- branches/mathtext_mgd/lib/matplotlib/text.py 2007-07-18 07:38:05 UTC (rev 3556) +++ branches/mathtext_mgd/lib/matplotlib/text.py 2007-07-18 13:16:35 UTC (rev 3557) @@ -238,7 +238,7 @@ lines = [self._text] else: lines = self._text.split('\n') - + whs = [] # Find full vertical extent of font, # including ascenders and descenders: @@ -753,8 +753,8 @@ if rcParams['text.usetex']: return 'TeX' if not matplotlib._havemath: return False if len(self._text)<2: return False - return ( self._text.startswith('$') and - self._text.endswith('$') ) + dollar_signs = self._text.count('$') - self._text.count('\\$') + return dollar_signs > 0 and dollar_signs % 2 == 0 def set_fontproperties(self, fp): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |