#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; } };