#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Font.h"
#include "FontAsset.h"
struct TextRange;
class Font;
class FontAsset;
///
/// Defines a list of fonts that can be used as a fallback, ordered by priority.
///
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API FontFallbackList : public ManagedScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(FontFallbackList);
private:
Array _fontAssets;
// Cache fallback fonts of various sizes
Dictionary*> _cache;
public:
///
/// Initializes a new instance of the class.
///
/// The fallback font assets.
FontFallbackList(const Array& fonts);
///
/// Initializes a new instance of the class, exposed for C#.
///
/// The fallback font assets.
/// The new instance.
API_FUNCTION() FORCE_INLINE static FontFallbackList* Create(const Array& fonts) {
return New(fonts);
}
///
/// Get the parent assets of fallback fonts.
///
/// The font assets.
API_PROPERTY() FORCE_INLINE Array& GetFonts() {
return _fontAssets;
}
///
/// Set the fallback fonts.
///
/// The parent assets of the new fonts.
API_PROPERTY() FORCE_INLINE void SetFonts(const Array& val) {
_fontAssets = val;
}
///
/// Gets the fallback fonts with the given size.
///
/// The size.
/// The generated fonts.
API_FUNCTION() FORCE_INLINE Array& GetFontList(float size) {
Array* result;
if (_cache.TryGet(size, result)) {
return *result;
}
result = New>(_fontAssets.Count());
auto& arr = *result;
for (int32 i = 0; i < _fontAssets.Count(); i++)
{
arr.Add(_fontAssets[i]->CreateFont(size));
}
_cache[size] = result;
return *result;
}
///
/// Gets the index of the fallback font that should be used to render the char
///
/// The char.
/// The primary font.
/// The number to return if none of the fonts can render.
/// -1 if char can be rendered with primary font, index if it matches a fallback font.
API_FUNCTION() FORCE_INLINE int32 GetCharFallbackIndex(Char c, Font* primaryFont = nullptr, int32 missing = -1) {
if (primaryFont && primaryFont->GetAsset()->ContainsChar(c)) {
return -1;
}
int32 fontIndex = 0;
while (fontIndex < _fontAssets.Count() && _fontAssets[fontIndex] && !_fontAssets[fontIndex]->ContainsChar(c))
{
fontIndex++;
}
if (fontIndex < _fontAssets.Count()) {
return fontIndex;
}
return missing;
}
///
/// Checks if every font is properly loaded.
///
/// True if every font asset is non-null, otherwise false.
API_FUNCTION() FORCE_INLINE bool Verify() {
for (int32 i = 0; i < _fontAssets.Count(); i++)
{
if (!_fontAssets[i]) {
return false;
}
}
return true;
}
};