Skip to content

Commit 9c5136f

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 587, which triggers some code paths for tables that are limited to 256 characters.
1 parent 08da740 commit 9c5136f

File tree

11 files changed

+40314
-1117
lines changed

11 files changed

+40314
-1117
lines changed

lib/matplotlib/testing/__init__.py

Lines changed: 46 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,45 @@ 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+
ipa_extensions = [chr(x) for x in range(0x250, 0x2AF+1)]
263+
count = itertools.count(start - 0xA0)
264+
non_basic_characters = '\n'.join(
265+
''.join(line)
266+
for _, line in itertools.groupby( # Replace with itertools.batched for Py3.12+.
267+
[*latin1_supplement, *latin_extended_A, *latin_extended_B, *ipa_extensions],
268+
key=lambda x: next(count) // 32) # 32 characters per line.
269+
)
270+
test_str = f"""There are basic characters
271+
{string.ascii_uppercase} {string.ascii_lowercase}
272+
{string.digits} {string.punctuation}
273+
and accented characters
274+
{non_basic_characters}
275+
in between!"""
276+
# The resulting string contains 587 unique characters. Some file formats use 8-bit
277+
# tables, which the large number of characters exercises twice over.
278+
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)