Currently, we set a minimum line height by measuring the height and depth of the "lp" string. Line spacing is then some multiple of the line height (by default 1.2×).
|
# Full vertical extent of font, including ascenders and descenders: |
|
_, lp_h, lp_d = _get_text_metrics_with_cache( |
|
renderer, "lp", self._fontproperties, |
|
ismath="TeX" if self.get_usetex() else False, |
|
dpi=self.get_figure(root=True).dpi) |
|
min_dy = (lp_h - lp_d) * self._linespacing |
Looking back into the history, this used to be "Tglp":
|
# Find full vertical extent, including ascenders and descenders: |
|
tmp, heightt = renderer.get_text_width_height( |
|
'Tglp', self._fontproperties, ismath=False) |
and before that just a "T" was used for line height:
|
tmp, heightt = renderer.get_text_width_height( |
|
'T', self._fontproperties, ismath=False) |
and before that, the "T" was used only for empty lines:
|
if not len(line) and not self.is_math_text(): |
|
# approx the height of empty line with tall char |
|
tmp, h = renderer.get_text_width_height( |
|
'T', self._fontproperties, ismath=False) |
Now that we are supporting more fonts and languages, this may not be ideal. For example, for the test in #30725, I only specified the OpenMoji font. This font contains only emoji and no Latin characters of any kind. This causes warnings that both l and p are not found even though they aren't used in any user strings. We then end up with the ascender/descender values for the Last Resort font. I haven't found a specific example, but I can imagine a user may be setting some language-specific font that contains no Latin characters and no fallback, and would trigger this warning as well, which might be a bit mysterious.
Microsoft's recommendation is to use the ascender value to measure from top to baseline and descender value from baseline to bottom, plus a line gap to produce the interline spacing (suggested to add up to 120% the height similar to our default.) Of course, fonts being fonts, there are 2 other sets of vertical metrics and various strategies for dealing with them.
Regardless of the multiple values to try, from the history, I don't think we went with the measurement strategy because it was thought that the embedded values were unreliable. Rather, it seems to have been from necessity of not having a font parser.
So the question now goes (with some of my thoughts in parentheses):
- Should we move to font metrics instead? (I think so.)
- If so, which strategy to use? (probably the webfont or Google ones.)
- Should we still try to measure
lp and set some combined minimum or just trust the fonts aren't broken? (hopefully not required.)
- What do we do when fallbacks are specified? Currently we get the measurement from the first to match the "lp" string. Should we instead look at all the specified fonts and take a minimum of all of them (even if not used in the text)? Or measure all the fonts used in a line? Or measure all the fonts used in an entire text object? (probably not the first option, unsure whether the second or third.)
Currently, we set a minimum line height by measuring the height and depth of the "lp" string. Line spacing is then some multiple of the line height (by default 1.2×).
matplotlib/lib/matplotlib/text.py
Lines 446 to 451 in 47874b4
Looking back into the history, this used to be "Tglp":
matplotlib/lib/matplotlib/text.py
Lines 254 to 256 in 30a5d33
and before that just a "T" was used for line height:
matplotlib/lib/matplotlib/text.py
Lines 251 to 252 in 6f2a3f1
and before that, the "T" was used only for empty lines:
matplotlib/lib/matplotlib/text.py
Lines 183 to 186 in 2e3f321
Now that we are supporting more fonts and languages, this may not be ideal. For example, for the test in #30725, I only specified the OpenMoji font. This font contains only emoji and no Latin characters of any kind. This causes warnings that both
landpare not found even though they aren't used in any user strings. We then end up with the ascender/descender values for the Last Resort font. I haven't found a specific example, but I can imagine a user may be setting some language-specific font that contains no Latin characters and no fallback, and would trigger this warning as well, which might be a bit mysterious.Microsoft's recommendation is to use the ascender value to measure from top to baseline and descender value from baseline to bottom, plus a line gap to produce the interline spacing (suggested to add up to 120% the height similar to our default.) Of course, fonts being fonts, there are 2 other sets of vertical metrics and various strategies for dealing with them.
Regardless of the multiple values to try, from the history, I don't think we went with the measurement strategy because it was thought that the embedded values were unreliable. Rather, it seems to have been from necessity of not having a font parser.
So the question now goes (with some of my thoughts in parentheses):
lpand set some combined minimum or just trust the fonts aren't broken? (hopefully not required.)