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