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;