MCPcopy Index your code
hub / github.com/matplotlib/matplotlib / _get_text_metrics_function

Function _get_text_metrics_function

lib/matplotlib/text.py:62–131  ·  view source on GitHub ↗

Helper function to provide a two-layered cache for font metrics To get the rendered size of a size of string we need to know: - what renderer we are using - the current dpi of the renderer - the string - the font properties - is it math text or not We do

(input_renderer, _cache=weakref.WeakKeyDictionary())

Source from the content-addressed store, hash-verified

60
61
62def _get_text_metrics_function(input_renderer, _cache=weakref.WeakKeyDictionary()):
63 """
64 Helper function to provide a two-layered cache for font metrics
65
66
67 To get the rendered size of a size of string we need to know:
68 - what renderer we are using
69 - the current dpi of the renderer
70 - the string
71 - the font properties
72 - is it math text or not
73
74 We do this as a two-layer cache with the outer layer being tied to a
75 renderer instance and the inner layer handling everything else.
76
77 The outer layer is implemented as `.WeakKeyDictionary` keyed on the
78 renderer. As long as someone else is holding a hard ref to the renderer
79 we will keep the cache alive, but it will be automatically dropped when
80 the renderer is garbage collected.
81
82 The inner layer is provided by an lru_cache with a large maximum size (such
83 that we expect very few cache misses in actual use cases). As the
84 dpi is mutable on the renderer, we need to explicitly include it as part of
85 the cache key on the inner layer even though we do not directly use it (it is
86 used in the method call on the renderer).
87
88 This function takes a renderer and returns a function that can be used to
89 get the font metrics.
90
91 Parameters
92 ----------
93 input_renderer : maplotlib.backend_bases.RendererBase
94 The renderer to set the cache up for.
95
96 _cache : dict, optional
97 We are using the mutable default value to attach the cache to the function.
98
99 In principle you could pass a different dict-like to this function to inject
100 a different cache, but please don't. This is an internal function not meant to
101 be reused outside of the narrow context we need it for.
102
103 There is a possible race condition here between threads, we may need to drop the
104 mutable default and switch to a threadlocal variable in the future.
105
106 """
107 if (_text_metrics := _cache.get(input_renderer, None)) is None:
108 # We are going to include this in the closure we put as values in the
109 # cache. Closing over a hard-ref would create an unbreakable reference
110 # cycle.
111 renderer_ref = weakref.ref(input_renderer)
112
113 # define the function locally to get a new lru_cache per renderer
114 @functools.lru_cache(4096)
115 # dpi is unused, but participates in cache invalidation (via the renderer).
116 def _text_metrics(text, fontprop, ismath, dpi):
117 # this should never happen under normal use, but this is a better error to
118 # raise than an AttributeError on `None`
119 if (local_renderer := renderer_ref()) is None:

Callers 1

Calls 1

getMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…