X Tutup
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
75 changes: 58 additions & 17 deletions lib/matplotlib/_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ def get_axis_height(self, font: str, fontsize: float, dpi: float) -> float:
"""
raise NotImplementedError()

def get_quad(self, font: str, fontsize: float, dpi: float) -> float:
"""
Get the size of a quad for the given *font* and *fontsize*.
"""
raise NotImplementedError()

def get_xheight(self, font: str, fontsize: float, dpi: float) -> float:
"""
Get the xheight for the given *font* and *fontsize*.
Expand Down Expand Up @@ -414,11 +420,25 @@ def _get_info(self, fontname: str, font_class: str, sym: str, fontsize: float,
)

def get_axis_height(self, fontname: str, fontsize: float, dpi: float) -> float:
# The fraction line (if present) must be aligned with the minus sign. Therefore,
# the height of the latter from the baseline is the axis height.
metrics = self.get_metrics(
fontname, mpl.rcParams['mathtext.default'], '\u2212', fontsize, dpi)
return (metrics.ymax + metrics.ymin) / 2
consts = _get_font_constants(self, fontname)
if consts.axis_height is not None:
return consts.axis_height * fontsize * dpi / 72
else:
# The fraction line (if present) must be aligned with the minus sign.
# Therefore, the height of the latter from the baseline is the axis height.
metrics = self.get_metrics(
fontname, mpl.rcParams['mathtext.default'], '\u2212', fontsize, dpi)
return (metrics.ymax + metrics.ymin) / 2

def get_quad(self, fontname: str, fontsize: float, dpi: float) -> float:
consts = _get_font_constants(self, fontname)
if consts.quad is not None:
return consts.quad * fontsize * dpi / 72
else:
# With no other option, we measure the size of an 'm'.
metrics = self.get_metrics(
fontname, mpl.rcParams['mathtext.default'], 'm', fontsize, dpi)
return metrics.advance

def get_xheight(self, fontname: str, fontsize: float, dpi: float) -> float:
# Some fonts report the wrong x-height, while some don't store it, so
Expand Down Expand Up @@ -950,6 +970,13 @@ class FontConstantsBase:
# and scriptscript styles.
denom2: T.ClassVar[float] = 1.1

# The height of a horizontal reference line used for positioning elements in a
# formula, similar to a baseline, as a multiple of design size.
axis_height: T.ClassVar[float | None] = None

# The size of a quad space in LaTeX, as a multiple of design size.
quad: T.ClassVar[float | None] = None


class ComputerModernFontConstants(FontConstantsBase):
# Previously, the x-height of Computer Modern was obtained from the font
Expand All @@ -974,14 +1001,18 @@ class ComputerModernFontConstants(FontConstantsBase):
num3 = 465286 / _x_height
denom1 = 719272 / _x_height
denom2 = 361592 / _x_height
# These come from the cmsy10.tfm metrics, scaled so they are in multiples of design
# size.
axis_height = 262144 / 2**20
quad = 1048579 / 2**20


class STIXFontConstants(FontConstantsBase):
script_space = 0.1
delta = 0.05
delta_slanted = 0.3
delta_integral = 0.3
# These values are extracted from the TeX table of STIXGeneral.ttf using FreeType,
# These values are extracted from the TeX table of STIXGeneral.ttf using FontForge,
# and then divided by design xheight, since we multiply these values by the scaled
# xheight later.
_x_height = 450
Expand All @@ -995,6 +1026,10 @@ class STIXFontConstants(FontConstantsBase):
num3 = 474 / _x_height
denom1 = 756 / _x_height
denom2 = 375 / _x_height
# These come from the same TeX table, scaled by Em size so they are in multiples of
# design size.
axis_height = 250 / 1000
quad = 1000 / 1000


class STIXSansFontConstants(STIXFontConstants):
Expand All @@ -1004,7 +1039,7 @@ class STIXSansFontConstants(STIXFontConstants):


class DejaVuSerifFontConstants(FontConstantsBase):
# These values are extracted from the TeX table of DejaVuSerif.ttf using FreeType,
# These values are extracted from the TeX table of DejaVuSerif.ttf using FontForge,
# and then divided by design xheight, since we multiply these values by the scaled
# xheight later.
_x_height = 1063
Expand All @@ -1018,10 +1053,13 @@ class DejaVuSerifFontConstants(FontConstantsBase):
num3 = 970.752 / _x_height
denom1 = 1548.29 / _x_height
denom2 = 768 / _x_height
# These come from the same TeX table, scaled by Em size so they are in multiples of
# design size.
axis_height = 512 / 2048


class DejaVuSansFontConstants(FontConstantsBase):
# These values are extracted from the TeX table of DejaVuSans.ttf using FreeType,
# These values are extracted from the TeX table of DejaVuSans.ttf using FontForge,
# and then divided by design xheight, since we multiply these values by the scaled
# xheight later.
_x_height = 1120
Expand All @@ -1035,6 +1073,9 @@ class DejaVuSansFontConstants(FontConstantsBase):
num3 = 970.752 / _x_height
denom1 = 1548.29 / _x_height
denom2 = 768 / _x_height
# These come from the same TeX table, scaled by Em size so they are in multiples of
# design size.
axis_height = 512 / 2048


# Maps font family names to the FontConstantBase subclass to use
Expand Down Expand Up @@ -1062,17 +1103,20 @@ class DejaVuSansFontConstants(FontConstantsBase):
}


def _get_font_constant_set(state: ParserState) -> type[FontConstantsBase]:
constants = _font_constant_mapping.get(
state.fontset._get_font(state.font).family_name, FontConstantsBase)
def _get_font_constants(fontset: Fonts, font: str) -> type[FontConstantsBase]:
constants = _font_constant_mapping.get(fontset._get_font(font).family_name,
FontConstantsBase)
# STIX sans isn't really its own fonts, just different code points
# in the STIX fonts, so we have to detect this one separately.
if (constants is STIXFontConstants and
isinstance(state.fontset, StixSansFonts)):
if constants is STIXFontConstants and isinstance(fontset, StixSansFonts):
return STIXSansFontConstants
return constants


def _get_font_constant_set(state: ParserState) -> type[FontConstantsBase]:
return _get_font_constants(state.fontset, state.font)


class Node:
"""A node in the TeX box model."""

Expand Down Expand Up @@ -2306,10 +2350,7 @@ def _make_space(self, percentage: float) -> Kern:
key = (state.font, state.fontsize, state.dpi)
width = self._em_width_cache.get(key)
if width is None:
metrics = state.fontset.get_metrics(
'it', mpl.rcParams['mathtext.default'], 'm',
state.fontsize, state.dpi)
width = metrics.advance
width = state.fontset.get_quad('it', state.fontsize, state.dpi)
self._em_width_cache[key] = width
return Kern(width * percentage)

Expand Down
8 changes: 4 additions & 4 deletions lib/matplotlib/tests/test_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,12 +577,12 @@ def test_box_repr():
_mathtext.DejaVuSansFonts(fm.FontProperties(), LoadFlags.NO_HINTING),
fontsize=12, dpi=100))
assert s == textwrap.dedent("""\
Hlist<w=9.51 h=15.30 d=5.00 s=0.00>[
Hlist<w=9.51 h=14.24 d=6.06 s=0.00>[
Hlist<w=0.00 h=0.00 d=0.00 s=0.00>[],
Hlist<w=9.51 h=15.30 d=5.00 s=0.00>[
Hlist<w=9.51 h=15.30 d=5.00 s=0.00>[
Hlist<w=9.51 h=14.24 d=6.06 s=0.00>[
Hlist<w=9.51 h=14.24 d=6.06 s=0.00>[
Hbox,
Vlist<w=7.43 h=20.30 d=0.00 s=5.00>[
Vlist<w=7.43 h=20.30 d=0.00 s=6.06>[
HCentered<w=7.43 h=8.51 d=0.00 s=0.00>[
Glue,
Hlist<w=7.43 h=8.51 d=0.00 s=0.00>[
Expand Down
Loading
X Tutup