Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c8baba5

Browse files
committed
Minor speed improvements from profiling. Fix kerning corruption issue when
"shrinking" characters. svn path=/trunk/matplotlib/; revision=3670
1 parent 996363d commit c8baba5

2 files changed

Lines changed: 63 additions & 52 deletions

File tree

examples/mathtext_examples.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
r'$100\%y\ x*y\ x/y x\$y$',
1010
r'$x\leftarrow y\ x\forall y\ x-y$',
1111
r'$x \sf x \bf x {\cal X} \rm x$',
12+
r'$x\ x\,x\;x\quad x\qquad x\!x$',
1213
r'$\{ \rm braces \}$',
1314
r'$\left[\left\lfloor\frac{5}{\frac{\left(3\right)}{4}} y\right)\right]$',
1415
r'$\left(x\right)$',
@@ -35,13 +36,29 @@
3536
r"$f'$",
3637
r'$\frac{x_2888}{y}$',
3738
r"$\sqrt[3]{\frac{X_2}{Y}}=5$",
39+
r"$\sqrt[5x\pi]{\prod^\frac{x}{2\pi^2}_\infty}$",
3840
r"$\sqrt[3]{x}=5$",
3941
r'$\frac{X}{\frac{X}{Y}}$',
42+
# From UTR #25
43+
r"$W^{3\beta}_{\delta_1 \rho_1 \sigma_2} = U^{3\beta}_{\delta_1 \rho_1} + \frac{1}{8 \pi 2} \int^{\alpha_2}_{\alpha_2} d \alpha^\prime_2 \left[\frac{ U^{2\beta}_{\delta_1 \rho_1} - \alpha^\prime_2U^{1\beta}_{\rho_1 \sigma_2} }{U^{0\beta}_{\rho_1 \sigma_2}}\right]$",
44+
r'$\mathcal{H} = \int d \tau (\epsilon E^2 + \mu H^2)$',
4045
r'$\widehat{abc}\widetilde{def}$'
4146
]
4247

4348
from pylab import *
4449

50+
def doall():
51+
for i, s in enumerate(stests):
52+
print "%02d: %s" % (i, s)
53+
plot([0,0,3], 'r')
54+
x = arange(0.0, 3.0, 0.1)
55+
56+
grid(True)
57+
text(0.1, 1.6, s, fontsize=20, markup="tex")
58+
59+
savefig('mathtext_example%02d' % i)
60+
figure()
61+
4562
if '--latex' in sys.argv:
4663
fd = open("mathtext_examples.ltx", "w")
4764
fd.write("\\documentclass{article}\n")
@@ -57,14 +74,4 @@
5774

5875
os.system("pdflatex mathtext_examples.ltx")
5976
else:
60-
for i, s in enumerate(stests):
61-
print "%02d: %s" % (i, s)
62-
plot([1,2,3], 'r')
63-
x = arange(0.0, 3.0, 0.1)
64-
65-
grid(True)
66-
text(1, 1.6, s, fontsize=20, markup="tex")
67-
68-
savefig('mathtext_example%02d' % i)
69-
figure()
70-
77+
doall()

lib/matplotlib/mathtext.py

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@
135135
from sets import Set
136136
from unicodedata import category
137137
from warnings import warn
138-
import numpy
138+
139+
from numpy import inf, isinf
139140

140141
from matplotlib import verbose
141142
from matplotlib.pyparsing import Literal, Word, OneOrMore, ZeroOrMore, \
@@ -554,7 +555,7 @@ class BakomaFonts(TruetypeFonts):
554555

555556
def _get_offset(self, cached_font, glyph, fontsize, dpi):
556557
if cached_font.font.postscript_name == 'Cmex10':
557-
return glyph.height/64.0/2 + 256.0/64.0 * dpi/72.0
558+
return glyph.height/64.0/2.0 + 256.0/64.0 * dpi/72.0
558559
return 0.
559560

560561
def _get_glyph(self, fontname, sym, fontsize):
@@ -654,7 +655,7 @@ def _get_glyph(self, fontname, sym, fontsize):
654655
# This is a total hack, but it works for now
655656
if sym.startswith('\\big'):
656657
uniindex = get_unicode_index(sym[4:])
657-
fontsize *= INV_SHRINK_FACTOR
658+
fontsize *= GROW_FACTOR
658659
else:
659660
warn("No TeX to unicode mapping for '%s'" % sym,
660661
MathTextWarning)
@@ -848,7 +849,7 @@ def get_underline_thickness(self, font, fontsize, dpi):
848849

849850
# How much text shrinks when going to the next-smallest level
850851
SHRINK_FACTOR = 0.7
851-
INV_SHRINK_FACTOR = 1.0 / SHRINK_FACTOR
852+
GROW_FACTOR = 1.0 / SHRINK_FACTOR
852853
# The number of different sizes of chars to use, beyond which they will not
853854
# get any smaller
854855
NUM_SIZE_LEVELS = 4
@@ -900,28 +901,22 @@ class Box(Node):
900901
@135"""
901902
def __init__(self, width, height, depth):
902903
Node.__init__(self)
903-
self.width = width
904-
self.height = height
905-
self.depth = depth
904+
self.width = width
905+
self.height = height
906+
self.depth = depth
906907

907908
def shrink(self):
908909
Node.shrink(self)
909910
if self.size < NUM_SIZE_LEVELS:
910-
if self.width is not None:
911-
self.width *= SHRINK_FACTOR
912-
if self.height is not None:
913-
self.height *= SHRINK_FACTOR
914-
if self.depth is not None:
915-
self.depth *= SHRINK_FACTOR
911+
self.width *= SHRINK_FACTOR
912+
self.height *= SHRINK_FACTOR
913+
self.depth *= SHRINK_FACTOR
916914

917915
def grow(self):
918916
Node.grow(self)
919-
if self.width is not None:
920-
self.width *= INV_SHRINK_FACTOR
921-
if self.height is not None:
922-
self.height *= INV_SHRINK_FACTOR
923-
if self.depth is not None:
924-
self.depth *= INV_SHRINK_FACTOR
917+
self.width *= GROW_FACTOR
918+
self.height *= GROW_FACTOR
919+
self.depth *= GROW_FACTOR
925920

926921
def render(self, x1, y1, x2, y2):
927922
pass
@@ -992,12 +987,16 @@ def shrink(self):
992987
Node.shrink(self)
993988
if self.size < NUM_SIZE_LEVELS:
994989
self.fontsize *= SHRINK_FACTOR
995-
self._update_metrics()
990+
self.width *= SHRINK_FACTOR
991+
self.height *= SHRINK_FACTOR
992+
self.depth *= SHRINK_FACTOR
996993

997994
def grow(self):
998995
Node.grow(self)
999-
self.fontsize *= INV_SHRINK_FACTOR
1000-
self._update_metrics()
996+
self.fontsize *= GROW_FACTOR
997+
self.width *= GROW_FACTOR
998+
self.height *= GROW_FACTOR
999+
self.depth *= GROW_FACTOR
10011000

10021001
class Accent(Char):
10031002
"""The font metrics need to be dealt with differently for accents, since they
@@ -1028,10 +1027,11 @@ def __init__(self, elements):
10281027
self.glue_order = 0 # The order of infinity (0 - 3) for the glue
10291028

10301029
def __repr__(self):
1031-
return '[%s <%d %d %d %d> %s]' % (self.__internal_repr__(),
1032-
self.width, self.height,
1033-
self.depth, self.shift_amount,
1034-
' '.join([repr(x) for x in self.children]))
1030+
return '[%s <%.02f %.02f %.02f %.02f> %s]' % (
1031+
self.__internal_repr__(),
1032+
self.width, self.height,
1033+
self.depth, self.shift_amount,
1034+
' '.join([repr(x) for x in self.children]))
10351035

10361036
def _determine_order(self, totals):
10371037
"""A helper function to determine the highest order of glue
@@ -1069,8 +1069,8 @@ def grow(self):
10691069
for child in self.children:
10701070
child.grow()
10711071
Box.grow(self)
1072-
self.shift_amount *= INV_SHRINK_FACTOR
1073-
self.glue_set *= INV_SHRINK_FACTOR
1072+
self.shift_amount *= GROW_FACTOR
1073+
self.glue_set *= GROW_FACTOR
10741074

10751075
class Hlist(List):
10761076
"""A horizontal list of boxes.
@@ -1131,7 +1131,7 @@ def hpack(self, w=0., m='additional'):
11311131
d = max(d, p.depth)
11321132
elif isinstance(p, Box):
11331133
x += p.width
1134-
if p.height is not None and p.depth is not None:
1134+
if not isinf(p.height) and not isinf(p.depth):
11351135
s = getattr(p, 'shift_amount', 0.)
11361136
h = max(h, p.height - s)
11371137
d = max(d, p.depth + s)
@@ -1167,7 +1167,7 @@ def __init__(self, elements, h=0., m='additional'):
11671167
List.__init__(self, elements)
11681168
self.vpack()
11691169

1170-
def vpack(self, h=0., m='additional', l=float(numpy.inf)):
1170+
def vpack(self, h=0., m='additional', l=float(inf)):
11711171
"""The main duty of vpack is to compute the dimensions of the
11721172
resulting boxes, and to adjust the glue if one of those dimensions is
11731173
pre-specified.
@@ -1192,7 +1192,7 @@ def vpack(self, h=0., m='additional', l=float(numpy.inf)):
11921192
if isinstance(p, Box):
11931193
x += d + p.height
11941194
d = p.depth
1195-
if p.width is not None:
1195+
if not isinf(p.width):
11961196
s = getattr(p, 'shift_amount', 0.)
11971197
w = max(w, p.width + s)
11981198
elif isinstance(p, Glue):
@@ -1234,7 +1234,7 @@ def vpack(self, h=0., m='additional', l=float(numpy.inf)):
12341234
class Rule(Box):
12351235
"""A Rule node stands for a solid black rectangle; it has width,
12361236
depth, and height fields just as in an Hlist. However, if any of these
1237-
dimensions is None, the actual value will be determined by running the
1237+
dimensions is inf, the actual value will be determined by running the
12381238
rule up to the boundary of the innermost enclosing box. This is called
12391239
a "running dimension." The width is never running in an Hlist; the
12401240
height and depth are never running in a Vlist.
@@ -1252,14 +1252,14 @@ def __init__(self, state):
12521252
thickness = state.font_output.get_underline_thickness(
12531253
state.font, state.fontsize, state.dpi)
12541254
height = depth = thickness * 0.5
1255-
Rule.__init__(self, None, height, depth, state)
1255+
Rule.__init__(self, inf, height, depth, state)
12561256

12571257
class Vrule(Rule):
12581258
"""Convenience class to create a vertical rule."""
12591259
def __init__(self, state):
12601260
thickness = state.font_output.get_underline_thickness(
12611261
state.font, state.fontsize, state.dpi)
1262-
Rule.__init__(self, thickness, None, None, state)
1262+
Rule.__init__(self, thickness, inf, inf, state)
12631263

12641264
class Glue(Node):
12651265
"""Most of the information in this object is stored in the underlying
@@ -1291,7 +1291,7 @@ def grow(self):
12911291
Node.grow(self)
12921292
if self.glue_spec.width != 0.:
12931293
self.glue_spec = self.glue_spec.copy()
1294-
self.glue_spec.width *= INV_SHRINK_FACTOR
1294+
self.glue_spec.width *= GROW_FACTOR
12951295

12961296
class GlueSpec(object):
12971297
"""@150, @151"""
@@ -1379,14 +1379,17 @@ def __init__(self, width):
13791379
Node.__init__(self)
13801380
self.width = width
13811381

1382+
def __repr__(self):
1383+
return "k%.02f" % self.width
1384+
13821385
def shrink(self):
13831386
Node.shrink(self)
13841387
if self.size < NUM_SIZE_LEVELS:
13851388
self.width *= SHRINK_FACTOR
13861389

13871390
def grow(self):
13881391
Node.grow(self)
1389-
self.width *= INV_SHRINK_FACTOR
1392+
self.width *= GROW_FACTOR
13901393

13911394
class SubSuperCluster(Hlist):
13921395
"""This class is a sort of hack to get around that fact that this
@@ -1507,9 +1510,9 @@ def hlist_out(self, box):
15071510
rule_height = p.height
15081511
rule_depth = p.depth
15091512
rule_width = p.width
1510-
if rule_height is None:
1513+
if isinf(rule_height):
15111514
rule_height = box.height
1512-
if rule_depth is None:
1515+
if isinf(rule_depth):
15131516
rule_depth = box.depth
15141517
if rule_height > 0 and rule_width > 0:
15151518
self.cur_v = baseline + rule_depth
@@ -1566,7 +1569,7 @@ def vlist_out(self, box):
15661569
rule_height = p.height
15671570
rule_depth = p.depth
15681571
rule_width = p.width
1569-
if rule_width is None:
1572+
if isinf(rule_width):
15701573
rule_width = box.width
15711574
rule_height += rule_depth
15721575
if rule_height > 0 and rule_depth > 0:
@@ -1822,7 +1825,7 @@ def __init__(self):
18221825

18231826
self._expression <<(
18241827
non_math
1825-
+ OneOrMore(
1828+
+ ZeroOrMore(
18261829
Suppress(math_delim)
18271830
+ math
18281831
+ Suppress(math_delim)
@@ -2178,7 +2181,8 @@ def sqrt(self, s, loc, toks):
21782181
else:
21792182
if not isinstance(root, ParseResults):
21802183
raise ParseFatalException(
2181-
"Can not parse root of radical. Only simple symbols are allowed.")
2184+
"Can not parse root of radical. "
2185+
"Only simple symbols are allowed in the root.")
21822186
root = Hlist(root.asList())
21832187
root.shrink()
21842188
root.shrink()

0 commit comments

Comments
 (0)