Skip to content

Commit df4e1ee

Browse files
authored
Merge pull request #3463 from florianessl/fix/DetectBrokenFonts
Improve heuristics check to detect broken RM2000-based fonts
2 parents 14723d3 + 08223c3 commit df4e1ee

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

src/font.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
# include FT_BITMAP_H
3838
# include FT_MODULE_H
3939
# include FT_TRUETYPE_TABLES_H
40+
# include FT_FONT_FORMATS_H
4041
#endif
4142

4243
#ifdef HAVE_HARFBUZZ
@@ -315,6 +316,32 @@ FTFont::FTFont(Filesystem_Stream::InputStream is, int size, bool bold, bool ital
315316
if (!strcmp(face->family_name, "RM2000") || !strcmp(face->family_name, "RMG2000")) {
316317
// Workaround for bad kerning in RM2000 and RMG2000 fonts
317318
rm2000_workaround = true;
319+
} else if (!FT_HAS_COLOR(face) && FT_HAS_FIXED_SIZES(face)) {
320+
auto font_format = FT_Get_Font_Format(face);
321+
if (!strcmp(font_format, "Windows FNT")) {
322+
static constexpr std::array<std::pair<char32_t, int>, 4> glyphs = {{
323+
{ 'h', 6},
324+
{ 'l', 4},
325+
{ 'I', 15},
326+
{ ' ', 15}
327+
}};
328+
// Check some metrics to identify custom fonts which were based
329+
// on the broken RM2000 font & thus also need the same workaround
330+
rm2000_workaround = true;
331+
for (size_t i = 0; i < glyphs.size(); ++i) {
332+
auto glyph_index = FT_Get_Char_Index(face, std::get<0>(glyphs[i]));
333+
334+
if (glyph_index == 0 || FT_Load_Glyph(face, glyph_index, FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) != FT_Err_Ok) {
335+
rm2000_workaround = false;
336+
break;
337+
}
338+
auto advance_x = Utils::RoundTo<int>(face->glyph->advance.x / 64.0);
339+
if (advance_x != std::get<1>(glyphs[i])) {
340+
rm2000_workaround = false;
341+
break;
342+
}
343+
}
344+
}
318345
}
319346
}
320347

0 commit comments

Comments
 (0)