From 503a383301606109d4fc831b426d9266371c351f Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 22 Nov 2020 00:36:40 +0000 Subject: [PATCH] Do not format characters in text input --- src/openrct2-ui/interface/InGameConsole.cpp | 6 +- src/openrct2-ui/interface/Widget.cpp | 8 +-- src/openrct2-ui/windows/TextInput.cpp | 6 +- src/openrct2/drawing/Drawing.String.cpp | 64 +++++++++++++++------ src/openrct2/drawing/Drawing.h | 6 +- src/openrct2/drawing/Text.cpp | 18 ++++-- 6 files changed, 74 insertions(+), 34 deletions(-) diff --git a/src/openrct2-ui/interface/InGameConsole.cpp b/src/openrct2-ui/interface/InGameConsole.cpp index 99e13a5b2a..d055f60b12 100644 --- a/src/openrct2-ui/interface/InGameConsole.cpp +++ b/src/openrct2-ui/interface/InGameConsole.cpp @@ -140,7 +140,7 @@ void InGameConsole::RefreshCaret(size_t position) _selectionStart = position; char tempString[TEXT_INPUT_SIZE] = { 0 }; std::memcpy(tempString, &_consoleCurrentLine, _selectionStart); - _caretScreenPosX = gfx_get_string_width(tempString); + _caretScreenPosX = gfx_get_string_width_no_formatting(tempString); } void InGameConsole::Scroll(int32_t linesToScroll) @@ -312,7 +312,7 @@ void InGameConsole::Draw(rct_drawpixelinfo* dpi) const { const size_t index = i + _consoleScrollPos; lineBuffer = colourFormatStr + _consoleLines[index]; - gfx_draw_string(dpi, lineBuffer.c_str(), textColour, screenCoords); + gfx_draw_string_no_formatting(dpi, lineBuffer.c_str(), textColour, screenCoords); screenCoords.y += lineHeight; } @@ -320,7 +320,7 @@ void InGameConsole::Draw(rct_drawpixelinfo* dpi) const // Draw current line lineBuffer = colourFormatStr + _consoleCurrentLine; - gfx_draw_string(dpi, lineBuffer.c_str(), TEXT_COLOUR_255, screenCoords); + gfx_draw_string_no_formatting(dpi, lineBuffer.c_str(), TEXT_COLOUR_255, screenCoords); // Draw caret if (_consoleCaretTicks < CONSOLE_CARET_FLASH_THRESHOLD) diff --git a/src/openrct2-ui/interface/Widget.cpp b/src/openrct2-ui/interface/Widget.cpp index fbbbb951b0..8eec71a3f9 100644 --- a/src/openrct2-ui/interface/Widget.cpp +++ b/src/openrct2-ui/interface/Widget.cpp @@ -1055,7 +1055,7 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti { safe_strcpy(wrapped_string, w->widgets[widgetIndex].string, 512); gfx_wrap_string(wrapped_string, bottomRight.x - topLeft.x - 5, &no_lines, &font_height); - gfx_draw_string(dpi, wrapped_string, w->colours[1], { topLeft.x + 2, topLeft.y }); + gfx_draw_string_no_formatting(dpi, wrapped_string, w->colours[1], { topLeft.x + 2, topLeft.y }); } return; } @@ -1066,14 +1066,14 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti // +13 for cursor when max length. gfx_wrap_string(wrapped_string, bottomRight.x - topLeft.x - 5 - 6, &no_lines, &font_height); - gfx_draw_string(dpi, wrapped_string, w->colours[1], { topLeft.x + 2, topLeft.y }); + gfx_draw_string_no_formatting(dpi, wrapped_string, w->colours[1], { topLeft.x + 2, topLeft.y }); size_t string_length = get_string_size(wrapped_string) - 1; // Make a copy of the string for measuring the width. char temp_string[TEXT_INPUT_SIZE] = { 0 }; std::memcpy(temp_string, wrapped_string, std::min(string_length, gTextInput->SelectionStart)); - int32_t cur_x = topLeft.x + gfx_get_string_width(temp_string) + 3; + int32_t cur_x = topLeft.x + gfx_get_string_width_no_formatting(temp_string) + 3; int32_t width = 6; if (static_cast(gTextInput->SelectionStart) < strlen(gTextBoxInput)) @@ -1082,7 +1082,7 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti // of the character that the cursor is under. temp_string[1] = '\0'; temp_string[0] = gTextBoxInput[gTextInput->SelectionStart]; - width = std::max(gfx_get_string_width(temp_string) - 2, 4); + width = std::max(gfx_get_string_width_no_formatting(temp_string) - 2, 4); } if (gTextBoxFrameNo <= 15) diff --git a/src/openrct2-ui/windows/TextInput.cpp b/src/openrct2-ui/windows/TextInput.cpp index db80b5873c..6948c2b81d 100644 --- a/src/openrct2-ui/windows/TextInput.cpp +++ b/src/openrct2-ui/windows/TextInput.cpp @@ -266,7 +266,7 @@ static void window_text_input_paint(rct_window* w, rct_drawpixelinfo* dpi) for (int32_t line = 0; line <= no_lines; line++) { screenCoords.x = w->windowPos.x + 12; - gfx_draw_string(dpi, wrap_pointer, w->colours[1], screenCoords); + gfx_draw_string_no_formatting(dpi, wrap_pointer, w->colours[1], screenCoords); size_t string_length = get_string_size(wrap_pointer) - 1; @@ -275,7 +275,7 @@ static void window_text_input_paint(rct_window* w, rct_drawpixelinfo* dpi) // Make a copy of the string for measuring the width. char temp_string[TEXT_INPUT_SIZE] = { 0 }; std::memcpy(temp_string, wrap_pointer, gTextInput->SelectionStart - char_count); - cursorX = w->windowPos.x + 13 + gfx_get_string_width(temp_string); + cursorX = w->windowPos.x + 13 + gfx_get_string_width_no_formatting(temp_string); cursorY = screenCoords.y; int32_t width = 6; @@ -286,7 +286,7 @@ static void window_text_input_paint(rct_window* w, rct_drawpixelinfo* dpi) utf8 tmp[5] = { 0 }; // This is easier than setting temp_string[0..5] uint32_t codepoint = utf8_get_next(text_input + gTextInput->SelectionStart, nullptr); utf8_write_codepoint(tmp, codepoint); - width = std::max(gfx_get_string_width(tmp) - 2, 4); + width = std::max(gfx_get_string_width_no_formatting(tmp) - 2, 4); } if (w->frame_no > 15) diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 34b3331e09..56ba5364a1 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -30,12 +30,13 @@ enum : uint32_t TEXT_DRAW_FLAG_OUTLINE = 1 << 1, TEXT_DRAW_FLAG_DARK = 1 << 2, TEXT_DRAW_FLAG_EXTRA_DARK = 1 << 3, + TEXT_DRAW_FLAG_NO_FORMATTING = 1 << 28, TEXT_DRAW_FLAG_Y_OFFSET_EFFECT = 1 << 29, TEXT_DRAW_FLAG_TTF = 1 << 30, TEXT_DRAW_FLAG_NO_DRAW = 1u << 31 }; -static int32_t ttf_get_string_width(std::string_view text); +static int32_t ttf_get_string_width(std::string_view text, bool noFormatting); /** * @@ -79,7 +80,12 @@ int32_t gfx_get_string_width_new_lined(std::string_view text) */ int32_t gfx_get_string_width(std::string_view text) { - return ttf_get_string_width(text); + return ttf_get_string_width(text, false); +} + +int32_t gfx_get_string_width_no_formatting(std::string_view text) +{ + return ttf_get_string_width(text, true); } /** @@ -833,25 +839,34 @@ static void ttf_process_string_codepoint(rct_drawpixelinfo* dpi, codepoint_t cod static void ttf_process_string(rct_drawpixelinfo* dpi, std::string_view text, text_draw_info* info) { - FmtString fmt(text); - for (const auto& token : fmt) + if (info->flags & TEXT_DRAW_FLAG_NO_FORMATTING) { - if (token.IsLiteral()) - { - ttf_process_string_literal(dpi, token.text, info); - } - else if (token.IsCodepoint()) - { - auto codepoint = token.GetCodepoint(); - ttf_process_string_codepoint(dpi, codepoint, info); - } - else - { - ttf_process_format_code(dpi, token, info); - } + ttf_process_string_literal(dpi, text, info); info->maxX = std::max(info->maxX, info->x); info->maxY = std::max(info->maxY, info->y); } + else + { + FmtString fmt(text); + for (const auto& token : fmt) + { + if (token.IsLiteral()) + { + ttf_process_string_literal(dpi, token.text, info); + } + else if (token.IsCodepoint()) + { + auto codepoint = token.GetCodepoint(); + ttf_process_string_codepoint(dpi, codepoint, info); + } + else + { + ttf_process_format_code(dpi, token, info); + } + info->maxX = std::max(info->maxX, info->x); + info->maxY = std::max(info->maxY, info->y); + } + } } static void ttf_process_initial_colour(int32_t colour, text_draw_info* info) @@ -919,7 +934,8 @@ static void ttf_process_initial_colour(int32_t colour, text_draw_info* info) } } -void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords) +void ttf_draw_string( + rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords, bool noFormatting) { if (text == nullptr) return; @@ -937,6 +953,11 @@ void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colo info.flags |= TEXT_DRAW_FLAG_TTF; } + if (noFormatting) + { + info.flags |= TEXT_DRAW_FLAG_NO_FORMATTING; + } + std::memcpy(info.palette, text_palette, sizeof(info.palette)); ttf_process_initial_colour(colour, &info); ttf_process_string(dpi, text, &info); @@ -949,7 +970,7 @@ void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colo gLastDrawStringY = info.y; } -static int32_t ttf_get_string_width(std::string_view text) +static int32_t ttf_get_string_width(std::string_view text, bool noFormatting) { text_draw_info info; info.font_sprite_base = gCurrentFontSpriteBase; @@ -967,6 +988,11 @@ static int32_t ttf_get_string_width(std::string_view text) info.flags |= TEXT_DRAW_FLAG_TTF; } + if (noFormatting) + { + info.flags |= TEXT_DRAW_FLAG_NO_FORMATTING; + } + ttf_process_string(nullptr, text, &info); return info.maxX; diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 7ccb38eeb5..ed02c2f4f5 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -733,6 +733,8 @@ void FASTCALL gfx_draw_sprite_raw_masked_software( // string void gfx_draw_string(rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, const ScreenCoordsXY& coords); +void gfx_draw_string_no_formatting( + rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, const ScreenCoordsXY& coords); /** @deprecated */ void gfx_draw_string_left( @@ -759,10 +761,12 @@ void gfx_draw_string_with_y_offsets( int32_t gfx_wrap_string(char* buffer, int32_t width, int32_t* num_lines, int32_t* font_height); int32_t gfx_get_string_width(std::string_view text); int32_t gfx_get_string_width_new_lined(std::string_view text); +int32_t gfx_get_string_width_no_formatting(std::string_view text); int32_t string_get_height_raw(char* buffer); int32_t gfx_clip_string(char* buffer, int32_t width); void shorten_path(utf8* buffer, size_t bufferSize, const utf8* path, int32_t availableWidth); -void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords); +void ttf_draw_string( + rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords, bool noFormatting); // scrolling text void scrolling_text_initialise_bitmaps(); diff --git a/src/openrct2/drawing/Text.cpp b/src/openrct2/drawing/Text.cpp index 5b7adfb1a5..77736be622 100644 --- a/src/openrct2/drawing/Text.cpp +++ b/src/openrct2/drawing/Text.cpp @@ -12,7 +12,9 @@ #include "../localisation/Localisation.h" #include "Drawing.h" -static void DrawText(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const TextPaint& paint, const_utf8string text); +static void DrawText( + rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const TextPaint& paint, const_utf8string text, + bool noFormatting = false); static void DrawText( rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const TextPaint& paint, rct_string_id format, const void* args); @@ -74,9 +76,10 @@ int32_t StaticLayout::GetLineCount() return LineCount; } -static void DrawText(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const TextPaint& paint, const_utf8string text) +static void DrawText( + rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const TextPaint& paint, const_utf8string text, bool noFormatting) { - int32_t width = gfx_get_string_width(text); + int32_t width = noFormatting ? gfx_get_string_width_no_formatting(text) : gfx_get_string_width(text); auto alignedCoords = coords; switch (paint.Alignment) @@ -91,7 +94,7 @@ static void DrawText(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, const break; } - ttf_draw_string(dpi, text, paint.Colour, alignedCoords); + ttf_draw_string(dpi, text, paint.Colour, alignedCoords, noFormatting); if (paint.UnderlineText) { @@ -151,6 +154,13 @@ void gfx_draw_string(rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t co DrawText(dpi, coords, textPaint, buffer); } +void gfx_draw_string_no_formatting( + rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, const ScreenCoordsXY& coords) +{ + TextPaint textPaint = { colour, gCurrentFontSpriteBase, false, TextAlignment::LEFT }; + DrawText(dpi, coords, textPaint, buffer, true); +} + // Basic void gfx_draw_string_left( rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, const ScreenCoordsXY& coords)