Fix text words wrapping deadlock

#1093
This commit is contained in:
Wojtek Figat
2023-05-12 13:53:31 +02:00
parent b1b1b88982
commit d7327d62e2

View File

@@ -118,16 +118,10 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
tmpLine.FirstCharIndex = 0;
tmpLine.LastCharIndex = -1;
int32 lastWhitespaceIndex = INVALID_INDEX;
float lastWhitespaceX = 0;
int32 lastWrapCharIndex = INVALID_INDEX;
float lastWrapCharX = 0;
bool lastMoveLine = false;
int32 lastUpperIndex = INVALID_INDEX;
float lastUpperX = 0;
int32 lastUnderscoreIndex = INVALID_INDEX;
float lastUnderscoreX = 0;
// Process each character to split text into single lines
for (int32 currentIndex = 0; currentIndex < textLength;)
{
@@ -137,30 +131,14 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
// Cache current character
const Char currentChar = text[currentIndex];
// Check if character is a whitespace
const bool isWhitespace = StringUtils::IsWhitespace(currentChar);
if (isWhitespace)
{
// Cache line break point
lastWhitespaceIndex = currentIndex;
lastWhitespaceX = cursorX;
}
// Check if character is an upper case letter
const bool isUpper = StringUtils::IsUpper(currentChar);
if (isUpper && currentIndex != 0)
// Check if character can wrap words
const bool isWrapChar = !StringUtils::IsAlnum(currentChar) || isWhitespace || StringUtils::IsUpper(currentChar);
if (isWrapChar && currentIndex != 0)
{
lastUpperIndex = currentIndex;
lastUpperX = cursorX;
}
// Check if character is an underscore
const bool isUnderscore = currentChar == '_';
if (isUnderscore)
{
lastUnderscoreIndex = currentIndex;
lastUnderscoreX = cursorX;
lastWrapCharIndex = currentIndex;
lastWrapCharX = cursorX;
}
// Check if it's a newline character
@@ -197,41 +175,31 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
}
else if (layout.TextWrapping == TextWrapping::WrapWords)
{
// Move line but back to the last after-whitespace character
moveLine = true;
if (lastWhitespaceIndex != INVALID_INDEX)
{
cursorX = lastWhitespaceX;
tmpLine.LastCharIndex = lastWhitespaceIndex - 1;
nextCharIndex = currentIndex = lastWhitespaceIndex + 1;
}
else if (lastUpperIndex != INVALID_INDEX)
if (lastWrapCharIndex != INVALID_INDEX)
{
// Skip moving twice for the same character
if (outputLines.HasItems() && outputLines.Last().LastCharIndex == lastUpperIndex - 1)
if (outputLines.HasItems() && outputLines.Last().LastCharIndex == lastWrapCharIndex - 1)
{
currentIndex = nextCharIndex;
lastMoveLine = moveLine;
continue;
}
cursorX = lastUpperX;
tmpLine.LastCharIndex = lastUpperIndex - 1;
nextCharIndex = currentIndex = lastUpperIndex;
}
else if (lastUnderscoreIndex != INVALID_INDEX)
{
cursorX = lastUnderscoreX;
tmpLine.LastCharIndex = lastUnderscoreIndex - 2;
nextCharIndex = currentIndex = lastUnderscoreIndex + 1;
}
else
{
nextCharIndex = currentIndex;
// Skip moving twice for the same character
if (lastMoveLine)
break;
// Move line
const Char wrapChar = text[lastWrapCharIndex];
moveLine = true;
cursorX = lastWrapCharX;
if (StringUtils::IsWhitespace(wrapChar))
{
// Skip whitespaces
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
nextCharIndex = currentIndex = lastWrapCharIndex + 1;
}
else
{
tmpLine.LastCharIndex = lastWrapCharIndex - 1;
nextCharIndex = currentIndex = lastWrapCharIndex;
}
}
}
else if (layout.TextWrapping == TextWrapping::WrapChars)
@@ -260,16 +228,8 @@ void Font::ProcessText(const StringView& text, Array<FontLineCache>& outputLines
tmpLine.FirstCharIndex = currentIndex;
tmpLine.LastCharIndex = currentIndex - 1;
cursorX = 0;
lastWhitespaceIndex = INVALID_INDEX;
lastWhitespaceX = 0;
lastUpperIndex = INVALID_INDEX;
lastUpperX = 0;
lastUnderscoreIndex = INVALID_INDEX;
lastUnderscoreX = 0;
lastWrapCharIndex = INVALID_INDEX;
lastWrapCharX = 0;
previous.IsValid = false;
}