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

Commit8ca754a

Browse files
committed
print fontname in missing glyph warning + all fallback fonts missing glyph
catch missing glyph errors in font testsadd :filter-warning: option to plot directive
1 parente394940 commit8ca754a

File tree

9 files changed

+65
-30
lines changed

9 files changed

+65
-30
lines changed

‎galleries/users_explain/text/fonts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
:include-source:
183183
:caption: The string "There are 几个汉字 in between!" rendered with 2 fonts.
184184
185+
185186
fig, ax = plt.subplots()
186187
ax.text(
187188
.5, .5, "There are 几个汉字 in between!",

‎lib/matplotlib/_text_helpers.py

Lines 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-
defwarn_on_missing_glyph(codepoint):
15+
defwarn_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"if0x0590<=codepoint<=0x05ffelse
2122
"Arabic"if0x0600<=codepoint<=0x06ffelse
2223
"Devanagari"if0x0900<=codepoint<=0x097felse

‎lib/matplotlib/sphinxext/plot_directive.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
figure. This overwrites the caption given in the content, when the plot
7979
is generated from a file.
8080
81+
``:filter-warning:`` : str
82+
When specified, will ignore warnings that match the input string, which is
83+
a warnings filter `message regex <msg>`_ string.
84+
85+
.. _msg: https://docs.python.org/3/library/warnings.html#the-warnings-filter
86+
8187
Additionally, this directive supports all the options of the `image directive
8288
<https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_,
8389
except for ``:target:`` (since plot will add its own target). These include
@@ -177,6 +183,7 @@
177183
importsys
178184
importtextwrap
179185
importtraceback
186+
importwarnings
180187

181188
fromdocutils.parsers.rstimportdirectives,Directive
182189
fromdocutils.parsers.rst.directives.imagesimportImage
@@ -221,6 +228,10 @@ def _option_format(arg):
221228
returndirectives.choice(arg, ('python','doctest'))
222229

223230

231+
def_option_string(arg):
232+
returnargifarg.strip()elseFalse
233+
234+
224235
defmark_plot_labels(app,document):
225236
"""
226237
To make plots referenceable, we need to move the reference from the
@@ -271,7 +282,8 @@ class PlotDirective(Directive):
271282
'context':_option_context,
272283
'nofigs':directives.flag,
273284
'caption':directives.unchanged,
274-
}
285+
'filter-warning':_option_string,
286+
}
275287

276288
defrun(self):
277289
"""Run the plot directive."""
@@ -854,16 +866,20 @@ def run(arguments, content, options, state_machine, state, lineno):
854866

855867
# make figures
856868
try:
857-
results=render_figures(code=code,
858-
code_path=source_file_name,
859-
output_dir=build_dir,
860-
output_base=output_base,
861-
context=keep_context,
862-
function_name=function_name,
863-
config=config,
864-
context_reset=context_opt=='reset',
865-
close_figs=context_opt=='close-figs',
866-
code_includes=source_file_includes)
869+
withwarnings.catch_warnings(record=True)asw:
870+
ifmsg:=options.get('filter-warning',False):
871+
warnings.filterwarnings('ignore',message=msg)
872+
873+
results=render_figures(code=code,
874+
code_path=source_file_name,
875+
output_dir=build_dir,
876+
output_base=output_base,
877+
context=keep_context,
878+
function_name=function_name,
879+
config=config,
880+
context_reset=context_opt=='reset',
881+
close_figs=context_opt=='close-figs',
882+
code_includes=source_file_includes)
867883
errors= []
868884
exceptPlotErroraserr:
869885
reporter=state.memo.reporter

‎lib/matplotlib/tests/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
frompathlibimportPath
2+
importpytest
23

4+
pytest.register_assert_rewrite("matplotlib.testing")
35

46
# Check that the test directories exist.
57
ifnot (Path(__file__).parent/'baseline_images').exists():

‎lib/matplotlib/tests/test_ft2font.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ def test_font_fallback_chinese(fig_test, fig_ref, family_name, file_name):
7878
fig_test.text(0.05,.85-0.15*j,txt,family=test_font)
7979

8080

81+
deftest_fallback_cascade_missing(recwarn):
82+
font_list= ['DejaVu Serif','DejaVu Sans']
83+
fig=plt.figure()
84+
fig.text(.5,.5,"Hello 🙃 World!",family=font_list)
85+
fig.canvas.draw()
86+
assertall(isinstance(warn.message,UserWarning)forwarninrecwarn)
87+
e="Glyph 128579 (\\N{{UPSIDE-DOWN FACE}}) missing from current font {}."
88+
assert ([(warn.message.args)forwarninrecwarn]==
89+
[(e.format(font),)forfontinfont_list])
90+
91+
8192
@pytest.mark.parametrize(
8293
"family_name, file_name",
8394
[

‎lib/matplotlib/tests/test_text.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,13 @@ def test_pdf_kerning():
817817

818818
deftest_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
assertall(isinstance(warn.message,UserWarning)forwarninrecwarn)
823823
assert (
824824
[warn.message.argsforwarninrecwarn]==
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

‎pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,6 @@ ignore_messages = [
288288
"Duplicate implicit target name:\".*\".",
289289
"Duplicate explicit target name:\".*\".",
290290
]
291+
292+
[pytest]
293+
python_files = lib\matplotlib\tests\*.py

‎src/ft2font.cpp

Lines changed: 13 additions & 14 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-
staticvoidft_glyph_warn(FT_ULong charcode)
187+
staticvoidft_glyph_warn(FT_ULong charcode, FT_String *family_name)
188188
{
189+
constchar* 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
gotoexit;
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
return0;
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
boolFT2Font::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,15 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
642641
FT_Error &glyph_error,
643642
booloverride =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,false);
645+
family_names.push_back(face->family_name);
647646
if (glyph_index ||override) {
648-
charcode_error =FT_Load_Glyph(face, glyph_index, flags);
649-
if (charcode_error) {
647+
if ((charcode_error=FT_Load_Glyph(face, glyph_index, flags))) {
650648
returnfalse;
651649
}
652650

653651
FT_Glyph thisGlyph;
654-
glyph_error =FT_Get_Glyph(face->glyph, &thisGlyph);
655-
if (glyph_error) {
652+
if ((glyph_error=FT_Get_Glyph(face->glyph, &thisGlyph))){
656653
returnfalse;
657654
}
658655

@@ -667,7 +664,6 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
667664
parent_glyphs.push_back(thisGlyph);
668665
returntrue;
669666
}
670-
671667
else {
672668
for (size_t i =0; i < fallbacks.size(); ++i) {
673669
bool was_found = fallbacks[i]->load_char_with_fallback(
@@ -677,6 +673,9 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
677673
returntrue;
678674
}
679675
}
676+
for (size_t j=family_names.size()-1; j>0; --j){
677+
ft_glyph_warn(charcode, family_names[j]);
678+
}
680679
returnfalse;
681680
}
682681
}

‎src/ft2font.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class FT2Font
144144
FT_Vector pen;/* untransformed origin*/
145145
std::vector<FT_Glyph> glyphs;
146146
std::vector<FT2Font *> fallbacks;
147+
std::vector<FT_String *> family_names;
147148
std::unordered_map<FT_UInt, FT2Font *> glyph_to_font;
148149
std::unordered_map<long, FT2Font *> char_to_font;
149150
FT_BBox bbox;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp