mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Merge pull request #19391 from CookiePLMonster/asan-fixes
Fix broken string wrapping and language loading
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
- Fix: [#19292] Overflow in totalRideValue.
|
||||
- Fix: [#19379] "No platforms" station style shows platforms on the Junior Roller Coaster.
|
||||
- Fix: [#19380] Startup crash when no sequences are installed and random sequences are enabled.
|
||||
- Fix: [#19391] String corruption caused by an improper buffer handling in GfxWrapString.
|
||||
|
||||
0.4.3 (2022-12-14)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
@@ -1123,9 +1123,6 @@ void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value)
|
||||
|
||||
static void WidgetTextBoxDraw(DrawPixelInfo* dpi, WindowBase& w, WidgetIndex widgetIndex)
|
||||
{
|
||||
int32_t no_lines = 0;
|
||||
char wrapped_string[TEXT_INPUT_SIZE];
|
||||
|
||||
// Get the widget
|
||||
const auto& widget = w.widgets[widgetIndex];
|
||||
|
||||
@@ -1149,43 +1146,42 @@ static void WidgetTextBoxDraw(DrawPixelInfo* dpi, WindowBase& w, WidgetIndex wid
|
||||
{
|
||||
if (widget.text != 0)
|
||||
{
|
||||
SafeStrCpy(wrapped_string, widget.string, 512);
|
||||
GfxWrapString(wrapped_string, bottomRight.x - topLeft.x - 5, FontStyle::Medium, &no_lines);
|
||||
GfxDrawStringNoFormatting(dpi, { topLeft.x + 2, topLeft.y }, wrapped_string, { w.colours[1], FontStyle::Medium });
|
||||
u8string wrappedString;
|
||||
GfxWrapString(widget.string, bottomRight.x - topLeft.x - 5, FontStyle::Medium, &wrappedString, nullptr);
|
||||
GfxDrawStringNoFormatting(
|
||||
dpi, { topLeft.x + 2, topLeft.y }, wrappedString.c_str(), { w.colours[1], FontStyle::Medium });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SafeStrCpy(wrapped_string, gTextBoxInput, TEXT_INPUT_SIZE);
|
||||
|
||||
// String length needs to add 12 either side of box
|
||||
// +13 for cursor when max length.
|
||||
GfxWrapString(wrapped_string, bottomRight.x - topLeft.x - 5 - 6, FontStyle::Medium, &no_lines);
|
||||
u8string wrappedString;
|
||||
GfxWrapString(gTextBoxInput, bottomRight.x - topLeft.x - 5 - 6, FontStyle::Medium, &wrappedString, nullptr);
|
||||
|
||||
GfxDrawStringNoFormatting(dpi, { topLeft.x + 2, topLeft.y }, wrapped_string, { w.colours[1], FontStyle::Medium });
|
||||
GfxDrawStringNoFormatting(dpi, { topLeft.x + 2, topLeft.y }, wrappedString.c_str(), { w.colours[1], FontStyle::Medium });
|
||||
|
||||
size_t string_length = GetStringSize(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 + GfxGetStringWidthNoFormatting(temp_string, FontStyle::Medium) + 3;
|
||||
// Make a trimmed view of the string for measuring the width.
|
||||
int32_t curX = topLeft.x
|
||||
+ GfxGetStringWidthNoFormatting(
|
||||
u8string_view{ wrappedString.c_str(), std::min(wrappedString.length(), gTextInput->SelectionStart) },
|
||||
FontStyle::Medium)
|
||||
+ 3;
|
||||
|
||||
int32_t width = 6;
|
||||
if (static_cast<uint32_t>(gTextInput->SelectionStart) < strlen(gTextBoxInput))
|
||||
{
|
||||
// Make a new 1 character wide string for measuring the width
|
||||
// of the character that the cursor is under.
|
||||
temp_string[1] = '\0';
|
||||
temp_string[0] = gTextBoxInput[gTextInput->SelectionStart];
|
||||
width = std::max(GfxGetStringWidthNoFormatting(temp_string, FontStyle::Medium) - 2, 4);
|
||||
width = std::max(
|
||||
GfxGetStringWidthNoFormatting(u8string{ gTextBoxInput[gTextInput->SelectionStart] }, FontStyle::Medium) - 2, 4);
|
||||
}
|
||||
|
||||
if (gTextBoxFrameNo <= 15)
|
||||
{
|
||||
colour = ColourMapA[w.colours[1]].mid_light;
|
||||
auto y = topLeft.y + (widget.height() - 1);
|
||||
GfxFillRect(dpi, { { cur_x, y }, { cur_x + width, y } }, colour + 5);
|
||||
GfxFillRect(dpi, { { curX, y }, { curX + width, y } }, colour + 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
|
||||
public:
|
||||
ErrorWindow(std::string text, uint16_t numLines)
|
||||
: _text(text)
|
||||
: _text(std::move(text))
|
||||
, _numLines(numLines)
|
||||
{
|
||||
}
|
||||
@@ -139,7 +139,7 @@ WindowBase* WindowErrorOpen(std::string_view title, std::string_view message)
|
||||
width = std::clamp(width, 64, 196);
|
||||
|
||||
int32_t numLines{};
|
||||
GfxWrapString(buffer.data(), width + 1, FontStyle::Medium, &numLines);
|
||||
GfxWrapString(buffer, width + 1, FontStyle::Medium, &buffer, &numLines);
|
||||
|
||||
width = width + 3;
|
||||
int32_t height = (numLines + 1) * FontGetLineHeight(FontStyle::Medium) + 4;
|
||||
@@ -155,7 +155,7 @@ WindowBase* WindowErrorOpen(std::string_view title, std::string_view message)
|
||||
windowPosition.y = std::min(windowPosition.y - height - 40, maxY);
|
||||
}
|
||||
|
||||
auto errorWindow = std::make_unique<ErrorWindow>(buffer, numLines);
|
||||
auto errorWindow = std::make_unique<ErrorWindow>(std::move(buffer), numLines);
|
||||
return WindowCreate(
|
||||
std::move(errorWindow), WindowClass::Error, windowPosition, width, height,
|
||||
WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_RESIZABLE);
|
||||
|
||||
@@ -567,10 +567,10 @@ static void WindowGameBottomToolbarDrawNewsItem(DrawPixelInfo* dpi, WindowBase*
|
||||
w->colours[2], INSET_RECT_F_30);
|
||||
|
||||
// Text
|
||||
const auto* newsItemText = newsItem->Text.c_str();
|
||||
auto screenCoords = w->windowPos + ScreenCoordsXY{ middleOutsetWidget->midX(), middleOutsetWidget->top + 11 };
|
||||
width = middleOutsetWidget->width() - 62;
|
||||
DrawNewsTicker(dpi, screenCoords, width, COLOUR_BRIGHT_GREEN, STR_BOTTOM_TOOLBAR_NEWS_TEXT, &newsItemText, newsItem->Ticks);
|
||||
DrawNewsTicker(
|
||||
dpi, screenCoords, width, COLOUR_BRIGHT_GREEN, STR_BOTTOM_TOOLBAR_NEWS_TEXT, newsItem->Text, newsItem->Ticks);
|
||||
|
||||
screenCoords = w->windowPos
|
||||
+ ScreenCoordsXY{ window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].left,
|
||||
|
||||
@@ -339,22 +339,21 @@ static ScreenCoordsXY WindowMultiplayerInformationGetSize()
|
||||
// Base dimensions.
|
||||
const int32_t width = 450;
|
||||
int32_t height = 55;
|
||||
int32_t numLines;
|
||||
|
||||
// Server name is displayed word-wrapped, so figure out how high it will be.
|
||||
{
|
||||
u8string buffer = NetworkGetServerName();
|
||||
GfxWrapString(buffer.data(), width, FontStyle::Medium, &numLines);
|
||||
height += ++numLines * lineHeight + (LIST_ROW_HEIGHT / 2);
|
||||
int32_t numLines;
|
||||
GfxWrapString(NetworkGetServerName(), width, FontStyle::Medium, nullptr, &numLines);
|
||||
height += (numLines + 1) * lineHeight + (LIST_ROW_HEIGHT / 2);
|
||||
}
|
||||
|
||||
// Likewise, for the optional server description -- which can be a little longer.
|
||||
const auto& descString = NetworkGetServerDescription();
|
||||
if (!descString.empty())
|
||||
{
|
||||
u8string buffer = descString;
|
||||
GfxWrapString(buffer.data(), width, FontStyle::Medium, &numLines);
|
||||
height += ++numLines * lineHeight + (LIST_ROW_HEIGHT / 2);
|
||||
int32_t numLines;
|
||||
GfxWrapString(descString, width, FontStyle::Medium, nullptr, &numLines);
|
||||
height += (numLines + 1) * lineHeight + (LIST_ROW_HEIGHT / 2);
|
||||
}
|
||||
|
||||
// Finally, account for provider info, if present.
|
||||
|
||||
@@ -218,12 +218,11 @@ public:
|
||||
|
||||
screenCoords.y += 25;
|
||||
|
||||
char wrapped_string[TEXT_INPUT_SIZE];
|
||||
SafeStrCpy(wrapped_string, _buffer.data(), _buffer.size());
|
||||
|
||||
// String length needs to add 12 either side of box
|
||||
// +13 for cursor when max length.
|
||||
GfxWrapString(wrapped_string, WW - (24 + 13), FontStyle::Medium, &no_lines);
|
||||
u8string wrappedString;
|
||||
GfxWrapString(
|
||||
u8string_view{ _buffer.data(), _buffer.size() }, WW - (24 + 13), FontStyle::Medium, &wrappedString, &no_lines);
|
||||
|
||||
GfxFillRectInset(
|
||||
&dpi, { { windowPos.x + 10, screenCoords.y }, { windowPos.x + WW - 10, screenCoords.y + 10 * (no_lines + 1) + 3 } },
|
||||
@@ -231,7 +230,7 @@ public:
|
||||
|
||||
screenCoords.y += 1;
|
||||
|
||||
char* wrap_pointer = wrapped_string;
|
||||
const utf8* wrapPointer = wrappedString.data();
|
||||
size_t char_count = 0;
|
||||
uint8_t cur_drawn = 0;
|
||||
|
||||
@@ -240,16 +239,16 @@ public:
|
||||
for (int32_t line = 0; line <= no_lines; line++)
|
||||
{
|
||||
screenCoords.x = windowPos.x + 12;
|
||||
GfxDrawStringNoFormatting(&dpi, screenCoords, wrap_pointer, { colours[1], FontStyle::Medium });
|
||||
GfxDrawStringNoFormatting(&dpi, screenCoords, wrapPointer, { colours[1], FontStyle::Medium });
|
||||
|
||||
size_t string_length = GetStringSize(wrap_pointer) - 1;
|
||||
size_t string_length = GetStringSize(wrapPointer) - 1;
|
||||
|
||||
if (!cur_drawn && (gTextInput->SelectionStart <= char_count + string_length))
|
||||
{
|
||||
// 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 = windowPos.x + 13 + GfxGetStringWidthNoFormatting(temp_string, FontStyle::Medium);
|
||||
// Make a view of the string for measuring the width.
|
||||
cursorX = windowPos.x + 13
|
||||
+ GfxGetStringWidthNoFormatting(
|
||||
u8string_view{ wrapPointer, gTextInput->SelectionStart - char_count }, FontStyle::Medium);
|
||||
cursorY = screenCoords.y;
|
||||
|
||||
int32_t textWidth = 6;
|
||||
@@ -257,7 +256,7 @@ public:
|
||||
{
|
||||
// Make a 1 utf8-character wide string for measuring the width
|
||||
// of the currently selected character.
|
||||
utf8 tmp[5] = { 0 }; // This is easier than setting temp_string[0..5]
|
||||
utf8 tmp[5] = {}; // This is easier than setting temp_string[0..5]
|
||||
uint32_t codepoint = UTF8GetNext(_buffer.data() + gTextInput->SelectionStart, nullptr);
|
||||
UTF8WriteCodepoint(tmp, codepoint);
|
||||
textWidth = std::max(GfxGetStringWidthNoFormatting(tmp, FontStyle::Medium) - 2, 4);
|
||||
@@ -274,7 +273,7 @@ public:
|
||||
cur_drawn++;
|
||||
}
|
||||
|
||||
wrap_pointer += string_length + 1;
|
||||
wrapPointer += string_length + 1;
|
||||
|
||||
if (_buffer[char_count + string_length] == ' ')
|
||||
char_count++;
|
||||
@@ -305,12 +304,9 @@ public:
|
||||
|
||||
static int32_t CalculateWindowHeight(std::string_view text)
|
||||
{
|
||||
std::string wrappedString(text);
|
||||
wrappedString.resize(TEXT_INPUT_SIZE);
|
||||
|
||||
// String length needs to add 12 either side of box +13 for cursor when max length.
|
||||
int32_t numLines{};
|
||||
GfxWrapString(wrappedString.data(), WW - (24 + 13), FontStyle::Medium, &numLines);
|
||||
GfxWrapString(text, WW - (24 + 13), FontStyle::Medium, nullptr, &numLines);
|
||||
return numLines * 10 + WH;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static Widget window_tooltip_widgets[] = {
|
||||
class TooltipWindow final : public Window
|
||||
{
|
||||
private:
|
||||
utf8 _tooltipText[CommonTextBufferSize]{};
|
||||
u8string _tooltipText;
|
||||
int16_t _tooltipNumLines = 1;
|
||||
|
||||
public:
|
||||
@@ -100,25 +100,24 @@ public:
|
||||
// Text
|
||||
left = windowPos.x + ((width + 1) / 2) - 1;
|
||||
top = windowPos.y + 1;
|
||||
DrawStringCentredRaw(&dpi, { left, top }, _tooltipNumLines, _tooltipText, FontStyle::Small);
|
||||
DrawStringCentredRaw(&dpi, { left, top }, _tooltipNumLines, _tooltipText.data(), FontStyle::Small);
|
||||
}
|
||||
|
||||
private:
|
||||
// Returns the width of the new tooltip text
|
||||
int32_t FormatTextForTooltip(const OpenRCT2String& message)
|
||||
{
|
||||
utf8 tempBuffer[CommonTextBufferSize];
|
||||
OpenRCT2::FormatStringLegacy(tempBuffer, sizeof(tempBuffer), message.str, message.args.Data());
|
||||
const u8string tempString = FormatStringID(message.str, message.args.Data());
|
||||
|
||||
OpenRCT2String formattedMessage{ STR_STRING_TOOLTIP, Formatter() };
|
||||
formattedMessage.args.Add<const char*>(tempBuffer);
|
||||
OpenRCT2::FormatStringLegacy(_tooltipText, sizeof(_tooltipText), formattedMessage.str, formattedMessage.args.Data());
|
||||
formattedMessage.args.Add<const char*>(tempString.c_str());
|
||||
const u8string tooltipTextUnwrapped = FormatStringID(formattedMessage.str, formattedMessage.args.Data());
|
||||
|
||||
auto textWidth = GfxGetStringWidthNewLined(_tooltipText, FontStyle::Small);
|
||||
auto textWidth = GfxGetStringWidthNewLined(tooltipTextUnwrapped, FontStyle::Small);
|
||||
textWidth = std::min(textWidth, 196);
|
||||
|
||||
int32_t numLines;
|
||||
textWidth = GfxWrapString(_tooltipText, textWidth + 1, FontStyle::Small, &numLines);
|
||||
textWidth = GfxWrapString(tooltipTextUnwrapped, textWidth + 1, FontStyle::Small, &_tooltipText, &numLines);
|
||||
_tooltipNumLines = numLines;
|
||||
return textWidth;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ static int32_t TTFGetStringWidth(std::string_view text, FontStyle fontStyle, boo
|
||||
*/
|
||||
int32_t GfxGetStringWidthNewLined(std::string_view text, FontStyle fontStyle)
|
||||
{
|
||||
thread_local std::string buffer;
|
||||
buffer.clear();
|
||||
u8string buffer;
|
||||
|
||||
std::optional<int32_t> maxWidth;
|
||||
FmtString fmt(text);
|
||||
@@ -174,11 +173,10 @@ int32_t GfxClipString(utf8* text, int32_t width, FontStyle fontStyle)
|
||||
* num_lines (edi) - out
|
||||
* font_height (ebx) - out
|
||||
*/
|
||||
int32_t GfxWrapString(utf8* text, int32_t width, FontStyle fontStyle, int32_t* outNumLines)
|
||||
int32_t GfxWrapString(u8string_view text, int32_t width, FontStyle fontStyle, u8string* outWrappedText, int32_t* outNumLines)
|
||||
{
|
||||
constexpr size_t NULL_INDEX = std::numeric_limits<size_t>::max();
|
||||
thread_local std::string buffer;
|
||||
buffer.resize(0);
|
||||
u8string buffer;
|
||||
|
||||
size_t currentLineIndex = 0;
|
||||
size_t splitIndex = NULL_INDEX;
|
||||
@@ -186,7 +184,7 @@ int32_t GfxWrapString(utf8* text, int32_t width, FontStyle fontStyle, int32_t* o
|
||||
size_t numLines = 0;
|
||||
int32_t maxWidth = 0;
|
||||
|
||||
FmtString fmt = text;
|
||||
FmtString fmt(text);
|
||||
for (const auto& token : fmt)
|
||||
{
|
||||
if (token.IsLiteral())
|
||||
@@ -261,8 +259,14 @@ int32_t GfxWrapString(utf8* text, int32_t width, FontStyle fontStyle, int32_t* o
|
||||
maxWidth = std::max(maxWidth, lineWidth);
|
||||
}
|
||||
|
||||
std::memcpy(text, buffer.data(), buffer.size() + 1);
|
||||
*outNumLines = static_cast<int32_t>(numLines);
|
||||
if (outWrappedText != nullptr)
|
||||
{
|
||||
*outWrappedText = std::move(buffer);
|
||||
}
|
||||
if (outNumLines != nullptr)
|
||||
{
|
||||
*outNumLines = static_cast<int32_t>(numLines);
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
@@ -333,7 +337,8 @@ static void ColourCharacterWindow(uint8_t colour, const uint16_t* current_font_f
|
||||
* text : esi
|
||||
* dpi : edi
|
||||
*/
|
||||
void DrawStringCentredRaw(DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t numLines, char* text, FontStyle fontStyle)
|
||||
void DrawStringCentredRaw(
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t numLines, const utf8* text, FontStyle fontStyle)
|
||||
{
|
||||
ScreenCoordsXY screenCoords(dpi->x, dpi->y);
|
||||
GfxDrawString(dpi, screenCoords, "", { COLOUR_BLACK, fontStyle });
|
||||
@@ -428,22 +433,22 @@ int32_t StringGetHeightRaw(std::string_view text, FontStyle fontStyle)
|
||||
* ticks : ebp >> 16
|
||||
*/
|
||||
void DrawNewsTicker(
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, void* args,
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, u8string_view args,
|
||||
int32_t ticks)
|
||||
{
|
||||
int32_t numLines, lineHeight, lineY;
|
||||
utf8* buffer = gCommonStringFormatBuffer;
|
||||
ScreenCoordsXY screenCoords(dpi->x, dpi->y);
|
||||
|
||||
GfxDrawString(dpi, screenCoords, "", { colour });
|
||||
FormatStringLegacy(buffer, 256, format, args);
|
||||
|
||||
GfxWrapString(buffer, width, FontStyle::Small, &numLines);
|
||||
u8string wrappedString;
|
||||
GfxWrapString(FormatStringID(format, args), width, FontStyle::Small, &wrappedString, &numLines);
|
||||
lineHeight = FontGetLineHeight(FontStyle::Small);
|
||||
|
||||
int32_t numCharactersDrawn = 0;
|
||||
int32_t numCharactersToDraw = ticks;
|
||||
|
||||
const utf8* buffer = wrappedString.data();
|
||||
lineY = coords.y - ((numLines * lineHeight) / 2);
|
||||
for (int32_t line = 0; line <= numLines; line++)
|
||||
{
|
||||
|
||||
@@ -524,15 +524,16 @@ void GfxDrawString(DrawPixelInfo* dpi, const ScreenCoordsXY& coords, const_utf8s
|
||||
void GfxDrawStringNoFormatting(DrawPixelInfo* dpi, const ScreenCoordsXY& coords, const_utf8string buffer, TextPaint textPaint);
|
||||
|
||||
void GfxDrawStringLeftCentred(DrawPixelInfo* dpi, StringId format, void* args, colour_t colour, const ScreenCoordsXY& coords);
|
||||
void DrawStringCentredRaw(DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t numLines, char* text, FontStyle fontStyle);
|
||||
void DrawStringCentredRaw(
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t numLines, const utf8* text, FontStyle fontStyle);
|
||||
void DrawNewsTicker(
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, void* args,
|
||||
DrawPixelInfo* dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, u8string_view args,
|
||||
int32_t ticks);
|
||||
void GfxDrawStringWithYOffsets(
|
||||
DrawPixelInfo* dpi, const utf8* text, int32_t colour, const ScreenCoordsXY& coords, const int8_t* yOffsets,
|
||||
bool forceSpriteFont, FontStyle fontStyle);
|
||||
|
||||
int32_t GfxWrapString(char* buffer, int32_t width, FontStyle fontStyle, int32_t* num_lines);
|
||||
int32_t GfxWrapString(u8string_view text, int32_t width, FontStyle fontStyle, u8string* outWrappedText, int32_t* outNumLines);
|
||||
int32_t GfxGetStringWidth(std::string_view text, FontStyle fontStyle);
|
||||
int32_t GfxGetStringWidthNewLined(std::string_view text, FontStyle fontStyle);
|
||||
int32_t GfxGetStringWidthNoFormatting(std::string_view text, FontStyle fontStyle);
|
||||
|
||||
@@ -22,19 +22,17 @@ static void DrawText(
|
||||
class StaticLayout
|
||||
{
|
||||
private:
|
||||
utf8string Buffer;
|
||||
u8string Buffer;
|
||||
TextPaint Paint;
|
||||
int32_t LineCount = 0;
|
||||
int32_t LineHeight;
|
||||
int32_t MaxWidth;
|
||||
|
||||
public:
|
||||
StaticLayout(utf8string source, const TextPaint& paint, int32_t width)
|
||||
StaticLayout(u8string_view source, const TextPaint& paint, int32_t width)
|
||||
: Paint(paint)
|
||||
{
|
||||
Buffer = source;
|
||||
Paint = paint;
|
||||
|
||||
MaxWidth = GfxWrapString(Buffer, width, paint.FontStyle, &LineCount);
|
||||
MaxWidth = GfxWrapString(source, width, paint.FontStyle, &Buffer, &LineCount);
|
||||
LineCount += 1;
|
||||
LineHeight = FontGetLineHeight(paint.FontStyle);
|
||||
}
|
||||
@@ -55,7 +53,7 @@ public:
|
||||
lineCoords.x += MaxWidth;
|
||||
break;
|
||||
}
|
||||
utf8* buffer = Buffer;
|
||||
const utf8* buffer = Buffer.data();
|
||||
for (int32_t line = 0; line < LineCount; ++line)
|
||||
{
|
||||
DrawText(dpi, lineCoords, tempPaint, buffer);
|
||||
@@ -175,9 +173,7 @@ int32_t DrawTextWrapped(
|
||||
{
|
||||
const void* args = ft.Data();
|
||||
|
||||
// TODO: Refactor StaticLayout to take a std::string_view instead. It shouldn't have to write to the buffer.
|
||||
const std::string buffer = FormatStringID(format, args);
|
||||
StaticLayout layout(const_cast<char*>(buffer.c_str()), textPaint, width);
|
||||
StaticLayout layout(FormatStringID(format, args), textPaint, width);
|
||||
|
||||
if (textPaint.Alignment == TextAlignment::CENTRE)
|
||||
{
|
||||
|
||||
@@ -109,7 +109,7 @@ void ChatDraw(DrawPixelInfo* dpi, uint8_t chatBackgroundColor)
|
||||
// Draw chat window
|
||||
if (gChatOpen)
|
||||
{
|
||||
inputLineHeight = ChatStringWrappedGetHeight(static_cast<void*>(&inputLine), _chatWidth - 10);
|
||||
inputLineHeight = ChatStringWrappedGetHeight(inputLine, _chatWidth - 10);
|
||||
_chatTop -= inputLineHeight;
|
||||
|
||||
for (int32_t i = 0; i < CHAT_HISTORY_SIZE; i++)
|
||||
@@ -120,8 +120,7 @@ void ChatDraw(DrawPixelInfo* dpi, uint8_t chatBackgroundColor)
|
||||
}
|
||||
|
||||
lineBuffer.assign(ChatGetHistory(i));
|
||||
auto lineCh = lineBuffer.c_str();
|
||||
int32_t lineHeight = ChatStringWrappedGetHeight(static_cast<void*>(&lineCh), _chatWidth - 10);
|
||||
int32_t lineHeight = ChatStringWrappedGetHeight(lineBuffer, _chatWidth - 10);
|
||||
_chatTop -= (lineHeight + 5);
|
||||
}
|
||||
|
||||
@@ -272,12 +271,9 @@ static void ChatClearInput()
|
||||
// But this adjusts the initial Y coordinate depending of the number of lines.
|
||||
static int32_t ChatHistoryDrawString(DrawPixelInfo* dpi, const char* text, const ScreenCoordsXY& screenCoords, int32_t width)
|
||||
{
|
||||
char buffer[CommonTextBufferSize];
|
||||
auto bufferPtr = buffer;
|
||||
FormatStringToBuffer(buffer, sizeof(buffer), "{OUTLINE}{WHITE}{STRING}", text);
|
||||
|
||||
int32_t numLines;
|
||||
GfxWrapString(bufferPtr, width, FontStyle::Medium, &numLines);
|
||||
u8string wrappedString;
|
||||
GfxWrapString(FormatString("{OUTLINE}{WHITE}{STRING}", text), width, FontStyle::Medium, &wrappedString, &numLines);
|
||||
auto lineHeight = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
int32_t expectedY = screenCoords.y - (numLines * lineHeight);
|
||||
@@ -286,7 +282,8 @@ static int32_t ChatHistoryDrawString(DrawPixelInfo* dpi, const char* text, const
|
||||
return (numLines * lineHeight); // Skip drawing, return total height.
|
||||
}
|
||||
|
||||
auto lineY = screenCoords.y;
|
||||
const utf8* bufferPtr = wrappedString.data();
|
||||
int32_t lineY = screenCoords.y;
|
||||
for (int32_t line = 0; line <= numLines; ++line)
|
||||
{
|
||||
GfxDrawString(dpi, { screenCoords.x, lineY - (numLines * lineHeight) }, bufferPtr, { TEXT_COLOUR_254 });
|
||||
@@ -298,22 +295,10 @@ static int32_t ChatHistoryDrawString(DrawPixelInfo* dpi, const char* text, const
|
||||
|
||||
// Wrap string without drawing, useful to get the height of a wrapped string.
|
||||
// Almost the same as gfx_draw_string_left_wrapped
|
||||
int32_t ChatStringWrappedGetHeight(void* args, int32_t width)
|
||||
int32_t ChatStringWrappedGetHeight(u8string_view args, int32_t width)
|
||||
{
|
||||
char buffer[CommonTextBufferSize];
|
||||
auto bufferPtr = buffer;
|
||||
FormatStringLegacy(bufferPtr, 256, STR_STRING, args);
|
||||
|
||||
int32_t numLines;
|
||||
GfxWrapString(bufferPtr, width, FontStyle::Medium, &numLines);
|
||||
int32_t lineHeight = FontGetLineHeight(FontStyle::Medium);
|
||||
|
||||
int32_t lineY = 0;
|
||||
for (int32_t line = 0; line <= numLines; ++line)
|
||||
{
|
||||
bufferPtr = GetStringEnd(bufferPtr) + 1;
|
||||
lineY += lineHeight;
|
||||
}
|
||||
|
||||
return lineY;
|
||||
GfxWrapString(FormatStringID(STR_STRING, args), width, FontStyle::Medium, nullptr, &numLines);
|
||||
const int32_t lineHeight = FontGetLineHeight(FontStyle::Medium);
|
||||
return lineHeight * numLines;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/String.hpp"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
@@ -42,4 +43,4 @@ void ChatDraw(DrawPixelInfo* dpi, uint8_t chatBackgroundColour);
|
||||
void ChatAddHistory(std::string_view s);
|
||||
void ChatInput(ChatInput input);
|
||||
|
||||
int32_t ChatStringWrappedGetHeight(void* args, int32_t width);
|
||||
int32_t ChatStringWrappedGetHeight(u8string_view args, int32_t width);
|
||||
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
Guard::ArgumentNotNull(path);
|
||||
|
||||
// Load file directly into memory
|
||||
std::vector<utf8> fileData;
|
||||
u8string fileData;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user