_font whiteline skip fix
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user