From 76974578b313a1097acf4308f541c339ff40fdea Mon Sep 17 00:00:00 2001 From: mix <167040362+mixiate@users.noreply.github.com> Date: Sat, 22 Feb 2025 13:38:06 +0000 Subject: [PATCH] Fix #23867: Crash when viewing 2 line 3D signs with 16 spaces --- .../paint/tile_element/Paint.LargeScenery.cpp | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp index e466b25436..b8c74bf5c9 100644 --- a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp @@ -262,41 +262,34 @@ static void PaintLargeScenery3DText( CodepointView view(current); auto lineWidth = 0; auto it = view.begin(); - while (it != view.end() && lineWidth < text->max_width) + size_t lastWhitespaceIndex = 0; + while (it != view.end()) { - // Trim any leading spaces - auto codepoint = *it; - if (codepoint != ' ' || lineWidth != 0) + const auto codepoint = *it; + const auto glyph = text->GetGlyph(codepoint, ' '); + lineWidth += glyph.width; + + if (codepoint == ' ') { - // Determine if this is a good place to split - if (codepoint == ' ' || codepoint == '\n') - { - auto index = it.GetIndex(); - best = current.substr(0, index); - next = current.substr(index + 1); - if (codepoint == '\n') - break; - } - - auto glyph = text->GetGlyph(*it, ' '); - lineWidth += glyph.width; + lastWhitespaceIndex = it.GetIndex(); } + + if (lineWidth > text->max_width) + { + break; + } + it++; + + const auto index = it.GetIndex(); + best = current.substr(0, index); + next = current.substr(index); } - // handle case where second line fully fits - if (it == view.end() && lineWidth < text->max_width) + if (lastWhitespaceIndex != 0 && it != view.end()) { - best = current; - next = std::string_view{}; - } - - if (best.empty()) - { - // No good split found, or reached end of string - auto index = it.GetIndex(); - best = current.substr(0, index - 1); - next = current.substr(index - 1); + best = current.substr(0, lastWhitespaceIndex); + next = current.substr(lastWhitespaceIndex + 1); } PaintLargeScenery3DTextLine(session, sceneryEntry, *text, best, imageTemplate, direction, offsetY);