const FFontData* FCompositeFontCache::GetBestMatchFontForAttributes(const FCachedTypefaceData* const InCachedTypefaceData, const TSet<FName>& InFontAttributes) { const FFontData* BestMatchFont = nullptr; int32 BestMatchCount = 0; const FTypeface& Typeface = InCachedTypefaceData->GetTypeface(); for (const FTypefaceEntry& TypefaceEntry : Typeface.Fonts) { const TSet<FName>& FontAttributes = GetFontAttributes(TypefaceEntry.Font); int32 MatchCount = 0; for (const FName& InAttribute : InFontAttributes) { if (FontAttributes.Contains(InAttribute)) { ++MatchCount; } } if (MatchCount > BestMatchCount || !BestMatchFont) { BestMatchFont = &TypefaceEntry.Font; BestMatchCount = MatchCount; } } return BestMatchFont; }
wxTextAttr::wxTextAttr(const wxColour& colText, const wxColour& colBack, const wxFont& font, wxTextAttrAlignment alignment): m_textAlignment(alignment), m_colText(colText), m_colBack(colBack) { Init(); if (m_colText.Ok()) m_flags |= wxTEXT_ATTR_TEXT_COLOUR; if (m_colBack.Ok()) m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR; if (alignment != wxTEXT_ALIGNMENT_DEFAULT) m_flags |= wxTEXT_ATTR_ALIGNMENT; GetFontAttributes(font); }
const FFontData& FCompositeFontCache::GetFontDataForCharacter(const FSlateFontInfo& InFontInfo, const TCHAR InChar, float& OutScalingFactor) { static const FFontData DummyFontData; auto FontDataHasCharacter = [&](const FFontData& InFontData) -> bool { #if WITH_FREETYPE TSharedPtr<FFreeTypeFace> FaceAndMemory = GetFontFace(InFontData); return FaceAndMemory.IsValid() && FT_Get_Char_Index(FaceAndMemory->GetFace(), InChar) != 0; #else // WITH_FREETYPE return false; #endif // WITH_FREETYPE }; const FCompositeFont* const ResolvedCompositeFont = InFontInfo.GetCompositeFont(); const FCachedTypefaceData* const CachedTypefaceData = GetCachedTypefaceForCharacter(ResolvedCompositeFont, InChar); if (CachedTypefaceData) { OutScalingFactor = CachedTypefaceData->GetScalingFactor(); const FCachedTypefaceData* const CachedDefaultTypefaceData = GetDefaultCachedTypeface(ResolvedCompositeFont); if (CachedDefaultTypefaceData) { const bool bIsDefaultTypeface = CachedTypefaceData == CachedDefaultTypefaceData; // Try to find the correct font from the typeface const FFontData* FoundFontData = CachedTypefaceData->GetFontData(InFontInfo.TypefaceFontName); if (FoundFontData && (bIsDefaultTypeface || FontDataHasCharacter(*FoundFontData))) { return *FoundFontData; } // Failing that, try and find a font by the attributes of the default font with the given name if (!bIsDefaultTypeface) { const FFontData* const FoundDefaultFontData = CachedDefaultTypefaceData->GetFontData(InFontInfo.TypefaceFontName); if (FoundDefaultFontData) { const TSet<FName>& DefaultFontAttributes = GetFontAttributes(*FoundDefaultFontData); FoundFontData = GetBestMatchFontForAttributes(CachedTypefaceData, DefaultFontAttributes); if (FoundFontData && FontDataHasCharacter(*FoundFontData)) { return *FoundFontData; } } } // Failing that, return the first font available (the "None" font) FoundFontData = CachedTypefaceData->GetFontData(NAME_None); if (FoundFontData && (bIsDefaultTypeface || FontDataHasCharacter(*FoundFontData))) { return *FoundFontData; } // Failing that, try again using the default font (as the sub-font may not have actually supported the character we needed) if (!bIsDefaultTypeface) { OutScalingFactor = CachedDefaultTypefaceData->GetScalingFactor(); // Try to find the correct font from the typeface FoundFontData = CachedDefaultTypefaceData->GetFontData(InFontInfo.TypefaceFontName); if (FoundFontData) { return *FoundFontData; } // Failing that, return the first font available (the "None" font) FoundFontData = CachedDefaultTypefaceData->GetFontData(NAME_None); if (FoundFontData) { return *FoundFontData; } } } else { // Try to find the correct font from the typeface const FFontData* FoundFontData = CachedTypefaceData->GetFontData(InFontInfo.TypefaceFontName); if (FoundFontData && FontDataHasCharacter(*FoundFontData)) { return *FoundFontData; } } } OutScalingFactor = 1.0f; return DummyFontData; }