diff --git a/modules/juce_graphics/native/juce_Fonts_freetype.cpp b/modules/juce_graphics/native/juce_Fonts_freetype.cpp index a6448d1e72..63bde137f9 100644 --- a/modules/juce_graphics/native/juce_Fonts_freetype.cpp +++ b/modules/juce_graphics/native/juce_Fonts_freetype.cpp @@ -429,37 +429,52 @@ public: if (cache == nullptr) return {}; - FcPatternPtr pattern { FcPatternCreate() }; - + const auto makeBasicPattern = [&] { + FcPatternPtr pattern { FcPatternCreate() }; + + { + FcValue value{}; + value.type = FcTypeString; + value.u.s = unalignedPointerCast (ftFace->face->style_name); + FcPatternAdd (pattern.get(), FC_STYLE, value, FcFalse); + } + + { + const FcCharSetPtr charset { FcCharSetCreate() }; + for (const auto& character : text) + FcCharSetAddChar (charset.get(), (FcChar32) character); + FcPatternAddCharSet (pattern.get(), FC_CHARSET, charset.get()); + } + + if (language.isNotEmpty()) + { + const FcLangSetPtr langset { FcLangSetCreate() }; + FcLangSetAdd (langset.get(), unalignedPointerCast (language.toRawUTF8())); + FcPatternAddLangSet (pattern.get(), FC_LANG, langset.get()); + } + + return pattern; + }; + + const auto fallbackWithFamily = std::invoke ([&] + { + auto pattern = makeBasicPattern(); + FcValue value{}; value.type = FcTypeString; value.u.s = unalignedPointerCast (ftFace->face->family_name); FcPatternAddWeak (pattern.get(), FC_FAMILY, value, FcFalse); - } - { - FcValue value{}; - value.type = FcTypeString; - value.u.s = unalignedPointerCast (ftFace->face->style_name); - FcPatternAddWeak (pattern.get(), FC_STYLE, value, FcFalse); - } + return fromPattern (pattern.get()); + }); - { - const FcCharSetPtr charset { FcCharSetCreate() }; - for (const auto& character : text) - FcCharSetAddChar (charset.get(), (FcChar32) character); - FcPatternAddCharSet (pattern.get(), FC_CHARSET, charset.get()); - } + if (text.isEmpty() || fallbackWithFamily->getNominalGlyphForCodepoint (*text.getCharPointer()).has_value()) + return fallbackWithFamily; - if (language.isNotEmpty()) - { - const FcLangSetPtr langset { FcLangSetCreate() }; - FcLangSetAdd (langset.get(), unalignedPointerCast (language.toRawUTF8())); - FcPatternAddLangSet (pattern.get(), FC_LANG, langset.get()); - } - - return fromPattern (pattern.get()); + const auto fallbackWithoutFamily = fromPattern (makeBasicPattern().get()); + jassert (fallbackWithoutFamily->getNominalGlyphForCodepoint (*text.getCharPointer()).has_value()); + return fallbackWithoutFamily; #else // Font substitution will not work unless fontconfig is enabled. jassertfalse;