diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index 7e7c373a0c..3961c4559d 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -140,7 +140,7 @@ public: { return _index != rhs._index; } - const char32_t operator*() const + char32_t operator*() const { return GetNextCodepoint(&_str[_index], nullptr); } diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 4ae0a79816..4e25195d70 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -133,7 +133,7 @@ int32_t gfx_clip_string(utf8* text, int32_t width) { // Width exceeded, rollback to best length and put ellipsis back buffer.resize(bestLength); - for (auto i = static_cast(bestLength) - 1; i >= 0 && i >= bestLength - 3; i--) + for (auto i = static_cast(bestLength) - 1; i >= 0 && i >= static_cast(bestLength) - 3; i--) { buffer[bestLength - i] = '.'; } @@ -392,6 +392,8 @@ int32_t string_get_height_raw(char* buffer) case FormatToken::FontSmall: fontBase = FONT_SPRITE_BASE_SMALL; break; + default: + break; } } return height; @@ -736,6 +738,31 @@ static void ttf_process_format_code(rct_drawpixelinfo* dpi, const FmtString::tok } } +static bool ShouldUseSpriteForCodepoint(char32_t codepoint) +{ + switch (codepoint) + { + case UnicodeChar::up: + case UnicodeChar::down: + case UnicodeChar::leftguillemet: + case UnicodeChar::tick: + case UnicodeChar::cross: + case UnicodeChar::right: + case UnicodeChar::rightguillemet: + case UnicodeChar::small_up: + case UnicodeChar::small_down: + case UnicodeChar::left: + case UnicodeChar::quote_open: + case UnicodeChar::quote_close: + case UnicodeChar::german_quote_open: + case UnicodeChar::plus: + case UnicodeChar::minus: + return true; + default: + return false; + } +} + static void ttf_process_string_literal(rct_drawpixelinfo* dpi, const std::string_view text, text_draw_info* info) { #ifndef NO_TTF @@ -748,6 +775,7 @@ static void ttf_process_string_literal(rct_drawpixelinfo* dpi, const std::string { ttf_draw_string_raw_sprite(dpi, text, info); } +#ifndef NO_TTF else { CodepointView codepoints(text); @@ -755,7 +783,7 @@ static void ttf_process_string_literal(rct_drawpixelinfo* dpi, const std::string for (auto it = codepoints.begin(); it != codepoints.end(); it++) { auto codepoint = *it; - if (utf8_should_use_sprite_for_codepoint(codepoint)) + if (ShouldUseSpriteForCodepoint(codepoint)) { auto index = it.GetIndex(); auto ttfLen = index - ttfRunIndex; @@ -771,6 +799,7 @@ static void ttf_process_string_literal(rct_drawpixelinfo* dpi, const std::string } } } +#endif // NO_TTF } static void ttf_process_string(rct_drawpixelinfo* dpi, std::string_view text, text_draw_info* info) diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index ec4bc6973e..37068fc31e 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -60,7 +60,6 @@ static std::mutex _mutex; static TTF_Font* ttf_open_font(const utf8* fontPath, int32_t ptSize); static void ttf_close_font(TTF_Font* font); -static uint32_t ttf_surface_cache_hash(TTF_Font* font, const utf8* text); static void ttf_surface_cache_dispose(ttf_cache_entry* entry); static void ttf_surface_cache_dispose_all(); static void ttf_getwidth_cache_dispose_all(); diff --git a/src/openrct2/interface/StdInOutConsole.cpp b/src/openrct2/interface/StdInOutConsole.cpp index 4570a9dfd5..239e1179a4 100644 --- a/src/openrct2/interface/StdInOutConsole.cpp +++ b/src/openrct2/interface/StdInOutConsole.cpp @@ -121,6 +121,8 @@ void StdInOutConsole::WriteLine(const std::string& s, FormatToken colourFormat) case FormatToken::ColourYellow: formatBegin = "\033[33m"; break; + default: + break; } } diff --git a/src/openrct2/localisation/FormatCodes.cpp b/src/openrct2/localisation/FormatCodes.cpp index 38013c70c0..5ea08f8620 100644 --- a/src/openrct2/localisation/FormatCodes.cpp +++ b/src/openrct2/localisation/FormatCodes.cpp @@ -31,7 +31,7 @@ static const std::unordered_map FormatTokenMap = { "COMMA1DP16", FormatToken::Comma1dp16, }, { "COMMA2DP32", FormatToken::Comma2dp32, }, { "COMMA16", FormatToken::Comma16, }, - { "UINT16", FormatToken::Uint16, }, + { "UINT16", FormatToken::UInt16, }, { "CURRENCY2DP", FormatToken::Currency2dp, }, { "CURRENCY", FormatToken::Currency, }, { "STRINGID", FormatToken::StringId, }, @@ -89,7 +89,7 @@ bool FormatTokenTakesArgument(FormatToken token) case FormatToken::Comma1dp16: case FormatToken::Comma2dp32: case FormatToken::Comma16: - case FormatToken::Uint16: + case FormatToken::UInt16: case FormatToken::Currency2dp: case FormatToken::Currency: case FormatToken::StringId: @@ -102,8 +102,9 @@ bool FormatTokenTakesArgument(FormatToken token) case FormatToken::Length: case FormatToken::Sprite: return true; + default: + return false; } - return false; } bool FormatTokenIsColour(FormatToken token) @@ -125,8 +126,9 @@ bool FormatTokenIsColour(FormatToken token) case FormatToken::ColourPearlAqua: case FormatToken::ColourPaleSilver: return true; + default: + return false; } - return false; } size_t FormatTokenGetTextColourIndex(FormatToken token) @@ -161,8 +163,9 @@ size_t FormatTokenGetTextColourIndex(FormatToken token) return 12; case FormatToken::ColourPaleSilver: return 13; + default: + return 0; } - return 0; } FormatToken FormatTokenFromTextColour(size_t textColour) @@ -178,28 +181,3 @@ FormatToken FormatTokenFromTextColour(size_t textColour) return FormatToken::ColourBlack; return tokens[textColour]; } - -bool utf8_should_use_sprite_for_codepoint(char32_t codepoint) -{ - switch (codepoint) - { - case UnicodeChar::up: - case UnicodeChar::down: - case UnicodeChar::leftguillemet: - case UnicodeChar::tick: - case UnicodeChar::cross: - case UnicodeChar::right: - case UnicodeChar::rightguillemet: - case UnicodeChar::small_up: - case UnicodeChar::small_down: - case UnicodeChar::left: - case UnicodeChar::quote_open: - case UnicodeChar::quote_close: - case UnicodeChar::german_quote_open: - case UnicodeChar::plus: - case UnicodeChar::minus: - return true; - default: - return false; - } -} diff --git a/src/openrct2/localisation/FormatCodes.h b/src/openrct2/localisation/FormatCodes.h index 4e80c5b542..2a8f227668 100644 --- a/src/openrct2/localisation/FormatCodes.h +++ b/src/openrct2/localisation/FormatCodes.h @@ -31,7 +31,7 @@ enum class FormatToken Comma1dp16, Comma2dp32, Comma16, - Uint16, + UInt16, Currency2dp, Currency, StringId, diff --git a/src/openrct2/localisation/Formatting.cpp b/src/openrct2/localisation/Formatting.cpp index b9f2950419..e1b3f3239f 100644 --- a/src/openrct2/localisation/Formatting.cpp +++ b/src/openrct2/localisation/Formatting.cpp @@ -16,6 +16,7 @@ #include "Localisation.h" #include "StringIds.h" +#include #include namespace OpenRCT2 @@ -237,13 +238,13 @@ namespace OpenRCT2 return result; } - std::string_view GetDigitSeperator() + static std::string_view GetDigitSeperator() { auto sz = language_get_string(STR_LOCALE_THOUSANDS_SEPARATOR); return sz != nullptr ? sz : std::string_view(); } - std::string_view GetDecimalSeperator() + static std::string_view GetDecimalSeperator() { auto sz = language_get_string(STR_LOCALE_DECIMAL_POINT); return sz != nullptr ? sz : std::string_view(); @@ -275,7 +276,7 @@ namespace OpenRCT2 template void FormatNumber(std::stringstream& ss, T value) { char buffer[32]; - int32_t i = 0; + size_t i = 0; size_t num; if (value < 0) @@ -294,7 +295,7 @@ namespace OpenRCT2 { while (num != 0 && i < sizeof(buffer) && i < TDecimalPlace) { - buffer[i++] = (char)('0' + (num % 10)); + buffer[i++] = static_cast('0' + (num % 10)); num /= 10; } @@ -303,7 +304,7 @@ namespace OpenRCT2 } // Whole digits - auto digitSep = GetDigitSeperator(); + [[maybe_unused]] auto digitSep = GetDigitSeperator(); size_t groupLen = 0; do { @@ -315,7 +316,7 @@ namespace OpenRCT2 AppendSeperator(buffer, i, digitSep); } } - buffer[i++] = (char)('0' + (num % 10)); + buffer[i++] = static_cast('0' + (num % 10)); num /= 10; if constexpr (TDigitSep) { @@ -324,7 +325,7 @@ namespace OpenRCT2 } while (num != 0 && i < sizeof(buffer)); // Finally reverse append the string - for (int32_t j = i - 1; j >= 0; j--) + for (int32_t j = static_cast(i - 1); j >= 0; j--) { ss << buffer[j]; } @@ -433,7 +434,7 @@ namespace OpenRCT2 { switch (token) { - case FormatToken::Uint16: + case FormatToken::UInt16: case FormatToken::Int32: if constexpr (std::is_integral()) { @@ -564,6 +565,8 @@ namespace OpenRCT2 ss << "{" << ((idx >> 24) & 0xFF) << "}"; } break; + default: + break; } } @@ -603,7 +606,7 @@ namespace OpenRCT2 return stringLen; } - void FormatArgumentAny(std::stringstream& ss, FormatToken token, const FormatArg_t& value) + static void FormatArgumentAny(std::stringstream& ss, FormatToken token, const FormatArg_t& value) { if (std::holds_alternative(value)) { @@ -705,7 +708,7 @@ namespace OpenRCT2 anyArgs.push_back(ReadFromArgs(args)); break; case FormatToken::Comma16: - case FormatToken::Uint16: + case FormatToken::UInt16: case FormatToken::MonthYear: case FormatToken::Month: case FormatToken::Velocity: @@ -733,6 +736,8 @@ namespace OpenRCT2 case FormatToken::Push16: args = reinterpret_cast(reinterpret_cast(args) - 2); break; + default: + break; } } } diff --git a/src/openrct2/localisation/Formatting.h b/src/openrct2/localisation/Formatting.h index 210e11594a..4c53bb1ef0 100644 --- a/src/openrct2/localisation/Formatting.h +++ b/src/openrct2/localisation/Formatting.h @@ -89,11 +89,12 @@ namespace OpenRCT2 auto& it = *stack.top(); while (!it.eol()) { - const auto& token = *it++; + const auto& token = *it; if (!FormatTokenTakesArgument(token.kind)) { ss << token.text; } + it++; } stack.pop(); } diff --git a/src/openrct2/localisation/Localisation.h b/src/openrct2/localisation/Localisation.h index 1e1230f9a1..140023c147 100644 --- a/src/openrct2/localisation/Localisation.h +++ b/src/openrct2/localisation/Localisation.h @@ -19,8 +19,6 @@ #include -bool utf8_should_use_sprite_for_codepoint(char32_t codepoint); - std::string format_string(rct_string_id format, const void* args); void format_string(char* dest, size_t size, rct_string_id format, const void* args); void format_string_to_upper(char* dest, size_t size, rct_string_id format, const void* args); diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index e13ce4ffca..42d11ef97c 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -170,6 +170,14 @@ target_link_libraries(test_string ${GTEST_LIBRARIES} test-common ${LDL} z) target_link_platform_libraries(test_string) add_test(NAME string COMMAND test_string) +# Formatting tests +set(STRING_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/FormattingTests.cpp") +add_executable(test_formatting ${STRING_TEST_SOURCES}) +SET_CHECK_CXX_FLAGS(test_formatting) +target_link_libraries(test_formatting ${GTEST_LIBRARIES} libopenrct2 ${LDL} z) +target_link_platform_libraries(test_formatting) +add_test(NAME formatting COMMAND test_formatting) + # Localisation test set(STRING_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/Localisation.cpp") add_executable(test_localisation ${STRING_TEST_SOURCES}) diff --git a/test/tests/FormattingTests.cpp b/test/tests/FormattingTests.cpp index de36f1c6d5..2a0d04a6b8 100644 --- a/test/tests/FormattingTests.cpp +++ b/test/tests/FormattingTests.cpp @@ -39,7 +39,7 @@ TEST_F(FmtStringTests, iteration) actual += String::StdFormat("[%d:%s]", t.kind, std::string(t.text).c_str()); } - ASSERT_EQ("[142:{BLACK}][0:Guests: ][124:{INT32}]", actual); + ASSERT_EQ("[28:{BLACK}][1:Guests: ][7:{INT32}]", actual); } TEST_F(FmtStringTests, without_format_tokens) @@ -287,7 +287,7 @@ TEST_F(FormattingTests, to_fixed_buffer) char buffer[16]; std::memset(buffer, '\xFF', sizeof(buffer)); auto len = FormatStringId(buffer, 8, STR_GUEST_X, 123); - ASSERT_EQ(len, 9); + ASSERT_EQ(len, 9U); ASSERT_STREQ("Guest 1", buffer); // Ensure rest of the buffer was not overwritten @@ -306,6 +306,6 @@ TEST_F(FormattingTests, using_legacy_buffer_args) char buffer[32]{}; auto len = FormatStringLegacy(buffer, sizeof(buffer), STR_QUEUING_FOR, ft.Data()); - ASSERT_EQ(len, 23); + ASSERT_EQ(len, 23U); ASSERT_STREQ("Queuing for Boat Hire 2", buffer); }