Skip to content

Commit f587ea4

Browse files
committed
Prevent the mathtext cache from getting out of hand, by clearing it
after every plot. svn path=/trunk/matplotlib/; revision=3722
1 parent 9dc973d commit f587ea4

10 files changed

Lines changed: 48 additions & 46 deletions

File tree

‎lib/matplotlib/backends/backend_agg.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
from matplotlib.figure import Figure
8484
from matplotlib.font_manager import findfont
8585
from matplotlib.ft2font import FT2Font, LOAD_DEFAULT
86-
from matplotlib.mathtext import math_parse_s_ft2font
86+
from matplotlib.mathtext import MathTextParser
8787
from matplotlib.transforms import lbwh_to_bbox
8888

8989
from _backend_agg import RendererAgg as _RendererAgg
@@ -125,7 +125,7 @@ def __init__(self, width, height, dpi):
125125

126126
self.copy_from_bbox = self._renderer.copy_from_bbox
127127
self.restore_region = self._renderer.restore_region
128-
128+
self.mathtext_parser = MathTextParser('Agg')
129129

130130
self.bbox = lbwh_to_bbox(0,0, self.width, self.height)
131131
if __debug__: verbose.report('RendererAgg.__init__ done',
@@ -173,7 +173,7 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
173173
"""
174174
if __debug__: verbose.report('RendererAgg.draw_mathtext',
175175
'debug-annoying')
176-
width, height, fonts, used_characters = math_parse_s_ft2font(
176+
width, height, fonts, used_characters = self.mathtext_parser.parse(
177177
s, self.dpi.get(), prop)
178178

179179
if angle == 90:
@@ -230,7 +230,7 @@ def get_text_width_height(self, s, prop, ismath, rgb=(0,0,0)):
230230
return n,m
231231

232232
if ismath:
233-
width, height, fonts, used_characters = math_parse_s_ft2font(
233+
width, height, fonts, used_characters = self.mathtext_parser.parse(
234234
s, self.dpi.get(), prop)
235235
return width, height
236236
font = self._get_agg_font(prop)

‎lib/matplotlib/backends/backend_agg2.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from matplotlib.cbook import enumerate, is_string_like, exception_to_str
1717
from matplotlib.figure import Figure
1818
from matplotlib.ft2font import FT2Font
19-
from matplotlib.mathtext import math_parse_s_ft2font
19+
from matplotlib.mathtext import MathTextParser
2020

2121

2222
from _backend_agg import RendererAgg as _RendererAgg

‎lib/matplotlib/backends/backend_cairo.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def _fn_name(): return sys._getframe(1).f_code.co_name
3838
FigureManagerBase, FigureCanvasBase
3939
from matplotlib.cbook import enumerate, izip
4040
from matplotlib.figure import Figure
41-
from matplotlib.mathtext import math_parse_s_cairo
41+
from matplotlib.mathtext import MathTextParser
4242
from matplotlib.transforms import Bbox
4343
from matplotlib.font_manager import ttfFontProperty
4444
from matplotlib import rcParams
@@ -92,7 +92,7 @@ def __init__(self, dpi):
9292
self.dpi = dpi
9393
self.text_ctx = cairo.Context (
9494
cairo.ImageSurface (cairo.FORMAT_ARGB32,1,1))
95-
95+
self.mathtext_parser = MathTextParser('Cairo')
9696

9797
def set_ctx_from_surface (self, surface):
9898
self.ctx = cairo.Context (surface)
@@ -304,7 +304,7 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):
304304
if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name())
305305

306306
ctx = gc.ctx
307-
width, height, glyphs, rects = math_parse_s_cairo(
307+
width, height, glyphs, rects = self.mathtext_parser.parse(
308308
s, self.dpi.get(), prop)
309309

310310
ctx.save()
@@ -352,7 +352,7 @@ def get_canvas_width_height(self):
352352
def get_text_width_height(self, s, prop, ismath):
353353
if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name())
354354
if ismath:
355-
width, height, fonts, used_characters = math_parse_s_cairo(
355+
width, height, fonts, used_characters = self.mathtext_parser.parse(
356356
s, self.dpi.get(), prop)
357357
return width, height
358358

‎lib/matplotlib/backends/backend_gdk.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def fn_name(): return sys._getframe(1).f_code.co_name
2424
FigureManagerBase, FigureCanvasBase
2525
from matplotlib.cbook import is_string_like, enumerate
2626
from matplotlib.figure import Figure
27-
from matplotlib.mathtext import math_parse_s_ft2font
27+
from matplotlib.mathtext import MathTextParser
2828

2929
from matplotlib.backends._backend_gdk import pixbuf_get_pixels_array
3030

@@ -71,6 +71,7 @@ def __init__(self, gtkDA, dpi):
7171
self.gtkDA = gtkDA
7272
self.dpi = dpi
7373
self._cmap = gtkDA.get_colormap()
74+
self.mathtext_parser = MathTextParser("Agg")
7475

7576
def set_pixmap (self, pixmap):
7677
self.gdkDrawable = pixmap
@@ -198,7 +199,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath):
198199

199200

200201
def _draw_mathtext(self, gc, x, y, s, prop, angle):
201-
width, height, fonts, used_characters = math_parse_s_ft2font(
202+
width, height, fonts, used_characters = self.mathtext_parser.parse(
202203
s, self.dpi.get(), prop)
203204

204205
if angle==90:
@@ -341,7 +342,7 @@ def get_canvas_width_height(self):
341342

342343
def get_text_width_height(self, s, prop, ismath):
343344
if ismath:
344-
width, height, fonts, used_characters = math_parse_s_ft2font(
345+
width, height, fonts, used_characters = self.mathtext_parser.parse(
345346
s, self.dpi.get(), prop)
346347
return width, height
347348

‎lib/matplotlib/backends/backend_pdf.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from matplotlib.dviread import Dvi
3030
from matplotlib.ft2font import FT2Font, FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, \
3131
LOAD_NO_HINTING, KERNING_UNFITTED
32-
from matplotlib.mathtext import math_parse_s_pdf
32+
from matplotlib.mathtext import MathTextParser
3333
from matplotlib.transforms import Bbox
3434
from matplotlib import ttconv
3535

@@ -1032,6 +1032,7 @@ def __init__(self, file):
10321032
self.encode_string = self.encode_string_type3
10331033
else:
10341034
self.encode_string = self.encode_string_type42
1035+
self.mathtext_parser = MathTextParser("Pdf")
10351036

10361037
def finalize(self):
10371038
self.gc.finalize()
@@ -1219,7 +1220,7 @@ def _setup_textpos(self, x, y, angle, oldx=0, oldy=0, oldangle=0):
12191220
def draw_mathtext(self, gc, x, y, s, prop, angle):
12201221
# TODO: fix positioning and encoding
12211222
width, height, glyphs, rects, used_characters = \
1222-
math_parse_s_pdf(s, 72, prop)
1223+
self.mathtext_parser.parse(s, 72, prop)
12231224
self.merge_used_characters(used_characters)
12241225

12251226
# When using Type 3 fonts, we can't use character codes higher
@@ -1466,7 +1467,7 @@ def get_text_width_height(self, s, prop, ismath):
14661467

14671468
if ismath:
14681469
w, h, glyphs, rects, used_characters = \
1469-
math_parse_s_pdf(s, 72, prop)
1470+
self.mathtext_parser.parse(s, 72, prop)
14701471

14711472
elif rcParams['pdf.use14corefonts']:
14721473
font = self._get_font_afm(prop)

‎lib/matplotlib/backends/backend_ps.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def _fn_name(): return sys._getframe(1).f_code.co_name
2121
from matplotlib.font_manager import findfont
2222
from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING
2323
from matplotlib.ttconv import convert_ttf_to_ps
24-
from matplotlib.mathtext import math_parse_s_ps
24+
from matplotlib.mathtext import MathTextParser
2525
from matplotlib.text import Text
2626

2727
from matplotlib.transforms import get_vec6_scales
@@ -144,6 +144,7 @@ def __init__(self, width, height, pswriter, dpi=72):
144144
self.fontd = {}
145145
self.afmfontd = {}
146146
self.used_characters = {}
147+
self.mathtext_parser = MathTextParser("PS")
147148

148149
def track_characters(self, font, s):
149150
"""Keeps track of which characters are required from
@@ -277,8 +278,8 @@ def get_text_width_height(self, s, prop, ismath):
277278
return w, h
278279

279280
if ismath:
280-
width, height, pswriter, used_characters = math_parse_s_ps(
281-
s, 72, prop)
281+
width, height, pswriter, used_characters = \
282+
self.mathtext_parser.parse(s, 72, prop)
282283
return width, height
283284

284285
if rcParams['ps.useafm']:
@@ -814,7 +815,7 @@ def draw_mathtext(self, gc,
814815
self._pswriter.write("% mathtext\n")
815816

816817
width, height, pswriter, used_characters = \
817-
math_parse_s_ps(s, 72, prop)
818+
self.mathtext_parser.parse(s, 72, prop)
818819
self.merge_used_characters(used_characters)
819820
self.set_color(*gc.get_rgb())
820821
thetext = pswriter.getvalue()

‎lib/matplotlib/backends/backend_qt.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors
1111
from matplotlib._pylab_helpers import Gcf
1212
from matplotlib.figure import Figure
13-
from matplotlib.mathtext import math_parse_s_ft2font
13+
from matplotlib.mathtext import MathTextParser
1414
from matplotlib.widgets import SubplotTool
1515

1616
import qt

‎lib/matplotlib/backends/backend_qt4.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors
1111
from matplotlib._pylab_helpers import Gcf
1212
from matplotlib.figure import Figure
13-
from matplotlib.mathtext import math_parse_s_ft2font
13+
from matplotlib.mathtext import MathTextParser
1414
from matplotlib.widgets import SubplotTool
1515

1616
from PyQt4 import QtCore, QtGui

‎lib/matplotlib/backends/backend_svg.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from matplotlib.figure import Figure
1010
from matplotlib.font_manager import findfont, FontProperties
1111
from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING
12-
from matplotlib.mathtext import math_parse_s_ft2font_svg
12+
from matplotlib.mathtext import MathTextParser
1313

1414
from xml.sax.saxutils import escape as escape_xml_text
1515

@@ -40,6 +40,7 @@ def __init__(self, width, height, svgwriter, basename=None):
4040
self._imaged = {}
4141
self._clipd = {}
4242
self._char_defs = {}
43+
self.mathtext_parser = MathTextParser('SVG')
4344
svgwriter.write(svgProlog%(width,height,width,height))
4445

4546
def _draw_svg_element(self, element, details, gc, rgbFace):
@@ -338,7 +339,7 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):
338339
Draw math text using matplotlib.mathtext
339340
"""
340341
width, height, svg_elements, used_characters = \
341-
math_parse_s_ft2font_svg(s, 72, prop)
342+
self.mathtext_parser.parse(s, 72, prop)
342343
svg_glyphs = svg_elements.svg_glyphs
343344
svg_rects = svg_elements.svg_rects
344345
color = rgb2hex(gc.get_rgb())
@@ -428,7 +429,7 @@ def get_canvas_width_height(self):
428429
def get_text_width_height(self, s, prop, ismath):
429430
if ismath:
430431
width, height, trash, used_characters = \
431-
math_parse_s_ft2font_svg(s, 72, prop)
432+
self.mathtext_parser.parse(s, 72, prop)
432433
return width, height
433434
font = self._get_font(prop)
434435
font.set_text(s, 0.0, flags=LOAD_NO_HINTING)

‎lib/matplotlib/mathtext.py‎

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ def _get_info (self, fontname, sym, fontsize, dpi, mark_as_used=True):
532532
slanted = slanted
533533
)
534534

535-
self.glyphd[key] = Bunch(
535+
result = self.glyphd[key] = Bunch(
536536
font = font,
537537
fontsize = fontsize,
538538
postscript_name = font.postscript_name,
@@ -542,7 +542,7 @@ def _get_info (self, fontname, sym, fontsize, dpi, mark_as_used=True):
542542
glyph = glyph,
543543
offset = offset
544544
)
545-
return self.glyphd[key]
545+
return result
546546

547547
def get_xheight(self, font, fontsize, dpi):
548548
cached_font = self._get_font(font)
@@ -2343,7 +2343,7 @@ def auto_sized_delimiter(self, s, loc, toks):
23432343
##############################################################################
23442344
# MAIN
23452345

2346-
class math_parse_s_ft2font_common:
2346+
class MathTextParser:
23472347
"""
23482348
Parse the math expression s, return the (bbox, fonts) tuple needed
23492349
to render it.
@@ -2352,40 +2352,38 @@ class math_parse_s_ft2font_common:
23522352
23532353
return is width, height, fonts
23542354
"""
2355-
major, minor1, minor2, tmp, tmp = sys.version_info
2356-
if major==2 and minor1==2:
2357-
raise SystemExit('mathtext broken on python2.2. We hope to get this fixed soon')
2358-
23592355
_parser = None
2360-
2356+
23612357
_backend_mapping = {
23622358
'Agg' : MathtextBackendAgg,
23632359
'PS' : MathtextBackendPs,
2364-
'PDF' : MathtextBackendPdf,
2360+
'Pdf' : MathtextBackendPdf,
23652361
'SVG' : MathtextBackendSvg,
23662362
'Cairo' : MathtextBackendCairo
23672363
}
23682364

23692365
def __init__(self, output):
2370-
self.output = output
2371-
self.cache = {}
2366+
self._output = output
2367+
self._cache = {}
23722368

2373-
def __call__(self, s, dpi, prop):
2369+
def parse(self, s, dpi, prop):
23742370
cacheKey = (s, dpi, hash(prop))
2375-
if self.cache.has_key(cacheKey):
2376-
result = self.cache[cacheKey]
2371+
result = self._cache.get(cacheKey)
2372+
if result is not None:
23772373
return result
23782374

2379-
if self.output == 'PS' and rcParams['ps.useafm']:
2375+
if self._output == 'PS' and rcParams['ps.useafm']:
23802376
font_output = StandardPsFonts(prop)
23812377
else:
2382-
backend = self._backend_mapping[self.output]()
2378+
backend = self._backend_mapping[self._output]()
23832379
if rcParams['mathtext.use_cm']:
23842380
font_output = BakomaFonts(prop, backend)
23852381
else:
23862382
font_output = UnicodeFonts(prop, backend)
23872383

23882384
fontsize = prop.get_size_in_points()
2385+
# This is a class variable so we don't rebuild the parser
2386+
# with each request.
23892387
if self._parser is None:
23902388
self.__class__._parser = Parser()
23912389
box = self._parser.parse(s, font_output, fontsize, dpi)
@@ -2395,16 +2393,16 @@ def __call__(self, s, dpi, prop):
23952393
font_output.set_canvas_size(w, h)
23962394
ship(2, 2, box)
23972395
result = font_output.get_results()
2398-
self.cache[cacheKey] = result
2396+
self._cache[cacheKey] = result
23992397
# Free up the transient data structures
24002398
self._parser.clear()
24012399
# Remove a cyclical reference
24022400
font_output.mathtext_backend.fonts_object = None
24032401

24042402
return result
24052403

2406-
math_parse_s_ft2font = math_parse_s_ft2font_common('Agg')
2407-
math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG')
2408-
math_parse_s_ps = math_parse_s_ft2font_common('PS')
2409-
math_parse_s_pdf = math_parse_s_ft2font_common('PDF')
2410-
math_parse_s_cairo = math_parse_s_ft2font_common('Cairo')
2404+
# math_parse_s_ft2font = math_parse_s_ft2font_common('Agg')
2405+
# math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG')
2406+
# math_parse_s_ps = math_parse_s_ft2font_common('PS')
2407+
# math_parse_s_pdf = math_parse_s_ft2font_common('PDF')
2408+
# math_parse_s_cairo = math_parse_s_ft2font_common('Cairo')

0 commit comments

Comments
 (0)