4
4
5
5
#include < algorithm>
6
6
#include < iterator>
7
+ #include < set>
7
8
#include < sstream>
8
9
#include < stdexcept>
9
10
#include < string>
@@ -184,11 +185,20 @@ FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1,
184
185
m_dirty = true ;
185
186
}
186
187
187
- static void ft_glyph_warn (FT_ULong charcode)
188
+ static void ft_glyph_warn (FT_ULong charcode, std::set<FT_String*> family_names )
188
189
{
189
190
PyObject *text_helpers = NULL , *tmp = NULL ;
191
+ std::set<FT_String*>::iterator it = family_names.begin ();
192
+ std::stringstream ss;
193
+ ss<<*it;
194
+ while (++it != family_names.end ()){
195
+ ss<<" , " <<*it;
196
+ }
197
+
190
198
if (!(text_helpers = PyImport_ImportModule (" matplotlib._text_helpers" )) ||
191
- !(tmp = PyObject_CallMethod (text_helpers, " warn_on_missing_glyph" , " k" , charcode))) {
199
+ !(tmp = PyObject_CallMethod (text_helpers,
200
+ " warn_on_missing_glyph" , " (k, s)" ,
201
+ charcode, ss.str ().c_str ()))) {
192
202
goto exit ;
193
203
}
194
204
exit :
@@ -199,19 +209,6 @@ static void ft_glyph_warn(FT_ULong charcode)
199
209
}
200
210
}
201
211
202
- static FT_UInt
203
- ft_get_char_index_or_warn (FT_Face face, FT_ULong charcode, bool warn = true )
204
- {
205
- FT_UInt glyph_index = FT_Get_Char_Index (face, charcode);
206
- if (glyph_index) {
207
- return glyph_index;
208
- }
209
- if (warn) {
210
- ft_glyph_warn (charcode);
211
- }
212
- return 0 ;
213
- }
214
-
215
212
// ft_outline_decomposer should be passed to FT_Outline_Decompose. On the
216
213
// first pass, vertices and codes are set to NULL, and index is simply
217
214
// incremented for each vertex that should be inserted, so that it is set, at
@@ -510,13 +507,13 @@ void FT2Font::set_text(
510
507
FT_Pos last_advance;
511
508
512
509
FT_Error charcode_error, glyph_error;
510
+ std::set<FT_String*> glyph_seen_fonts;
513
511
FT2Font *ft_object_with_glyph = this ;
514
512
bool was_found = load_char_with_fallback (ft_object_with_glyph, glyph_index, glyphs,
515
513
char_to_font, glyph_to_font, codepoints[n], flags,
516
- charcode_error, glyph_error, false );
514
+ charcode_error, glyph_error, glyph_seen_fonts, false );
517
515
if (!was_found) {
518
- ft_glyph_warn ((FT_ULong)codepoints[n]);
519
-
516
+ ft_glyph_warn ((FT_ULong)codepoints[n], glyph_seen_fonts);
520
517
// render missing glyph tofu
521
518
// come back to top-most font
522
519
ft_object_with_glyph = this ;
@@ -570,6 +567,7 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
570
567
// if this is parent FT2Font, cache will be filled in 2 ways:
571
568
// 1. set_text was previously called
572
569
// 2. set_text was not called and fallback was enabled
570
+ std::set <FT_String *> glyph_seen_fonts;
573
571
if (fallback && char_to_font.find (charcode) != char_to_font.end ()) {
574
572
ft_object = char_to_font[charcode];
575
573
// since it will be assigned to ft_object anyway
@@ -579,10 +577,12 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
579
577
FT_UInt final_glyph_index;
580
578
FT_Error charcode_error, glyph_error;
581
579
FT2Font *ft_object_with_glyph = this ;
582
- bool was_found = load_char_with_fallback (ft_object_with_glyph, final_glyph_index, glyphs, char_to_font,
583
- glyph_to_font, charcode, flags, charcode_error, glyph_error, true );
580
+ bool was_found = load_char_with_fallback (ft_object_with_glyph, final_glyph_index,
581
+ glyphs, char_to_font, glyph_to_font,
582
+ charcode, flags, charcode_error, glyph_error,
583
+ glyph_seen_fonts, true );
584
584
if (!was_found) {
585
- ft_glyph_warn (charcode);
585
+ ft_glyph_warn (charcode, glyph_seen_fonts );
586
586
if (charcode_error) {
587
587
throw_ft_error (" Could not load charcode" , charcode_error);
588
588
}
@@ -592,9 +592,13 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
592
592
}
593
593
ft_object = ft_object_with_glyph;
594
594
} else {
595
+ // no fallback case
595
596
ft_object = this ;
596
- FT_UInt glyph_index = ft_get_char_index_or_warn (face, (FT_ULong)charcode);
597
-
597
+ FT_UInt glyph_index = FT_Get_Char_Index (face, (FT_ULong) charcode);
598
+ if (!glyph_index){
599
+ glyph_seen_fonts.insert ((face != NULL )?face->family_name : NULL );
600
+ ft_glyph_warn ((FT_ULong)charcode, glyph_seen_fonts);
601
+ }
598
602
if (FT_Error error = FT_Load_Glyph (face, glyph_index, flags)) {
599
603
throw_ft_error (" Could not load charcode" , error);
600
604
}
@@ -640,16 +644,17 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
640
644
FT_Int32 flags,
641
645
FT_Error &charcode_error,
642
646
FT_Error &glyph_error,
647
+ std::set<FT_String*> &glyph_seen_fonts,
643
648
bool override = false )
644
649
{
645
650
FT_UInt glyph_index = FT_Get_Char_Index (face, charcode);
651
+ glyph_seen_fonts.insert (face->family_name );
646
652
647
653
if (glyph_index || override ) {
648
654
charcode_error = FT_Load_Glyph (face, glyph_index, flags);
649
655
if (charcode_error) {
650
656
return false ;
651
657
}
652
-
653
658
FT_Glyph thisGlyph;
654
659
glyph_error = FT_Get_Glyph (face->glyph , &thisGlyph);
655
660
if (glyph_error) {
@@ -667,12 +672,12 @@ bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
667
672
parent_glyphs.push_back (thisGlyph);
668
673
return true ;
669
674
}
670
-
671
675
else {
672
676
for (size_t i = 0 ; i < fallbacks.size (); ++i) {
673
677
bool was_found = fallbacks[i]->load_char_with_fallback (
674
- ft_object_with_glyph, final_glyph_index, parent_glyphs, parent_char_to_font,
675
- parent_glyph_to_font, charcode, flags, charcode_error, glyph_error, override );
678
+ ft_object_with_glyph, final_glyph_index, parent_glyphs,
679
+ parent_char_to_font, parent_glyph_to_font, charcode, flags,
680
+ charcode_error, glyph_error, glyph_seen_fonts, override );
676
681
if (was_found) {
677
682
return true ;
678
683
}
@@ -721,8 +726,7 @@ FT_UInt FT2Font::get_char_index(FT_ULong charcode, bool fallback = false)
721
726
ft_object = this ;
722
727
}
723
728
724
- // historically, get_char_index never raises a warning
725
- return ft_get_char_index_or_warn (ft_object->get_face (), charcode, false );
729
+ return FT_Get_Char_Index (ft_object->get_face (), charcode);
726
730
}
727
731
728
732
void FT2Font::get_width_height (long *width, long *height)
0 commit comments