Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/matplotlib/_afm.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,18 @@ def get_angle(self) -> float:
"""Return the fontangle as float."""
return self._header['ItalicAngle']

def get_ascender(self) -> float:
"""Return the ascent as float."""
return self._header['Ascender']

def get_capheight(self) -> float:
"""Return the cap height as float."""
return self._header['CapHeight']

def get_descender(self) -> float:
"""Return the descent as float."""
return self._header['Descender']

def get_xheight(self) -> float:
"""Return the xheight as float."""
return self._header['XHeight']
Expand Down
26 changes: 26 additions & 0 deletions lib/matplotlib/backends/_backend_pdf_ps.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,32 @@ def get_canvas_width_height(self):
# docstring inherited
return self.width * 72.0, self.height * 72.0

def _get_font_height_metrics(self, prop):
"""
Return the ascent, descent, and line gap for font described by *prop*.

TODO: This is a temporary method until we design a proper API for the backends.

Parameters
----------
prop : `.font_manager.FontProperties`
The properties describing the font to measure.

Returns
-------
ascent, descent, line_gap : float or None
The ascent, descent and line gap of the determined font, or None to fall
back to normal measurements.
"""
if not mpl.rcParams[self._use_afm_rc_name]:
return None, None, None
font = self._get_font_afm(prop)
scale = prop.get_size_in_points() / 1000
a = font.get_ascender() * scale
d = -font.get_descender() * scale
g = (a + d) * 0.2 # Preserve previous line spacing of 1.2.
return a, d, g

def get_text_width_height_descent(self, s, prop, ismath):
# docstring inherited
if ismath == "TeX":
Expand Down
Binary file not shown.
39 changes: 23 additions & 16 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,22 +437,29 @@ def _get_layout(self, renderer):
dpi = self.get_figure(root=True).dpi
# Determine full vertical extent of font, including ascenders and descenders:
if not self.get_usetex():
font = get_font(fontManager._find_fonts_by_props(self._fontproperties))
possible_metrics = [
('OS/2', 'sTypoLineGap', 'sTypoAscender', 'sTypoDescender'),
('hhea', 'lineGap', 'ascent', 'descent')
]
for table_name, linegap_key, ascent_key, descent_key in possible_metrics:
table = font.get_sfnt_table(table_name)
if table is None:
continue
# Rescale to font size/DPI if the metrics were available.
fontsize = self._fontproperties.get_size_in_points()
units_per_em = font.get_sfnt_table('head')['unitsPerEm']
line_gap = table[linegap_key] / units_per_em * fontsize * dpi / 72
min_ascent = table[ascent_key] / units_per_em * fontsize * dpi / 72
min_descent = -table[descent_key] / units_per_em * fontsize * dpi / 72
break
if hasattr(renderer, '_get_font_height_metrics'):
# TODO: This is a temporary internal method call (for _backend_pdf_ps to
# support AFM files) until we design a proper API for the backends.
min_ascent, min_descent, line_gap = renderer._get_font_height_metrics(
self._fontproperties)
if min_ascent is None:
font = get_font(fontManager._find_fonts_by_props(self._fontproperties))
possible = [
('OS/2', 'sTypoLineGap', 'sTypoAscender', 'sTypoDescender'),
('hhea', 'lineGap', 'ascent', 'descent')
]
for table_name, linegap_key, ascent_key, descent_key in possible:
table = font.get_sfnt_table(table_name)
if table is None:
continue
# Rescale to font size/DPI if the metrics were available.
fontsize = self._fontproperties.get_size_in_points()
units_per_em = font.get_sfnt_table('head')['unitsPerEm']
scale = 1 / units_per_em * fontsize * dpi / 72
line_gap = table[linegap_key] * scale
min_ascent = table[ascent_key] * scale
min_descent = -table[descent_key] * scale
break
if None in (min_ascent, min_descent):
# Fallback to font measurement.
_, h, min_descent = _get_text_metrics_with_cache(
Expand Down
Loading