void UFont::Serialize( FArchive& Ar ) { Super::Serialize( Ar ); Ar << CharRemap; // Update any composite font data to use bulk data with us as its outer if( Ar.UE4Ver() < VER_UE4_SLATE_BULK_FONT_DATA ) { auto UpgradeFontDataToBulk = [this](FFontData& InFontData) { if( InFontData.FontData_DEPRECATED.Num() > 0 ) { UFontBulkData* FontBulkData = NewObject<UFontBulkData>(this); FontBulkData->Initialize(InFontData.FontData_DEPRECATED.GetData(), InFontData.FontData_DEPRECATED.Num()); InFontData.BulkDataPtr = FontBulkData; InFontData.FontData_DEPRECATED.Empty(); } }; for( FTypefaceEntry& TypefaceEntry : CompositeFont.DefaultTypeface.Fonts ) { UpgradeFontDataToBulk(TypefaceEntry.Font); } for( FCompositeSubFont& SubFont : CompositeFont.SubTypefaces ) { for( FTypefaceEntry& TypefaceEntry : SubFont.Typeface.Fonts ) { UpgradeFontDataToBulk(TypefaceEntry.Font); } } } }
TSharedPtr<const FCompositeFont> FLegacySlateFontInfoCache::GetSystemFont() { if (!SystemFont.IsValid()) { TArray<uint8> FontBytes = FPlatformMisc::GetSystemFontBytes(); UFontBulkData* FontBulkData = NewObject<UFontBulkData>(); FontBulkData->Initialize(FontBytes.GetData(), FontBytes.Num()); SystemFont = MakeShareable(new FStandaloneCompositeFont(NAME_None, TEXT("DefaultSystemFont"), FontBulkData, EFontHinting::Default)); } return SystemFont; }
const FFontData& FLegacySlateFontInfoCache::GetLastResortFont() { // GetLastResortFont is called directly from the font cache, so may be called from multiple threads at once FScopeLock Lock(&LastResortFontCS); if (!LastResortFont.IsValid()) { const FString LastResortFontPath = FPaths::EngineContentDir() / TEXT("Slate/Fonts/LastResort.ttf"); UFontBulkData* FontBulkData = NewObject<UFontBulkData>(); FontBulkData->Initialize(LastResortFontPath); LastResortFont = MakeShareable(new FFontData(LastResortFontPath, FontBulkData, EFontHinting::Default)); } return *LastResortFont; }
const FFontData& FLegacySlateFontInfoCache::GetFallbackFontData() { // GetFallbackFontData is called directly from the font cache, so may be called from multiple threads at once FScopeLock Lock(&FallbackFontDataCS); // The fallback font can change if the active culture is changed const int32 CurrentHistoryVersion = FTextLocalizationManager::Get().GetTextRevision(); if (!FallbackFontData.IsValid() || FallbackFontDataHistoryVersion != CurrentHistoryVersion) { FallbackFontDataHistoryVersion = CurrentHistoryVersion; const FString FallbackFontPath = FPaths::EngineContentDir() / TEXT("Slate/Fonts/") / (NSLOCTEXT("Slate", "FallbackFont", "DroidSansFallback").ToString() + TEXT(".ttf")); UFontBulkData* FontBulkData = NewObject<UFontBulkData>(); FontBulkData->Initialize(FallbackFontPath); FallbackFontData = MakeShareable(new FFontData(FallbackFontPath, FontBulkData, EFontHinting::Default)); } return *FallbackFontData; }
TSharedPtr<const FCompositeFont> FLegacySlateFontInfoCache::GetCompositeFont(const FName& InLegacyFontName, const EFontHinting InLegacyFontHinting) { if (InLegacyFontName.IsNone()) { return nullptr; } FString LegacyFontPath = InLegacyFontName.ToString(); // Work out what the given path is supposed to be relative to if (!FPaths::FileExists(LegacyFontPath)) { // UMG assets specify the path either relative to the game or engine content directories - test both LegacyFontPath = FPaths::GameContentDir() / InLegacyFontName.ToString(); if (!FPaths::FileExists(LegacyFontPath)) { LegacyFontPath = FPaths::EngineContentDir() / InLegacyFontName.ToString(); if (!FPaths::FileExists(LegacyFontPath)) { // Missing font file - just use what we were given LegacyFontPath = InLegacyFontName.ToString(); } } } const FLegacyFontKey LegacyFontKey(*LegacyFontPath, InLegacyFontHinting); { TSharedPtr<const FCompositeFont>* const ExistingCompositeFont = LegacyFontNameToCompositeFont.Find(LegacyFontKey); if(ExistingCompositeFont) { return *ExistingCompositeFont; } } UFontBulkData* FontBulkData = NewObject<UFontBulkData>(); FontBulkData->Initialize(LegacyFontPath); TSharedRef<const FCompositeFont> NewCompositeFont = MakeShareable(new FStandaloneCompositeFont(NAME_None, LegacyFontPath, FontBulkData, InLegacyFontHinting)); LegacyFontNameToCompositeFont.Add(LegacyFontKey, NewCompositeFont); return NewCompositeFont; }
const FFontData& FLegacySlateFontInfoCache::GetFallbackFont() { const FName FallbackFontName = *(FPaths::EngineContentDir() / TEXT("Slate/Fonts/") / (NSLOCTEXT("Slate", "FallbackFont", "DroidSansFallback").ToString() + TEXT(".ttf"))); // GetFallbackFont is called directly from the font cache, so may be called from multiple threads at once FScopeLock Lock(&FallbackFontCS); { TSharedPtr<const FFontData>* const ExistingFallbackFont = FallbackFonts.Find(FallbackFontName); if(ExistingFallbackFont) { return **ExistingFallbackFont; } } const FString FallbackFontPath = FallbackFontName.ToString(); UFontBulkData* FontBulkData = NewObject<UFontBulkData>(); FontBulkData->Initialize(FallbackFontPath); TSharedRef<const FFontData> NewFallbackFont = MakeShareable(new FFontData(FallbackFontPath, FontBulkData, EFontHinting::Default)); FallbackFonts.Add(FallbackFontName, NewFallbackFont); return *NewFallbackFont; }