From 42c042c249c384223b17b0fe523197e4594eb195 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 12 May 2023 13:53:31 +0200 Subject: [PATCH] Fix text words wrapping deadlock #1093 --- Source/Engine/Render2D/Font.cpp | 92 ++++++++++----------------------- 1 file changed, 26 insertions(+), 66 deletions(-) diff --git a/Source/Engine/Render2D/Font.cpp b/Source/Engine/Render2D/Font.cpp index b026e2d80..c36f40515 100644 --- a/Source/Engine/Render2D/Font.cpp +++ b/Source/Engine/Render2D/Font.cpp @@ -118,16 +118,10 @@ void Font::ProcessText(const StringView& text, Array& 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& 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& 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& 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; }