Пример #1
0
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;
}