From 54a7d43cf1285dd81450d6bf23cca76f02bd00ec Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sun, 24 Aug 2014 16:26:56 -0700 Subject: [PATCH] Use EnumFontFamiliesEx to try to find the correct match when fontconfig gives several options Fixes collection of ITC Cheltenham, ITC Tiffany, Zurich, Delicious, Jacoby, Segoe WP, Agilita LT, and a bunch of dumb improperly modified fonts I have lying around. Closes #1806. --- src/font_file_lister_fontconfig.cpp | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/font_file_lister_fontconfig.cpp b/src/font_file_lister_fontconfig.cpp index 6c8d413e1..72e010da7 100644 --- a/src/font_file_lister_fontconfig.cpp +++ b/src/font_file_lister_fontconfig.cpp @@ -16,6 +16,7 @@ #include "font_file_lister.h" +#include #include #ifdef __APPLE__ @@ -113,6 +114,38 @@ CollectionResult FontConfigFontFileLister::GetFontPaths(std::string const& facen auto match = matches->fonts[0]; +#ifdef _WIN32 + wxMemoryDC dc; + // Use EnumFontFamiliesEx to verify the match, as fontconfig sometimes gives + // us some incorrect matches along with the correct one + for (FcPattern *pat : boost::make_iterator_range(&matches->fonts[0], &matches->fonts[matches->nfont])) { + FcChar8 *fullname; + if (FcPatternGetString(pat, FC_FULLNAME, 0, &fullname) != FcResultMatch) + continue; + + LOGFONT lf = {0}; + lf.lfCharSet = DEFAULT_CHARSET; + wcsncpy(lf.lfFaceName, agi::charset::ConvertW((const char *)fullname).c_str(), 31); + + auto cb = [&](const LOGFONT *lf) { + auto face = agi::charset::ConvertW(lf->lfFaceName); + boost::to_lower(face); + return face == family; + }; + + using type = decltype(cb); + bool found = !EnumFontFamiliesEx(dc.GetHDC(), &lf, + [](const LOGFONT *lf, const TEXTMETRIC *, DWORD, LPARAM lParam) -> int { + return !(*reinterpret_cast(lParam))(lf); + }, (LPARAM)&cb, 0); + + if (found) { + match = pat; + break; + } + } +#endif + FcChar8 *file; if(FcPatternGetString(match, FC_FILE, 0, &file) != FcResultMatch) return ret;