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

Appearance settings

Commit cad73cf

Browse filesBrowse files
committed
print fontname in missing glyph warning + all fallback fonts missing glyph
catch missing glyph errors in font tests
1 parent 1536245 commit cad73cf
Copy full SHA for cad73cf

File tree

7 files changed

+37
-18
lines changed
Filter options

7 files changed

+37
-18
lines changed

‎lib/matplotlib/_text_helpers.py

Copy file name to clipboardExpand all lines: lib/matplotlib/_text_helpers.py
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
"LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"])
1313

1414

15-
def warn_on_missing_glyph(codepoint):
15+
def warn_on_missing_glyph(codepoint, font_name):
1616
_api.warn_external(
17-
"Glyph {} ({}) missing from current font.".format(
17+
"Glyph {} ({}) missing from current font {}.".format(
1818
codepoint,
19-
chr(codepoint).encode("ascii", "namereplace").decode("ascii")))
19+
chr(codepoint).encode("ascii", "namereplace").decode("ascii"),
20+
font_name))
2021
block = ("Hebrew" if 0x0590 <= codepoint <= 0x05ff else
2122
"Arabic" if 0x0600 <= codepoint <= 0x06ff else
2223
"Devanagari" if 0x0900 <= codepoint <= 0x097f else

‎lib/matplotlib/tests/test_backend_pdf.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_pdf.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ def test_glyphs_subset():
419419
assert subfont.get_num_glyphs() == nosubfont.get_num_glyphs()
420420

421421

422+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
422423
@image_comparison(["multi_font_type3.pdf"], tol=4.6)
423424
def test_multi_font_type3():
424425
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
@@ -432,6 +433,7 @@ def test_multi_font_type3():
432433
fig.text(0.15, 0.475, "There are 几个汉字 in between!")
433434

434435

436+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
435437
@image_comparison(["multi_font_type42.pdf"], tol=2.2)
436438
def test_multi_font_type42():
437439
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])

‎lib/matplotlib/tests/test_backend_ps.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_ps.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ def test_no_duplicate_definition():
318318
assert max(Counter(wds).values()) == 1
319319

320320

321+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
321322
@image_comparison(["multi_font_type3.eps"], tol=0.51)
322323
def test_multi_font_type3():
323324
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
@@ -331,6 +332,7 @@ def test_multi_font_type3():
331332
fig.text(0.15, 0.475, "There are 几个汉字 in between!")
332333

333334

335+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
334336
@image_comparison(["multi_font_type42.eps"], tol=1.6)
335337
def test_multi_font_type42():
336338
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])

‎lib/matplotlib/tests/test_backend_svg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_svg.py
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ def test_svg_metadata():
492492
assert values == metadata['Keywords']
493493

494494

495+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
495496
@image_comparison(["multi_font_aspath.svg"], tol=1.8)
496497
def test_multi_font_type3():
497498
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
@@ -505,6 +506,7 @@ def test_multi_font_type3():
505506
fig.text(0.15, 0.475, "There are 几个汉字 in between!")
506507

507508

509+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
508510
@image_comparison(["multi_font_astext.svg"])
509511
def test_multi_font_type42():
510512
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
@@ -551,6 +553,7 @@ def test_svg_escape():
551553
assert '&lt;&apos;&quot;&amp;&gt;"' in buf
552554

553555

556+
@pytest.mark.filterwarnings("ignore: Glyph * : UserWarning")
554557
@pytest.mark.parametrize("font_str", [
555558
"'DejaVu Sans', 'WenQuanYi Zen Hei', 'Arial', sans-serif",
556559
"'DejaVu Serif', 'WenQuanYi Zen Hei', 'Times New Roman', serif",

‎lib/matplotlib/tests/test_ft2font.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_ft2font.py
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def test_ft2font_positive_hinting_factor():
3030
ft2font.FT2Font(file_name, 0)
3131

3232

33+
@pytest.mark.filterwarnings("ignore: Glyph .* missing from current font DejaVu Sans.")
3334
def test_fallback_smoke():
3435
fp = fm.FontProperties(family=["WenQuanYi Zen Hei"])
3536
if Path(fm.findfont(fp)).name != "wqy-zenhei.ttc":
@@ -55,6 +56,7 @@ def test_fallback_smoke():
5556
fig.savefig(io.BytesIO(), format=fmt)
5657

5758

59+
@pytest.mark.filterwarnings("ignore: Glyph .* missing from current font DejaVu Sans.")
5860
@pytest.mark.parametrize('family_name, file_name',
5961
[("WenQuanYi Zen Hei", "wqy-zenhei"),
6062
("Noto Sans CJK JP", "NotoSansCJK")]
@@ -78,6 +80,18 @@ def test_font_fallback_chinese(fig_test, fig_ref, family_name, file_name):
7880
fig_test.text(0.05, .85 - 0.15*j, txt, family=test_font)
7981

8082

83+
def test_fallback_cascade_missing(recwarn):
84+
font_list = ['DejaVu Serif', 'DejaVu Sans']
85+
fig = plt.figure()
86+
fig.text(.5, .5, "Hello 🙃 World!", family=font_list)
87+
fig.canvas.draw()
88+
assert all(isinstance(warn.message, UserWarning) for warn in recwarn)
89+
e = "Glyph 128579 (\\N{{UPSIDE-DOWN FACE}}) missing from current font {}."
90+
assert ([(warn.message.args) for warn in recwarn] ==
91+
[(e.format(font),) for font in font_list])
92+
93+
94+
@pytest.mark.filterwarnings("ignore: Glyph ")
8195
@pytest.mark.parametrize(
8296
"family_name, file_name",
8397
[

‎lib/matplotlib/tests/test_text.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_text.py
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,13 @@ def test_pdf_kerning():
817817

818818
def test_unsupported_script(recwarn):
819819
fig = plt.figure()
820-
fig.text(.5, .5, "\N{BENGALI DIGIT ZERO}")
820+
t = fig.text(.5, .5, "\N{BENGALI DIGIT ZERO}")
821821
fig.canvas.draw()
822822
assert all(isinstance(warn.message, UserWarning) for warn in recwarn)
823823
assert (
824824
[warn.message.args for warn in recwarn] ==
825-
[(r"Glyph 2534 (\N{BENGALI DIGIT ZERO}) missing from current font.",),
825+
[(r"Glyph 2534 (\N{BENGALI DIGIT ZERO}) missing from current font "
826+
+ f"{t.get_fontname()}.",),
826827
(r"Matplotlib currently does not support Bengali natively.",)])
827828

828829

‎src/ft2font.cpp

Copy file name to clipboardExpand all lines: src/ft2font.cpp
+9-13Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,13 @@ FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1,
184184
m_dirty = true;
185185
}
186186

187-
static void ft_glyph_warn(FT_ULong charcode)
187+
static void ft_glyph_warn(FT_ULong charcode, FT_String *family_name)
188188
{
189+
const char* name = (family_name != NULL)?family_name:"UNAVAILABLE";
189190
PyObject *text_helpers = NULL, *tmp = NULL;
191+
190192
if (!(text_helpers = PyImport_ImportModule("matplotlib._text_helpers")) ||
191-
!(tmp = PyObject_CallMethod(text_helpers, "warn_on_missing_glyph", "k", charcode))) {
193+
!(tmp = PyObject_CallMethod(text_helpers, "warn_on_missing_glyph", "(k, s)", charcode, name))) {
192194
goto exit;
193195
}
194196
exit:
@@ -207,7 +209,7 @@ ft_get_char_index_or_warn(FT_Face face, FT_ULong charcode, bool warn = true)
207209
return glyph_index;
208210
}
209211
if (warn) {
210-
ft_glyph_warn(charcode);
212+
ft_glyph_warn(charcode, face->family_name);
211213
}
212214
return 0;
213215
}
@@ -515,8 +517,6 @@ void FT2Font::set_text(
515517
char_to_font, glyph_to_font, codepoints[n], flags,
516518
charcode_error, glyph_error, false);
517519
if (!was_found) {
518-
ft_glyph_warn((FT_ULong)codepoints[n]);
519-
520520
// render missing glyph tofu
521521
// come back to top-most font
522522
ft_object_with_glyph = this;
@@ -582,7 +582,6 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
582582
bool was_found = load_char_with_fallback(ft_object_with_glyph, final_glyph_index, glyphs, char_to_font,
583583
glyph_to_font, charcode, flags, charcode_error, glyph_error, true);
584584
if (!was_found) {
585-
ft_glyph_warn(charcode);
586585
if (charcode_error) {
587586
throw_ft_error("Could not load charcode", charcode_error);
588587
}
@@ -609,7 +608,7 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
609608

610609
bool FT2Font::get_char_fallback_index(FT_ULong charcode, int& index) const
611610
{
612-
FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
611+
FT_UInt glyph_index = ft_get_char_index_or_warn(face, charcode);
613612
if (glyph_index) {
614613
// -1 means the host has the char and we do not need to fallback
615614
index = -1;
@@ -642,17 +641,14 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
642641
FT_Error &glyph_error,
643642
bool override = false)
644643
{
645-
FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
646-
644+
FT_UInt glyph_index = ft_get_char_index_or_warn(face, charcode);
647645
if (glyph_index || override) {
648-
charcode_error = FT_Load_Glyph(face, glyph_index, flags);
649-
if (charcode_error) {
646+
if ((charcode_error=FT_Load_Glyph(face, glyph_index, flags))) {
650647
return false;
651648
}
652649

653650
FT_Glyph thisGlyph;
654-
glyph_error = FT_Get_Glyph(face->glyph, &thisGlyph);
655-
if (glyph_error) {
651+
if ((glyph_error= FT_Get_Glyph(face->glyph, &thisGlyph))){
656652
return false;
657653
}
658654

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.