117    if( aSearchLang.Lower() == aSupportedLang.Lower() )
 
  120    if( aSupportedLang.empty() )
 
  123    if( aSearchLang.empty() )
 
  126    wxArrayString supportedLangBits;
 
  127    wxStringSplit( aSupportedLang.Lower(), supportedLangBits, wxS( 
'-' ) );
 
  129    wxArrayString searhcLangBits;
 
  130    wxStringSplit( aSearchLang.Lower(), searhcLangBits, wxS( 
'-' ) );
 
  134    if( searhcLangBits.size() == 1 || supportedLangBits.size() == 1 )
 
  136        return searhcLangBits[0] == supportedLangBits[0];
 
 
  207                                            int& aFaceIndex, 
bool aBold, 
bool aItalic,
 
  208                                            const std::vector<wxString>* aEmbeddedFiles )
 
  217    if( aFontName.Lower().Contains( wxS( 
"bold" ) )       
 
  218        || aFontName.Lower().Contains( wxS( 
"heavy" ) )
 
  219        || aFontName.Lower().Contains( wxS( 
"black" ) )   
 
  220        || aFontName.Lower().Contains( wxS( 
"thick" ) )
 
  221        || aFontName.Lower().Contains( wxS( 
"dark" ) ) )
 
  226    FcConfig* 
config = FcConfigGetCurrent();
 
  230        for( 
const auto& file : *aEmbeddedFiles )
 
  232            FcConfigAppFontAddFile( 
config, (
const FcChar8*) file.c_str().AsChar() );
 
  236    wxString qualifiedFontName = aFontName;
 
  238    wxScopedCharBuffer 
const fcBuffer = qualifiedFontName.ToUTF8();
 
  240    FcPattern* pat = FcPatternCreate();
 
  243        FcPatternAddString( pat, FC_STYLE, (
const FcChar8*) 
"Bold" );
 
  246        FcPatternAddString( pat, FC_STYLE, (
const FcChar8*) 
"Italic" );
 
  248    FcPatternAddString( pat, FC_FAMILY, (FcChar8*) fcBuffer.data() );
 
  250    FcConfigSubstitute( 
config, pat, FcMatchPattern );
 
  251    FcDefaultSubstitute( pat );
 
  253    FcResult   r = FcResultNoMatch;
 
  254    FcPattern* font = FcFontMatch( 
config, pat, &r );
 
  260        FcChar8* file = 
nullptr;
 
  262        if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch )
 
  264            aFontFile = wxString::FromUTF8( (
char*) file );
 
  268            FcChar8* family = 
nullptr;
 
  269            FcChar8* style = 
nullptr;
 
  273            std::unordered_map<std::string, std::string> famStrings;
 
  278            if( FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch )
 
  280                FcPatternGetInteger( font, FC_INDEX, 0, &aFaceIndex );
 
  282                fontName = wxString::FromUTF8( (
char*) family );
 
  284                if( FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch )
 
  286                    styleStr = wxString::FromUTF8( (
char*) style );
 
  288                    if( !styleStr.IsEmpty() )
 
  290                        styleStr.Replace( 
' ', 
':' );
 
  291                        fontName += 
':' + styleStr;
 
  295                bool has_bold = 
false;
 
  296                bool has_ital = 
false;
 
  297                wxString lower_style = styleStr.Lower();
 
  299                if( lower_style.Contains( wxS( 
"thin" ) )
 
  300                         || lower_style.Contains( wxS( 
"light" ) )   
 
  301                         || lower_style.Contains( wxS( 
"regular" ) )
 
  302                         || lower_style.Contains( wxS( 
"roman" ) )
 
  303                         || lower_style.Contains( wxS( 
"book" ) ) )
 
  307                else if( lower_style.Contains( wxS( 
"medium" ) )
 
  308                         || lower_style.Contains( wxS( 
"semibold" ) )
 
  309                         || lower_style.Contains( wxS( 
"demibold" ) ) )
 
  313                else if( lower_style.Contains( wxS( 
"bold" ) )       
 
  314                         || lower_style.Contains( wxS( 
"heavy" ) )
 
  315                         || lower_style.Contains( wxS( 
"black" ) )   
 
  316                         || lower_style.Contains( wxS( 
"thick" ) )
 
  317                         || lower_style.Contains( wxS( 
"dark" ) ) )
 
  322                if( lower_style.Contains( wxS( 
"italic" ) )
 
  323                        || lower_style.Contains( wxS( 
"oblique" ) )
 
  324                        || lower_style.Contains( wxS( 
"slant" ) ) )
 
  329                for( 
auto const& [key, val] : famStrings )
 
  332                    searchFont = wxString::FromUTF8( (
char*) val.data() );
 
  334                    if( searchFont.Lower().StartsWith( aFontName.Lower() ) )
 
  336                        if( ( aBold && !has_bold ) && ( aItalic && !has_ital ) )
 
  338                        else if( aBold && !has_bold )
 
  340                        else if( aItalic && !has_ital )
 
  342                        else if( ( aBold != has_bold ) || ( aItalic != has_ital ) )
 
  353        FcPatternDestroy( font );
 
  359            s_reporter->Report( wxString::Format( 
_( 
"Error loading font '%s'." ),
 
  360                                                  qualifiedFontName ) );
 
  364        fontName.Replace( 
':', 
' ' );
 
  368        if( fontName.CmpNoCase( qualifiedFontName ) == 0 )
 
  371            s_reporter->Report( wxString::Format( 
_( 
"Font '%s' not found; substituting '%s'." ),
 
  372                                                  qualifiedFontName, fontName ) );
 
  375    FcPatternDestroy( pat );
 
 
  381                            const std::vector<wxString>* aEmbeddedFiles, 
bool aForce )
 
  389        FcConfig* 
config = FcConfigGetCurrent();
 
  393            for( 
const auto& file : *aEmbeddedFiles )
 
  395                FcConfigAppFontAddFile( 
config, (
const FcChar8*) file.c_str().AsChar() );
 
  399        FcPattern*   pat = FcPatternCreate();
 
  400        FcObjectSet* os = FcObjectSetBuild( FC_FAMILY, FC_FAMILYLANG, FC_STYLE, FC_LANG, FC_FILE,
 
  401                                            FC_OUTLINE, 
nullptr );
 
  402        FcFontSet*   fs = FcFontList( 
config, pat, os );
 
  404        for( 
int i = 0; fs && i < fs->nfont; ++i )
 
  406            FcPattern* font = fs->fonts[i];
 
  412            if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch
 
  413                && FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch
 
  414                && FcPatternGetLangSet( font, FC_LANG, 0, &langSet ) == FcResultMatch
 
  415                && FcPatternGetBool( font, FC_OUTLINE, 0, &outline ) == FcResultMatch )
 
  421                std::string    theFamily =
 
  432                static std::map<wxString, bool> availableLanguages;
 
  434                FcStrSet*  langStrSet = FcLangSetGetLangs( langSet );
 
  435                FcStrList* langStrList = FcStrListCreate( langStrSet );
 
  436                FcChar8*   langStr = FcStrListNext( langStrList );
 
  437                bool       langSupported = 
false;
 
  442                    langSupported = 
true;
 
  444                else while( langStr )
 
  446                    wxString langWxStr( 
reinterpret_cast<char *
>( langStr ) );
 
  448                    if( availableLanguages.find( langWxStr ) == availableLanguages.end() )
 
  450                        const wxLanguageInfo* langInfo = wxLocale::FindLanguageInfo( langWxStr );
 
  451                        bool  available = langInfo && wxLocale::IsAvailable( langInfo->Language );
 
  453                        availableLanguages[ langWxStr ] = available;
 
  456                    if( availableLanguages[ langWxStr ] )
 
  458                        langSupported = 
true;
 
  464                                    wxS( 
"Font '%s' language '%s' not supported by OS." ),
 
  465                                    theFamily, langWxStr );
 
  468                    langStr = FcStrListNext( langStrList );
 
  471                FcStrListDone( langStrList );
 
  472                FcStrSetDestroy( langStrSet );
 
  478                std::string theFile( 
reinterpret_cast<char *
>( file ) );
 
  479                std::string theStyle( 
reinterpret_cast<char *
>( style ) );
 
  480                FONTINFO    fontInfo( std::move( theFile ), std::move( theStyle ), theFamily );
 
  482                if( theFamily.length() > 0 && theFamily.front() == 
'.' )
 
  485                std::map<std::string, FONTINFO>::iterator it = 
m_fontInfoCache.find( theFamily );
 
  490                    it->second.Children().push_back( fontInfo );
 
  495            FcFontSetDestroy( fs );
 
  500    for( 
const std::pair<const std::string, FONTINFO>& entry : 
m_fontInfoCache )
 
  501        aFonts.push_back( entry.second.Family() );