// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Engine/Content/BinaryAsset.h" #include "Engine/Content/AssetReference.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Core/Math/Vector2.h" class Font; class FontManager; struct FontTextureAtlasSlot; typedef struct FT_FaceRec_* FT_Face; // Font glyph metrics: // // xmin xmax // | | // |<-------- width -------->| // | | // | +-------------------------+----------------- ymax // | | ggggggggg ggggg | ^ ^ // | | g:::::::::ggg::::g | | | // | | g:::::::::::::::::g | | | // | | g::::::ggggg::::::gg | | | // | | g:::::g g:::::g | | | // offsetX -|-------->| g:::::g g:::::g | offsetY | // | | g:::::g g:::::g | | | // | | g::::::g g:::::g | | | // | | g:::::::ggggg:::::g | | | // | | g::::::::::::::::g | | height // | | gg::::::::::::::g | | | // baseline ---*---------|---- gggggggg::::::g-----*-------- | // / | | g:::::g | | // origin | | gggggg g:::::g | | // | | g:::::gg gg:::::g | | // | | g::::::ggg:::::::g | | // | | gg:::::::::::::g | | // | | ggg::::::ggg | | // | | gggggg | v // | +-------------------------+----------------- ymin // | | // |------------- advanceX ----------->| /// /// The cached font character entry (read for rendering and further processing). /// API_STRUCT(NoDefault) struct FLAXENGINE_API FontCharacterEntry { DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry); /// /// The character represented by this entry. /// API_FIELD() Char Character; /// /// True if entry is valid, otherwise false. /// API_FIELD() bool IsValid = false; /// /// The index to a specific texture in the font cache. /// API_FIELD() byte TextureIndex; /// /// The left bearing expressed in integer pixels. /// API_FIELD() int16 OffsetX; /// /// The top bearing expressed in integer pixels. /// API_FIELD() int16 OffsetY; /// /// The amount to advance in X before drawing the next character in a string. /// API_FIELD() int16 AdvanceX; /// /// The distance from baseline to glyph top most point. /// API_FIELD() int16 BearingY; /// /// The height in pixels of the glyph. /// API_FIELD() int16 Height; /// /// The start location of the character in the texture (in texture coordinates space). /// API_FIELD() Float2 UV; /// /// The size the character in the texture (in texture coordinates space). /// API_FIELD() Float2 UVSize; /// /// The slot in texture atlas, containing the pixel data of the glyph. /// API_FIELD() const FontTextureAtlasSlot* Slot; /// /// The owner font. /// API_FIELD() const class Font* Font; }; template<> struct TIsPODType { enum { Value = true }; }; /// /// The font hinting used when rendering characters. /// API_ENUM() enum class FontHinting : byte { /// /// Use the default hinting specified in the font. /// Default, /// /// Force the use of an automatic hinting algorithm (over the fonts native hinter). /// Auto, /// /// Force the use of an automatic light hinting algorithm, optimized for non-monochrome displays. /// AutoLight, /// /// Force the use of an automatic hinting algorithm optimized for monochrome displays. /// Monochrome, /// /// Do not use hinting. This generally generates 'blurrier' bitmap glyphs when the glyphs are rendered in any of the anti-aliased modes. /// None, }; /// /// The font flags used when rendering characters. /// API_ENUM(Attributes="Flags") enum class FontFlags : byte { /// /// No options. /// None = 0, /// /// Enables using anti-aliasing for font characters. Otherwise font will use the monochrome data. /// AntiAliasing = 1, /// /// Enables artificial embolden effect. /// Bold = 2, /// /// Enables slant effect, emulating italic style. /// Italic = 4, }; /// /// The font rasterization mode. /// API_ENUM() enum class FontRasterMode : byte { /// /// Use the default FreeType rasterizer to render font atlases. /// Bitmap, /// /// Use the Multi-channel Signed Distance Field (MSDF) generator to render font atlases. Need to be rendered with a compatible material. /// MSDF, }; DECLARE_ENUM_OPERATORS(FontFlags); /// /// The font asset options. /// API_STRUCT() struct FontOptions { DECLARE_SCRIPTING_TYPE_MINIMAL(FontOptions); /// /// The font hinting used when rendering characters. /// API_FIELD() FontHinting Hinting; /// /// The flags. /// API_FIELD() FontFlags Flags; /// /// The font rasterization mode. /// API_FIELD() FontRasterMode RasterMode; /// /// The font size used when generating MSDF font atlases. /// API_FIELD() float MSDFSize; }; /// /// Font asset contains glyph collection and cached data used to render text. /// API_CLASS(NoSpawn) class FLAXENGINE_API FontAsset : public BinaryAsset { DECLARE_BINARY_ASSET_HEADER(FontAsset, 5); friend Font; private: FT_Face _face; FontOptions _options; BytesContainer _fontFile; Array> _fonts; Dictionary, FontCharacterEntry> _characterCache; AssetReference _virtualBold; AssetReference _virtualItalic; AssetReference _virtualRasterMode; public: /// /// Gets the font family name. /// API_PROPERTY() String GetFamilyName() const; /// /// Gets the font style name. /// API_PROPERTY() String GetStyleName() const; /// /// Gets FreeType face handle. /// FORCE_INLINE FT_Face GetFTFace() const { return _face; } /// /// Gets the font options. /// API_PROPERTY() const FontOptions& GetOptions() const { return _options; } /// /// Gets the font style flags. /// API_PROPERTY() FontFlags GetStyle() const; /// /// Sets the font options. /// API_PROPERTY() void SetOptions(const FontOptions& value); public: /// /// Creates the font object of given characters size. /// /// The font characters size. /// The created font object. API_FUNCTION() Font* CreateFont(float size); /// /// Gets the font with bold style. Returns itself or creates a new virtual font asset using this font but with bold option enabled. /// /// The virtual font or this. API_FUNCTION() FontAsset* GetBold(); /// /// Gets the font with italic style. Returns itself or creates a new virtual font asset using this font but with italic option enabled. /// /// The virtual font or this. API_FUNCTION() FontAsset* GetItalic(); /// /// Gets the different rasterization mode of the font. Returns itself or creates a new virtual font asset using this font but rasterized with the specified mode. /// /// The virtual font or this. API_FUNCTION() FontAsset* GetRasterMode(FontRasterMode rasterMode); /// /// Initializes the font with a custom font file data. /// /// Raw bytes with font file data. /// True if cannot init, otherwise false. API_FUNCTION() bool Init(const BytesContainer& fontFile); /// /// Check if the font contains the glyph of a char. /// /// The char to test. /// True if the font contains the glyph of the char, otherwise false. API_FUNCTION() bool ContainsChar(Char c) const; /// /// Invalidates all cached dynamic font atlases using this font. Can be used to reload font characters after changing font asset options. /// API_FUNCTION() void Invalidate(); public: // [BinaryAsset] uint64 GetMemoryUsage() const override; #if USE_EDITOR bool Save(const StringView& path = StringView::Empty) override; #endif protected: // [BinaryAsset] bool init(AssetInitData& initData) override; LoadResult load() override; void unload(bool isReloading) override; AssetChunksFlag getChunksToPreload() const override; private: bool Init(); };