Skip to content

Commit c8d438f

Browse files
committed
TST: add a test of font families in svg text-as-text mode
This tests: 1. all of the fonts from the generic lists Matplotlib maintains ends up in the svg 2. the generic family is included and un-escaped 3. the specific fonts are escaped 4. glyph fallback will happen in fonts found via generic family names
1 parent ddb8917 commit c8d438f

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

lib/matplotlib/tests/test_backend_svg.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,75 @@ def test_svg_escape():
527527
fig.savefig(fd, format='svg')
528528
buf = fd.getvalue().decode()
529529
assert '<'"&>"' in buf
530+
531+
532+
@pytest.mark.parametrize("font_str", [
533+
"'DejaVu Sans', 'WenQuanYi Zen Hei', 'Arial', sans-serif",
534+
"'DejaVu Serif', 'WenQuanYi Zen Hei', 'Times New Roman', serif",
535+
"'Arial', 'WenQuanYi Zen Hei', cursive",
536+
"'Impact', 'WenQuanYi Zen Hei', fantasy",
537+
"'DejaVu Sans Mono', 'WenQuanYi Zen Hei', 'Courier New', monospace",
538+
# # These do not work because the logic to get the font metrics will not
539+
# # find WenQuanYi as the fallback logic steps with the first fallback font
540+
# "'DejaVu Sans Mono', 'Courier New', 'WenQuanYi Zen Hei', monospace",
541+
# "'DejaVu Sans', 'Arial', 'WenQuanYi Zen Hei', sans-serif",
542+
# "'DejaVu Serif', 'Times New Roman', 'WenQuanYi Zen Hei', serif",
543+
])
544+
@pytest.mark.parametrize("include_generic", [True, False])
545+
def test_svg_font_string(font_str, include_generic):
546+
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
547+
if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc":
548+
pytest.skip("Font may be missing")
549+
550+
explicit, *rest, generic = map(
551+
lambda x: x.strip("'"), font_str.split(", ")
552+
)
553+
size = len(generic)
554+
if include_generic:
555+
rest = rest + [generic]
556+
plt.rcParams[f"font.{generic}"] = rest
557+
plt.rcParams["font.size"] = size
558+
plt.rcParams["svg.fonttype"] = "none"
559+
560+
fig, ax = plt.subplots()
561+
if generic == "sans-serif":
562+
generic_options = ["sans", "sans-serif", "sans serif"]
563+
else:
564+
generic_options = [generic]
565+
566+
for generic_name in generic_options:
567+
# test that falback works
568+
ax.text(
569+
0.5,
570+
0.5,
571+
"There are 几个汉字 in between!",
572+
family=[explicit, generic_name],
573+
ha="center",
574+
)
575+
# test depulication works
576+
ax.text(
577+
0.5,
578+
0.1,
579+
"There are 几个汉字 in between!",
580+
family=[explicit, *rest, generic_name],
581+
ha="center",
582+
)
583+
ax.axis("off")
584+
585+
with BytesIO() as fd:
586+
fig.savefig(fd, format="svg")
587+
buf = fd.getvalue()
588+
589+
tree = xml.etree.ElementTree.fromstring(buf)
590+
ns = "http://www.w3.org/2000/svg"
591+
text_count = 0
592+
for text_element in tree.findall(f".//{{{ns}}}text"):
593+
text_count += 1
594+
font_info = dict(
595+
map(lambda x: x.strip(), _.strip().split(":"))
596+
for _ in dict(text_element.items())["style"].split(";")
597+
)["font"]
598+
599+
assert font_info == f"{size}px {font_str}"
600+
print(font_info)
601+
assert text_count == len(ax.texts)

0 commit comments

Comments
 (0)