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

Skip to content

Commit dd567a6

Browse files
committed
Turn _mathtext.ship into a plain function.
Making it a plain function with two nested mutually recursive functions, instead of a singleton object with methods, makes ship() thread-safe at no cost (otherwise, two threads calling ship() at the same time would overwrite each other's instance variables).
1 parent 0d0799b commit dd567a6

File tree

1 file changed

+56
-60
lines changed

1 file changed

+56
-60
lines changed

lib/matplotlib/_mathtext.py

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,8 @@ def get_underline_thickness(self, font, fontsize, dpi):
911911
#
912912
# The most relevant "chapters" are:
913913
# Data structures for boxes and their friends
914-
# Shipping pages out (Ship class)
915-
# Packaging (hpack and vpack)
914+
# Shipping pages out (ship())
915+
# Packaging (hpack() and vpack())
916916
# Data structures for math mode
917917
# Subroutines for math mode
918918
# Typesetting math formulas
@@ -1690,65 +1690,63 @@ def __init__(self, c, width, state, always=False, char_class=Char):
16901690
self.width = char.width
16911691

16921692

1693-
class Ship:
1693+
def ship(ox, oy, box):
16941694
"""
16951695
Ship boxes to output once they have been set up, this sends them to output.
16961696
1697-
Since boxes can be inside of boxes inside of boxes, the main work of `Ship`
1697+
Since boxes can be inside of boxes inside of boxes, the main work of `ship`
16981698
is done by two mutually recursive routines, `hlist_out` and `vlist_out`,
16991699
which traverse the `Hlist` nodes and `Vlist` nodes inside of horizontal
17001700
and vertical boxes. The global variables used in TeX to store state as it
1701-
processes have become member variables here.
1701+
processes have become local variables here.
17021702
"""
17031703

1704-
def __call__(self, ox, oy, box):
1705-
self.max_push = 0 # Deepest nesting of push commands so far
1706-
self.cur_s = 0
1707-
self.cur_v = 0.
1708-
self.cur_h = 0.
1709-
self.off_h = ox
1710-
self.off_v = oy + box.height
1711-
self.hlist_out(box)
1704+
max_push = 0 # Deepest nesting of push commands so far
1705+
cur_s = 0
1706+
cur_v = 0.
1707+
cur_h = 0.
1708+
off_h = ox
1709+
off_v = oy + box.height
17121710

1713-
@staticmethod
17141711
def clamp(value):
17151712
if value < -1000000000.:
17161713
return -1000000000.
17171714
if value > 1000000000.:
17181715
return 1000000000.
17191716
return value
17201717

1721-
def hlist_out(self, box):
1718+
def hlist_out(box):
1719+
nonlocal max_push, cur_s, cur_v, cur_h, off_h, off_v
1720+
17221721
cur_g = 0
17231722
cur_glue = 0.
17241723
glue_order = box.glue_order
17251724
glue_sign = box.glue_sign
1726-
base_line = self.cur_v
1727-
left_edge = self.cur_h
1728-
self.cur_s += 1
1729-
self.max_push = max(self.cur_s, self.max_push)
1730-
clamp = self.clamp
1725+
base_line = cur_v
1726+
left_edge = cur_h
1727+
cur_s += 1
1728+
max_push = max(cur_s, max_push)
17311729

17321730
for p in box.children:
17331731
if isinstance(p, Char):
1734-
p.render(self.cur_h + self.off_h, self.cur_v + self.off_v)
1735-
self.cur_h += p.width
1732+
p.render(cur_h + off_h, cur_v + off_v)
1733+
cur_h += p.width
17361734
elif isinstance(p, Kern):
1737-
self.cur_h += p.width
1735+
cur_h += p.width
17381736
elif isinstance(p, List):
17391737
# node623
17401738
if len(p.children) == 0:
1741-
self.cur_h += p.width
1739+
cur_h += p.width
17421740
else:
1743-
edge = self.cur_h
1744-
self.cur_v = base_line + p.shift_amount
1741+
edge = cur_h
1742+
cur_v = base_line + p.shift_amount
17451743
if isinstance(p, Hlist):
1746-
self.hlist_out(p)
1744+
hlist_out(p)
17471745
else:
17481746
# p.vpack(box.height + box.depth, 'exactly')
1749-
self.vlist_out(p)
1750-
self.cur_h = edge + p.width
1751-
self.cur_v = base_line
1747+
vlist_out(p)
1748+
cur_h = edge + p.width
1749+
cur_v = base_line
17521750
elif isinstance(p, Box):
17531751
# node624
17541752
rule_height = p.height
@@ -1759,12 +1757,11 @@ def hlist_out(self, box):
17591757
if np.isinf(rule_depth):
17601758
rule_depth = box.depth
17611759
if rule_height > 0 and rule_width > 0:
1762-
self.cur_v = base_line + rule_depth
1763-
p.render(self.cur_h + self.off_h,
1764-
self.cur_v + self.off_v,
1760+
cur_v = base_line + rule_depth
1761+
p.render(cur_h + off_h, cur_v + off_v,
17651762
rule_width, rule_height)
1766-
self.cur_v = base_line
1767-
self.cur_h += rule_width
1763+
cur_v = base_line
1764+
cur_h += rule_width
17681765
elif isinstance(p, Glue):
17691766
# node625
17701767
glue_spec = p.glue_spec
@@ -1778,38 +1775,39 @@ def hlist_out(self, box):
17781775
cur_glue += glue_spec.shrink
17791776
cur_g = round(clamp(box.glue_set * cur_glue))
17801777
rule_width += cur_g
1781-
self.cur_h += rule_width
1782-
self.cur_s -= 1
1778+
cur_h += rule_width
1779+
cur_s -= 1
1780+
1781+
def vlist_out(box):
1782+
nonlocal max_push, cur_s, cur_v, cur_h, off_h, off_v
17831783

1784-
def vlist_out(self, box):
17851784
cur_g = 0
17861785
cur_glue = 0.
17871786
glue_order = box.glue_order
17881787
glue_sign = box.glue_sign
1789-
self.cur_s += 1
1790-
self.max_push = max(self.max_push, self.cur_s)
1791-
left_edge = self.cur_h
1792-
self.cur_v -= box.height
1793-
top_edge = self.cur_v
1794-
clamp = self.clamp
1788+
cur_s += 1
1789+
max_push = max(max_push, cur_s)
1790+
left_edge = cur_h
1791+
cur_v -= box.height
1792+
top_edge = cur_v
17951793

17961794
for p in box.children:
17971795
if isinstance(p, Kern):
1798-
self.cur_v += p.width
1796+
cur_v += p.width
17991797
elif isinstance(p, List):
18001798
if len(p.children) == 0:
1801-
self.cur_v += p.height + p.depth
1799+
cur_v += p.height + p.depth
18021800
else:
1803-
self.cur_v += p.height
1804-
self.cur_h = left_edge + p.shift_amount
1805-
save_v = self.cur_v
1801+
cur_v += p.height
1802+
cur_h = left_edge + p.shift_amount
1803+
save_v = cur_v
18061804
p.width = box.width
18071805
if isinstance(p, Hlist):
1808-
self.hlist_out(p)
1806+
hlist_out(p)
18091807
else:
1810-
self.vlist_out(p)
1811-
self.cur_v = save_v + p.depth
1812-
self.cur_h = left_edge
1808+
vlist_out(p)
1809+
cur_v = save_v + p.depth
1810+
cur_h = left_edge
18131811
elif isinstance(p, Box):
18141812
rule_height = p.height
18151813
rule_depth = p.depth
@@ -1818,9 +1816,8 @@ def vlist_out(self, box):
18181816
rule_width = box.width
18191817
rule_height += rule_depth
18201818
if rule_height > 0 and rule_depth > 0:
1821-
self.cur_v += rule_height
1822-
p.render(self.cur_h + self.off_h,
1823-
self.cur_v + self.off_v,
1819+
cur_v += rule_height
1820+
p.render(cur_h + off_h, cur_v + off_v,
18241821
rule_width, rule_height)
18251822
elif isinstance(p, Glue):
18261823
glue_spec = p.glue_spec
@@ -1834,14 +1831,13 @@ def vlist_out(self, box):
18341831
cur_glue += glue_spec.shrink
18351832
cur_g = round(clamp(box.glue_set * cur_glue))
18361833
rule_height += cur_g
1837-
self.cur_v += rule_height
1834+
cur_v += rule_height
18381835
elif isinstance(p, Char):
18391836
raise RuntimeError(
18401837
"Internal mathtext error: Char node found in vlist")
1841-
self.cur_s -= 1
1842-
1838+
cur_s -= 1
18431839

1844-
ship = Ship()
1840+
hlist_out(box)
18451841

18461842

18471843
##############################################################################

0 commit comments

Comments
 (0)