Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Create tiny mathtext baseline images using svg with non-embedded fonts.#19201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
anntzer wants to merge3 commits intomatplotlib:masterfromanntzer:mathtextsvgtests
Closed
Show file tree
Hide file tree
Changes fromall 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
7 changes: 4 additions & 3 deletionslib/matplotlib/_mathtext.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2158,7 +2158,8 @@ def __init__(self):

p.sqrt <<= Group(
Suppress(Literal(r"\sqrt"))
- ((Optional(p.lbracket + p.int_literal + p.rbracket, default=None)
- ((Group(Optional(
p.lbracket + OneOrMore(~p.rbracket + p.token) + p.rbracket))
+ p.required_group)
| Error("Expected \\sqrt{value}"))
)
Expand DownExpand Up@@ -2864,10 +2865,10 @@ def sqrt(self, s, loc, toks):

# Add the root and shift it upward so it is above the tick.
# The value of 0.6 is a hard-coded hack ;)
ifroot is None:
ifnot root:
root = Box(check.width * 0.5, 0., 0.)
else:
root = Hlist([Char(x, state) for x inroot])
root = Hlist(root)
root.shrink()
root.shrink()

Expand Down
32 changes: 24 additions & 8 deletionslib/matplotlib/backends/backend_svg.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@
from matplotlib.backends.backend_mixed import MixedModeRenderer
from matplotlib.colors import rgb2hex
from matplotlib.dates import UTC
from matplotlib.font_manager import findfont, get_font
from matplotlib.font_manager import findfont, get_font, ttfFontProperty
from matplotlib.ft2font import LOAD_NO_HINTING
from matplotlib.mathtext import MathTextParser
from matplotlib.path import Path
Expand DownExpand Up@@ -94,6 +94,12 @@ def escape_attrib(s):
return s


def _quote_escape_attrib(s):
return ('"' + escape_cdata(s) + '"' if '"' not in s else
"'" + escape_cdata(s) + "'" if "'" not in s else
'"' + escape_attrib(s) + '"')


def short_float_fmt(x):
"""
Create a short string representation of a float, which is %f
Expand DownExpand Up@@ -159,8 +165,8 @@ def start(self, tag, attrib={}, **extra):
for k, v in sorted({**attrib, **extra}.items()):
if v:
k = escape_cdata(k)
v =escape_attrib(v)
self.__write(' %s="%s"' % (k, v))
v =_quote_escape_attrib(v)
self.__write(' %s=%s' % (k, v))
self.__open = 1
return len(self.__tags) - 1

Expand DownExpand Up@@ -1197,11 +1203,21 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
# Sort the characters by font, and output one tspan for each.
spans = OrderedDict()
for font, fontsize, thetext, new_x, new_y in glyphs:
style = generate_css({
'font-size': short_float_fmt(fontsize) + 'px',
'font-family': font.family_name,
'font-style': font.style_name.lower(),
'font-weight': font.style_name.lower()})
entry = ttfFontProperty(font)
font_parts = ['font:']
if entry.style != 'normal':
font_parts.append(entry.style)
if entry.variant != 'normal':
font_parts.append(entry.variant)
if entry.weight != 400:
font_parts.append(f'{entry.weight}')
font_parts.extend([
f'{short_float_fmt(fontsize)}px',
f'{entry.name!r}', # ensure quoting
])
if entry.stretch != 'normal':
font_parts.extend(['; font-stretch:', entry.stretch])
style = ' '.join(font_parts)
if thetext == 32:
thetext = 0xa0 # non-breaking space
spans.setdefault(style, []).append((new_x, -new_y, thetext))
Expand Down
19 changes: 17 additions & 2 deletionslib/matplotlib/testing/compare.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -181,7 +181,7 @@ def __call__(self, orig, dest):
# just be reported as a regular exception below).
"DISPLAY": "",
# Do not load any user options.
"INKSCAPE_PROFILE_DIR":os.devnull,
"INKSCAPE_PROFILE_DIR":self._tmpdir.name,
}
# Old versions of Inkscape (e.g. 0.48.3.1) seem to sometimes
# deadlock when stderr is redirected to a pipe, so we redirect it
Expand DownExpand Up@@ -233,6 +233,15 @@ def __del__(self):
self._tmpdir.cleanup()


class _SVGWithMatplotlibFontsConverter(_SVGConverter):
def __call__(self, orig, dest):
if not hasattr(self, "_tmpdir"):
self._tmpdir = TemporaryDirectory()
shutil.copytree(cbook._get_data_path("fonts/ttf"),
Path(self._tmpdir.name, "fonts"))
return super().__call__(orig, dest)


def _update_converter():
try:
mpl._get_executable_info("gs")
Expand All@@ -254,6 +263,7 @@ def _update_converter():
#: extension to png format.
converter = {}
_update_converter()
_svg_with_matplotlib_fonts_converter = _SVGWithMatplotlibFontsConverter()


def comparable_formats():
Expand DownExpand Up@@ -303,7 +313,12 @@ def convert(filename, cache):
return str(newpath)

_log.debug("For %s: converting to png.", filename)
converter[path.suffix[1:]](path, newpath)
convert = converter[path.suffix[1:]]
if path.suffix == ".svg":
contents = path.read_text()
if 'style="font:' in contents: # for svg.fonttype = none.
convert = _svg_with_matplotlib_fonts_converter
convert(path, newpath)

if cache_dir is not None:
_log.debug("For %s: caching conversion result.", filename)
Expand Down
View file
Open in desktop
Loading
Sorry, something went wrong.Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 39 additions & 9 deletionslib/matplotlib/tests/test_mathtext.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
import io
importos
from pathlibimportPath
import re
import shlex
from xml.etree import ElementTree as ET

import numpy as np
import pytest
Expand DownExpand Up@@ -110,6 +112,9 @@
r'$\left(X\right)_{a}^{b}$', # github issue 7615
r'$\dfrac{\$100.00}{y}$', # github issue #1888
]
svg_only_math_tests = [
r'$\sqrt[ab]{123}$', # github issue #8665
]

digits = "0123456789"
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Expand DownExpand Up@@ -165,8 +170,6 @@
for set in chars:
font_tests.append(wrapper % set)

font_tests = list(filter(lambda x: x[1] is not None, enumerate(font_tests)))


@pytest.fixture
def baseline_images(request, fontset, index):
Expand All@@ -190,6 +193,32 @@ def test_mathtext_rendering(baseline_images, fontset, index, test):
horizontalalignment='center', verticalalignment='center')


cur_svg_only_math_tests = list(
filter(lambda x: x[1] is not None, enumerate(svg_only_math_tests)))


@pytest.mark.parametrize('index, test', cur_svg_only_math_tests,
ids=[str(idx) for idx, _ in cur_svg_only_math_tests])
@pytest.mark.parametrize('fontset', ['all'])
@pytest.mark.parametrize('baseline_images', ['mathtext1'], indirect=True)
@image_comparison(
baseline_images=None, extensions=['svg'],
savefig_kwarg={
'metadata': { # Minimize svg size.
'Creator': None, 'Date': None, 'Format': None, 'Type': None}})
def test_mathtext_rendering_svg_only(baseline_images, fontset, index, test):
mpl.rcParams['svg.fonttype'] = 'none'
fig = plt.figure(figsize=(5.25, 5.25))
fig.patch.set_visible(False) # Minimize svg size.
fontsets = ['cm', 'stix', 'stixsans', 'dejavusans', 'dejavuserif']
for i, fontset in enumerate(fontsets):
fig.text(0.5, (i + .5) / len(fontsets), test, math_fontfamily=fontset,
horizontalalignment='center', verticalalignment='center')


font_tests = list(filter(lambda x: x[1] is not None, enumerate(font_tests)))


@pytest.mark.parametrize('index, test', font_tests,
ids=[str(index) for index, _ in font_tests])
@pytest.mark.parametrize('fontset',
Expand DownExpand Up@@ -328,7 +357,7 @@ def test_mathtext_fallback_to_cm_invalid():
("stix", ['DejaVu Sans', 'mpltest', 'STIXGeneral'])])
def test_mathtext_fallback(fallback, fontlist):
mpl.font_manager.fontManager.addfont(
os.path.join((os.path.dirname(os.path.realpath(__file__))), 'mpltest.ttf'))
str(Path(__file__).resolve().parent / 'mpltest.ttf'))
mpl.rcParams["svg.fonttype"] = 'none'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.rm'] = 'mpltest'
Expand All@@ -342,12 +371,13 @@ def test_mathtext_fallback(fallback, fontlist):
fig, ax = plt.subplots()
fig.text(.5, .5, test_str, fontsize=40, ha='center')
fig.savefig(buff, format="svg")
char_fonts = [
line.split("font-family:")[-1].split(";")[0]
for line in str(buff.getvalue()).split(r"\n") if "tspan" in line
]
tspans = (ET.fromstring(buff.getvalue())
.findall(".//{http://www.w3.org/2000/svg}tspan[@style]"))
# Getting the last element of the style attrib is a close enough
# approximation for parsing the font property.
char_fonts = [shlex.split(tspan.attrib["style"])[-1] for tspan in tspans]
assert char_fonts == fontlist
mpl.font_manager.fontManager.ttflist = mpl.font_manager.fontManager.ttflist[:-1]
mpl.font_manager.fontManager.ttflist.pop()


def test_math_to_image(tmpdir):
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp