Skip to content

Commit d48cc1c

Browse files
committed
Improve fallback font export tests
Working on matplotlib#28765, I realized that we don't need an external font to test font fallback, as `cmr10`, and related, fonts have fairly low coverage compared to `DejaVu Sans`. Thus font fallback can easily be tested by starting with `cmr10`, and pulling additional characters from `DejaVu Sans`. In addition, this change increases unique characters in the figure to 491, which triggers some code paths for tables that are normally limited to 256 characters.
1 parent 9db1b97 commit d48cc1c

File tree

12 files changed

+23969
-1180
lines changed

12 files changed

+23969
-1180
lines changed

lib/matplotlib/testing/__init__.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
"""
22
Helper functions for testing.
33
"""
4-
from pathlib import Path
5-
from tempfile import TemporaryDirectory
4+
import itertools
65
import locale
76
import logging
87
import os
8+
from pathlib import Path
9+
import string
910
import subprocess
1011
import sys
12+
from tempfile import TemporaryDirectory
1113

1214
import matplotlib as mpl
1315
from matplotlib import _api
@@ -232,3 +234,44 @@ def is_ci_environment():
232234
return True
233235

234236
return False
237+
238+
239+
def _gen_multi_font_text():
240+
"""
241+
Generate text intended for use with multiple fonts to exercise font fallbacks.
242+
243+
Returns
244+
-------
245+
fonts : list of str
246+
The names of the fonts used to render the test string, sorted by intended
247+
priority. This should be set as the font family for the Figure or Text artist.
248+
text : str
249+
The test string.
250+
"""
251+
# These fonts are serif and sans-serif, and would not normally be combined, but that
252+
# should make it easier to see which glyph is from which font.
253+
fonts = ['cmr10', 'DejaVu Sans']
254+
# cmr10 does not contain accented characters, so they should fall back to DejaVu
255+
# Sans. However, some accented capital A versions *are* in cmr10 with non-standard
256+
# glyph shapes, so don't test those (otherwise this Latin1 supplement group would
257+
# start at 0xA0.)
258+
start = 0xC5
259+
latin1_supplement = [chr(x) for x in range(start, 0xFF+1)]
260+
latin_extended_A = [chr(x) for x in range(0x100, 0x17F+1)]
261+
latin_extended_B = [chr(x) for x in range(0x180, 0x24F+1)]
262+
count = itertools.count(start - 0xA0)
263+
non_basic_characters = '\n'.join(
264+
''.join(line)
265+
for _, line in itertools.groupby( # Replace with itertools.batched for Py3.12+.
266+
[*latin1_supplement, *latin_extended_A, *latin_extended_B],
267+
key=lambda x: next(count) // 32) # 32 characters per line.
268+
)
269+
test_str = f"""There are basic characters
270+
{string.ascii_uppercase} {string.ascii_lowercase}
271+
{string.digits} {string.punctuation}
272+
and accented characters
273+
{non_basic_characters}
274+
in between!"""
275+
# The resulting string contains 491 unique characters. Some file formats use 8-bit
276+
# tables, which the large number of characters exercises twice over.
277+
return fonts, test_str

lib/matplotlib/testing/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ def ipython_in_subprocess(
5252
all_expected_backends: dict[tuple[int, int], str],
5353
) -> None: ...
5454
def is_ci_environment() -> bool: ...
55+
def _gen_multi_font_text() -> tuple[list[str], str]: ...
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)