mirror of https://github.com/OpenRCT2/OpenRCT2.git
173 lines
5.2 KiB
C++
173 lines
5.2 KiB
C++
/*****************************************************************************
|
|
* Copyright (c) 2014-2024 OpenRCT2 developers
|
|
*
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
|
*
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
|
*****************************************************************************/
|
|
|
|
#include "Text.h"
|
|
|
|
#include "../localisation/Formatter.h"
|
|
#include "../localisation/Formatting.h"
|
|
#include "../localisation/Localisation.h"
|
|
#include "Drawing.h"
|
|
|
|
class StaticLayout
|
|
{
|
|
private:
|
|
u8string Buffer;
|
|
TextPaint Paint;
|
|
int32_t LineCount = 0;
|
|
int32_t LineHeight;
|
|
int32_t MaxWidth;
|
|
|
|
public:
|
|
StaticLayout(u8string_view source, const TextPaint& paint, int32_t width)
|
|
: Paint(paint)
|
|
{
|
|
MaxWidth = GfxWrapString(source, width, paint.FontStyle, &Buffer, &LineCount);
|
|
LineCount += 1;
|
|
LineHeight = FontGetLineHeight(paint.FontStyle);
|
|
}
|
|
|
|
void Draw(DrawPixelInfo& dpi, const ScreenCoordsXY& coords)
|
|
{
|
|
TextPaint tempPaint = Paint;
|
|
|
|
auto lineCoords = coords;
|
|
switch (Paint.Alignment)
|
|
{
|
|
case TextAlignment::LEFT:
|
|
break;
|
|
case TextAlignment::CENTRE:
|
|
lineCoords.x += MaxWidth / 2;
|
|
break;
|
|
case TextAlignment::RIGHT:
|
|
lineCoords.x += MaxWidth;
|
|
break;
|
|
}
|
|
const utf8* buffer = Buffer.data();
|
|
for (int32_t line = 0; line < LineCount; ++line)
|
|
{
|
|
DrawText(dpi, lineCoords, tempPaint, buffer);
|
|
tempPaint.Colour = TEXT_COLOUR_254;
|
|
buffer = GetStringEnd(buffer) + 1;
|
|
lineCoords.y += LineHeight;
|
|
}
|
|
}
|
|
|
|
int32_t GetHeight() const
|
|
{
|
|
return LineHeight * LineCount;
|
|
}
|
|
|
|
int32_t GetWidth() const
|
|
{
|
|
return MaxWidth;
|
|
}
|
|
|
|
int32_t GetLineCount() const
|
|
{
|
|
return LineCount;
|
|
}
|
|
};
|
|
|
|
void DrawText(
|
|
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, const TextPaint& paint, const_utf8string text, bool noFormatting)
|
|
{
|
|
int32_t width = noFormatting ? GfxGetStringWidthNoFormatting(text, paint.FontStyle)
|
|
: GfxGetStringWidth(text, paint.FontStyle);
|
|
|
|
auto alignedCoords = coords;
|
|
switch (paint.Alignment)
|
|
{
|
|
case TextAlignment::LEFT:
|
|
break;
|
|
case TextAlignment::CENTRE:
|
|
alignedCoords.x -= (width - 1) / 2;
|
|
break;
|
|
case TextAlignment::RIGHT:
|
|
alignedCoords.x -= width;
|
|
break;
|
|
}
|
|
|
|
TTFDrawString(dpi, text, paint.Colour, alignedCoords, noFormatting, paint.FontStyle, paint.Darkness);
|
|
|
|
if (paint.UnderlineText == TextUnderline::On)
|
|
{
|
|
GfxFillRect(
|
|
dpi, { { alignedCoords + ScreenCoordsXY{ 0, 11 } }, { alignedCoords + ScreenCoordsXY{ width, 11 } } },
|
|
gTextPalette[1]);
|
|
if (gTextPalette[2] != 0)
|
|
{
|
|
GfxFillRect(
|
|
dpi, { { alignedCoords + ScreenCoordsXY{ 1, 12 } }, { alignedCoords + ScreenCoordsXY{ width + 1, 12 } } },
|
|
gTextPalette[2]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrawTextBasic(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, StringId format)
|
|
{
|
|
Formatter ft{};
|
|
TextPaint textPaint{};
|
|
DrawTextBasic(dpi, coords, format, ft, textPaint);
|
|
}
|
|
|
|
void DrawTextBasic(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, StringId format, const Formatter& ft, TextPaint textPaint)
|
|
{
|
|
utf8 buffer[512];
|
|
OpenRCT2::FormatStringLegacy(buffer, sizeof(buffer), format, ft.Data());
|
|
DrawText(dpi, coords, textPaint, buffer);
|
|
}
|
|
|
|
void DrawTextEllipsised(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, StringId format)
|
|
{
|
|
Formatter ft{};
|
|
TextPaint textPaint{};
|
|
DrawTextEllipsised(dpi, coords, width, format, ft, textPaint);
|
|
}
|
|
|
|
void DrawTextEllipsised(
|
|
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, StringId format, const Formatter& ft, TextPaint textPaint)
|
|
{
|
|
utf8 buffer[512];
|
|
OpenRCT2::FormatStringLegacy(buffer, sizeof(buffer), format, ft.Data());
|
|
GfxClipString(buffer, width, textPaint.FontStyle);
|
|
|
|
DrawText(dpi, coords, textPaint, buffer);
|
|
}
|
|
|
|
int32_t DrawTextWrapped(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, StringId format)
|
|
{
|
|
Formatter ft{};
|
|
TextPaint textPaint{};
|
|
return DrawTextWrapped(dpi, coords, width, format, ft, textPaint);
|
|
}
|
|
|
|
int32_t DrawTextWrapped(
|
|
DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, StringId format, const Formatter& ft, TextPaint textPaint)
|
|
{
|
|
const void* args = ft.Data();
|
|
|
|
StaticLayout layout(FormatStringIDLegacy(format, args), textPaint, width);
|
|
|
|
if (textPaint.Alignment == TextAlignment::CENTRE)
|
|
{
|
|
// The original tried to vertically centre the text, but used line count - 1
|
|
int32_t lineCount = layout.GetLineCount();
|
|
int32_t lineHeight = layout.GetHeight() / lineCount;
|
|
int32_t yOffset = (lineCount - 1) * lineHeight / 2;
|
|
|
|
layout.Draw(dpi, coords - ScreenCoordsXY{ layout.GetWidth() / 2, yOffset });
|
|
}
|
|
else
|
|
{
|
|
layout.Draw(dpi, coords);
|
|
}
|
|
|
|
return layout.GetHeight();
|
|
}
|