_font whiteline skip fix

This commit is contained in:
2024-03-22 20:31:09 +02:00
parent f7677b6ab8
commit d32f690eac
2 changed files with 71 additions and 25 deletions

View File

@@ -61,14 +61,37 @@ void Font::GetCharacter(Char c, FontCharacterEntry& result, bool enableFallback)
Platform::MemoryClear(&_characters.Get()[oldSize], (newSize - oldSize) * sizeof(FontCharacterEntry*));
}
}
FontCharacterEntry* entry = _characters[c];
if (entry == nullptr)
{
ScopeLock lock(_asset->Locker);
// Create character cache
entry = New<FontCharacterEntry>();
FontManager::AddNewEntry(this, c, *entry);
_characters[c] = entry;
}
// Try to use fallback font if character is missing
if (enableFallback)
{
ScopeLock lock(_asset->Locker);
if (!_asset->ContainsChar(c))
{
for (int32 fallbackIndex = 0; fallbackIndex < FallbackFonts.Count(); fallbackIndex++)
{
FontAsset* fallbackFont = FallbackFonts.Get()[fallbackIndex].Get();
if (fallbackFont && fallbackFont->ContainsChar(c))
{
fallbackFont->CreateFont(GetSize())->GetCharacter(c, result, enableFallback);
return;
}
}
}
}
result = *entry;
#else
// Try to get the character or cache it if cannot be found
@@ -173,7 +196,7 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
if (textLength == 0)
return;
int32 cursorX = 0;
FontLineCharacterCache characterCache;
Char previous = 0;
float scale = layout.Scale / FontManager::FontScale;
int32 boundsWidth = (int32)Math::Ceil(layout.Bounds.GetWidth() / scale);
@@ -188,17 +211,59 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
bool lastMoveLine = false;
int32 newlinesCount = 0;
if (characterEntries != NULL)
{
characterEntries->Resize(textLength, false);
for (int32 currentIndex = 0; currentIndex < textLength; currentIndex++)
{
const Char currentChar = text[currentIndex];
FontLineCharacterCache& characterCache = characterEntries->At(currentIndex);
GetCharacter(currentChar, characterCache.Entry);
characterCache.IsWhitespace = StringUtils::IsWhitespace(currentChar);
// Get kerning
if (!characterCache.IsWhitespace && previous != 0)
characterCache.Kerning = GetKerning(previous, currentChar);
else
characterCache.Kerning = 0;
previous = currentChar;
}
}
// Process each character to split text into single lines
for (int32 currentIndex = 0; currentIndex < textLength;)
{
bool moveLine = false;
int32 xAdvance = 0;
int32 xAdvance;
bool isWhitespace;
int32 nextCharIndex = currentIndex + 1;
// Cache current character
if (currentIndex == 96)
currentIndex = currentIndex;
const Char currentChar = text[currentIndex];
characterCache.IsWhitespace = StringUtils::IsWhitespace(currentChar);
const bool isWrapChar = characterCache.IsWhitespace || StringUtils::IsUpper(currentChar) || !StringUtils::IsAlnum(currentChar);
if (characterEntries != NULL)
{
FontLineCharacterCache& characterCache = characterEntries->At(currentIndex);
isWhitespace = characterCache.IsWhitespace;
xAdvance = characterCache.Kerning + characterCache.Entry.AdvanceX;
}
else
{
FontCharacterEntry entry;
GetCharacter(currentChar, entry);
isWhitespace = StringUtils::IsWhitespace(currentChar);
int32 kerning;
if (!isWhitespace && previous != 0)
kerning = GetKerning(previous, currentChar);
else
kerning = 0;
xAdvance = kerning + entry.AdvanceX;
}
const bool isWrapChar = isWhitespace || StringUtils::IsUpper(currentChar) || !StringUtils::IsAlnum(currentChar);
// Check if character can wrap words
if (isWrapChar && currentIndex != 0)
@@ -218,21 +283,6 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
}
else
{
// Get character entry
GetCharacter(currentChar, characterCache.Entry);
// Get kerning
if (!characterCache.IsWhitespace && previous != 0)
{
characterCache.Kerning = GetKerning(previous, currentChar);
}
else
{
characterCache.Kerning = 0;
}
previous = currentChar;
xAdvance = (characterCache.Kerning + characterCache.Entry.AdvanceX);
// Check if character fits the line or skip wrapping
if (cursorX + xAdvance <= boundsWidth || layout.TextWrapping == TextWrapping::NoWrap)
{
@@ -274,10 +324,6 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
if (lastMoveLine)
break;
}
// Avoid adding same character entries again if we skipped characters earlier
if (characterEntries != nullptr && characterEntries->Count() == currentIndex - newlinesCount)
characterEntries->Add(characterCache);
}
// Check if move to another line

View File

@@ -1411,7 +1411,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
for (int32 charIndex = line.FirstCharIndex; charIndex < line.LastCharIndex; charIndex++)
{
const Char c = text[charIndex];
const FontLineCharacterCache& characterCache = CharacterCache[entryIndex];
const FontLineCharacterCache& characterCache = CharacterCache[charIndex];
const FontCharacterEntry& entry = characterCache.Entry;
pointer += advanceDirX * (float)characterCache.Kerning;