diff --git a/Source/Engine/Render2D/Font.h b/Source/Engine/Render2D/Font.h index 3f42fd396..d68f497d6 100644 --- a/Source/Engine/Render2D/Font.h +++ b/Source/Engine/Render2D/Font.h @@ -10,6 +10,7 @@ #include "TextLayoutOptions.h" class FontAsset; +struct FontTextureAtlasSlot; // The default DPI that engine is using #define DefaultDPI 96 @@ -204,6 +205,11 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry); /// 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; }; template<> diff --git a/Source/Engine/Render2D/FontManager.cpp b/Source/Engine/Render2D/FontManager.cpp index 578e28409..bb7edf974 100644 --- a/Source/Engine/Render2D/FontManager.cpp +++ b/Source/Engine/Render2D/FontManager.cpp @@ -242,7 +242,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry) // Find atlas for the character texture int32 atlasIndex = 0; - const FontTextureAtlas::Slot* slot = nullptr; + const FontTextureAtlasSlot* slot = nullptr; for (; atlasIndex < Atlases.Count(); atlasIndex++) { // Add the character to the texture @@ -283,6 +283,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry) entry.UV.Y = static_cast(slot->Y + padding); entry.UVSize.X = static_cast(slot->Width - 2 * padding); entry.UVSize.Y = static_cast(slot->Height - 2 * padding); + entry.Slot = slot; return false; } diff --git a/Source/Engine/Render2D/FontTextureAtlas.cpp b/Source/Engine/Render2D/FontTextureAtlas.cpp index 972fe1bcb..724040157 100644 --- a/Source/Engine/Render2D/FontTextureAtlas.cpp +++ b/Source/Engine/Render2D/FontTextureAtlas.cpp @@ -40,7 +40,7 @@ void FontTextureAtlas::Init(uint32 width, uint32 height) uint32 padding = GetPaddingAmount(); _width = width; _height = height; - _root = New(padding, padding, _width - padding, _height - padding); + _root = New(padding, padding, _width - padding, _height - padding); _isDirty = false; // Reserve upload data memory @@ -48,19 +48,19 @@ void FontTextureAtlas::Init(uint32 width, uint32 height) Platform::MemoryClear(_data.Get(), _data.Capacity()); } -FontTextureAtlas::Slot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data) +FontTextureAtlasSlot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data) { // Check for invalid size if (targetWidth == 0 || targetHeight == 0) return nullptr; // Try to find slot for the texture - Slot* slot = nullptr; + FontTextureAtlasSlot* slot = nullptr; const uint32 padding = GetPaddingAmount(); const uint32 allPadding = padding * 2; for (int32 i = 0; i < _freeSlots.Count(); i++) { - Slot* e = _freeSlots[i]; + FontTextureAtlasSlot* e = _freeSlots[i]; if (e->Width == targetWidth + allPadding && e->Height == targetHeight + allPadding) { slot = e; @@ -89,7 +89,7 @@ FontTextureAtlas::Slot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 ta bool FontTextureAtlas::Invalidate(uint32 x, uint32 y, uint32 width, uint32 height) { - Slot* slot = invalidate(_root, x, y, width, height); + FontTextureAtlasSlot* slot = invalidate(_root, x, y, width, height); if (slot) { _freeSlots.Add(slot); @@ -97,7 +97,7 @@ bool FontTextureAtlas::Invalidate(uint32 x, uint32 y, uint32 width, uint32 heigh return slot != nullptr; } -void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array& data) +void FontTextureAtlas::CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array& data) { uint8* start = &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel]; const uint32 padding = GetPaddingAmount(); @@ -148,6 +148,15 @@ void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array& dat } } +byte* FontTextureAtlas::GetSlotData(const FontTextureAtlasSlot* slot, uint32& width, uint32& height, uint32& stride) +{ + const uint32 padding = GetPaddingAmount(); + width = slot->Width - padding * 2; + height = slot->Height - padding * 2; + stride = _width * _bytesPerPixel; + return &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel]; +} + void FontTextureAtlas::copyRow(const RowData& copyRowData) const { const byte* data = copyRowData.SrcData; @@ -238,13 +247,13 @@ bool FontTextureAtlas::HasDataSyncWithGPU() const return _isDirty == false; } -FontTextureAtlas::Slot* FontTextureAtlas::invalidate(Slot* parent, uint32 x, uint32 y, uint32 width, uint32 height) +FontTextureAtlasSlot* FontTextureAtlas::invalidate(FontTextureAtlasSlot* parent, uint32 x, uint32 y, uint32 width, uint32 height) { if (parent->X == x && parent->Y == y && parent->Width == width && parent->Height == height) { return parent; } - Slot* result = parent->Left ? invalidate(parent->Left, x, y, width, height) : nullptr; + FontTextureAtlasSlot* result = parent->Left ? invalidate(parent->Left, x, y, width, height) : nullptr; if (result) return result; return parent->Right ? invalidate(parent->Right, x, y, width, height) : nullptr; diff --git a/Source/Engine/Render2D/FontTextureAtlas.h b/Source/Engine/Render2D/FontTextureAtlas.h index 5d9fa43dd..4bffdaf58 100644 --- a/Source/Engine/Render2D/FontTextureAtlas.h +++ b/Source/Engine/Render2D/FontTextureAtlas.h @@ -8,6 +8,21 @@ #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. /// @@ -29,21 +44,6 @@ private: public: - /// - /// Contains information about single texture atlas slot. - /// - struct Slot : RectPack - { - Slot(uint32 x, uint32 y, uint32 width, uint32 height) - : RectPack(x, y, width, height) - { - } - - void OnInsert() - { - } - }; - /// /// Describes how to handle texture atlas padding /// @@ -74,8 +74,8 @@ private: uint32 _bytesPerPixel; PaddingStyle _paddingStyle; bool _isDirty; - Slot* _root; - Array _freeSlots; + FontTextureAtlasSlot* _root; + Array _freeSlots; public: @@ -157,7 +157,7 @@ public: /// Height of the entry. /// The data. /// The atlas slot occupied by the new entry. - Slot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data); + FontTextureAtlasSlot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data); /// /// Invalidates the cached dynamic entry from the atlas. @@ -174,7 +174,17 @@ public: /// /// The slot. /// The data. - void CopyDataIntoSlot(const Slot* slot, const Array& 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.). @@ -204,7 +214,7 @@ public: private: - Slot* invalidate(Slot* parent, uint32 x, uint32 y, uint32 width, uint32 height); + 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;