_font array storage

This commit is contained in:
2023-09-09 14:20:30 +03:00
parent 674d5b9709
commit 49497d1a78
2 changed files with 50 additions and 0 deletions

View File

@@ -13,7 +13,10 @@ Font::Font(FontAsset* parentAsset, float size)
: ManagedScriptingObject(SpawnParams(Guid::New(), Font::TypeInitializer))
, _asset(parentAsset)
, _size(size)
#if USE_ARRAY_CHARACTER_STORAGE
#else
, _characters(512)
#endif
{
_asset->_fonts.Add(this);
@@ -26,6 +29,12 @@ Font::Font(FontAsset* parentAsset, float size)
_ascender = Convert26Dot6ToRoundedPixel<int16>(face->size->metrics.ascender);
_descender = Convert26Dot6ToRoundedPixel<int16>(face->size->metrics.descender);
_lineGap = _height - _ascender + _descender;
#if USE_ARRAY_CHARACTER_STORAGE
_characters.SetCapacity(256);
_characters.Resize(256);
for (int i = 0; i < _characters.Count(); i++)
_characters[i].IsValid = false;
#endif
}
Font::~Font()
@@ -36,6 +45,32 @@ Font::~Font()
void Font::GetCharacter(Char c, FontCharacterEntry& result, bool enableFallback)
{
#if USE_ARRAY_CHARACTER_STORAGE
// Try to get the character or cache it if cannot be found
if (c >= _characters.Count())
{
// This thread race condition may happen in editor but in game we usually do all stuff with fonts on main thread (chars caching)
ScopeLock lock(_asset->Locker);
// Handle situation when more than one thread wants to get the same character
if (c >= _characters.Count())
{
int oldSize = _characters.Count();
int newSize = Math::Min(c + 64, 65536);
_characters.SetCapacity(newSize);
_characters.Resize(newSize);
for (int i = oldSize; i < newSize; i++)
_characters[i].IsValid = false;
}
}
result = _characters[c];
if (!result.IsValid)
{
// Create character cache
FontManager::AddNewEntry(this, c, _characters[c]);
result = _characters[c];
}
#else
// Try to get the character or cache it if cannot be found
if (!_characters.TryGet(c, result))
{
@@ -67,6 +102,7 @@ void Font::GetCharacter(Char c, FontCharacterEntry& result, bool enableFallback)
// Add to the dictionary
_characters.Add(c, result);
}
#endif
}
int32 Font::GetKerning(Char first, Char second) const
@@ -112,11 +148,19 @@ void Font::Invalidate()
{
ScopeLock lock(_asset->Locker);
#if USE_ARRAY_CHARACTER_STORAGE
for (int32 i = 0; i < _characters.Count(); i++)
{
FontManager::Invalidate(_characters[i]);
}
_characters.Clear();
#else
for (auto i = _characters.Begin(); i.IsNotEnd(); ++i)
{
FontManager::Invalidate(i->Value);
}
_characters.Clear();
#endif
}
void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines, const TextLayoutOptions& layout, Array<FontCharacterEntry>& characterEntries, Array<float>& characterKernings)

View File

@@ -15,6 +15,8 @@ struct FontTextureAtlasSlot;
// The default DPI that engine is using
#define DefaultDPI 96
#define USE_ARRAY_CHARACTER_STORAGE 1
/// <summary>
/// The text range.
/// </summary>
@@ -239,7 +241,11 @@ private:
int32 _descender;
int32 _lineGap;
bool _hasKerning;
#if USE_ARRAY_CHARACTER_STORAGE
Array<FontCharacterEntry> _characters;
#else
Dictionary<Char, FontCharacterEntry> _characters;
#endif
mutable Dictionary<uint32, int32> _kerningTable;
public: