// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Math/Vector2.h" #include "Engine/Content/Assets/Texture.h" #include "Engine/Graphics/Textures/GPUTexture.h" #include "Engine/Utilities/RectPack.h" /// /// Contains information about single texture atlas slot. /// struct FontTextureAtlasSlot : RectPack { FontTextureAtlasSlot(uint32 x, uint32 y, uint32 width, uint32 height) : RectPack(x, y, width, height) { } void OnInsert() { } }; /// /// Texture resource that contains an atlas of cached font glyphs. /// API_CLASS(NoSpawn) class FLAXENGINE_API FontTextureAtlas : public Texture { DECLARE_BINARY_ASSET_HEADER(FontTextureAtlas, TexturesSerializedVersion); private: struct RowData { const byte* SrcData; uint8* DstData; uint32 SrcRow; uint32 DstRow; uint32 RowWidth; uint32 SrcTextureWidth; uint32 DstTextureWidth; }; public: /// /// Describes how to handle texture atlas padding /// enum PaddingStyle { /// /// Don't pad the atlas. /// NoPadding, /// /// Dilate the texture by one pixel to pad the atlas. /// DilateBorder, /// /// One pixel uniform padding border filled with zeros. /// PadWithZero, }; private: Array _data; uint32 _width; uint32 _height; PixelFormat _format; uint32 _bytesPerPixel; PaddingStyle _paddingStyle; bool _isDirty; FontTextureAtlasSlot* _root; Array _freeSlots; public: /// /// Initializes a new instance of the class. /// /// The texture pixels format. /// The texture entries padding style. /// The atlas index. FontTextureAtlas(PixelFormat format, PaddingStyle paddingStyle, int32 index); public: /// /// Gets the atlas width. /// FORCE_INLINE uint32 GetWidth() const { return _width; } /// /// Gets the atlas height. /// FORCE_INLINE uint32 GetHeight() const { return _height; } /// /// Gets the atlas size. /// FORCE_INLINE Float2 GetSize() const { return Float2(static_cast(_width), static_cast(_height)); } /// /// Determines whether this atlas is dirty and data need to be flushed. /// FORCE_INLINE bool IsDirty() const { return _isDirty; } /// /// Gets padding style for textures in the atlas. /// FORCE_INLINE PaddingStyle GetPaddingStyle() const { return _paddingStyle; } /// /// Gets amount of pixels to pad textures inside an atlas. /// uint32 GetPaddingAmount() const; public: /// /// Setups the atlas after creation. /// /// The pixel format. /// The padding style. void Setup(PixelFormat format, PaddingStyle paddingStyle); /// /// Initializes the atlas. /// /// The width. /// The height. void Init(uint32 width, uint32 height); /// /// Adds the new entry to the atlas /// /// Width of the entry. /// Height of the entry. /// The data. /// The atlas slot occupied by the new entry. FontTextureAtlasSlot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data); /// /// Invalidates the cached dynamic entry from the atlas. /// /// The slot location (X coordinate in atlas pixels). /// The slot location (Y coordinate in atlas pixels). /// The slot width (size in atlas pixels). /// The slot height (size in atlas pixels). /// True if slot has been freed, otherwise false. bool Invalidate(uint32 x, uint32 y, uint32 width, uint32 height); /// /// Copies the data into the slot. /// /// The slot. /// The data. void CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array& data); /// /// Returns glyph's bitmap data of the slot. /// /// The slot in atlas. /// The width of the slot. /// The height of the slot. /// The stride of the slot. /// The pointer to the bitmap data of the given slot. byte* GetSlotData(const FontTextureAtlasSlot* slot, uint32& width, uint32& height, uint32& stride); /// /// Clears this atlas entries data (doesn't change size/texture etc.). /// void Clear(); /// /// Disposed whole atlas data (texture, nodes etc.). /// void Dispose(); /// /// Flushes this atlas data to the GPU /// void Flush(); /// /// Ensures that texture has been created for that atlas. /// void EnsureTextureCreated() const; /// /// Determines whether atlas has data synchronized with the GPU. /// /// true if atlas has data synchronized with the GPU; otherwise, false. bool HasDataSyncWithGPU() const; private: FontTextureAtlasSlot* invalidate(FontTextureAtlasSlot* parent, uint32 x, uint32 y, uint32 width, uint32 height); void markAsDirty(); void copyRow(const RowData& copyRowData) const; void zeroRow(const RowData& copyRowData) const; protected: // [Texture] void unload(bool isReloading) override; };