diff --git a/src/Components/Modules/TextRenderer.cpp b/src/Components/Modules/TextRenderer.cpp index 985eebef..bbf4b2bc 100644 --- a/src/Components/Modules/TextRenderer.cpp +++ b/src/Components/Modules/TextRenderer.cpp @@ -134,17 +134,45 @@ namespace Components return nullptr; } - bool TextRenderer::IsFontIcon(const char*& text, Game::Material*& fontIconMaterial) + bool TextRenderer::IsFontIcon(const char*& text, FontIconInfo& fontIcon) { const auto* curPos = text; - while (*curPos != ' ' && *curPos != ':' && *curPos != 0) + while (*curPos != ' ' && *curPos != ':' && *curPos != 0 && *curPos != '+') curPos++; + const auto* nameEnd = curPos; + + if(*curPos == '+') + { + auto breakArgs = false; + while(!breakArgs) + { + curPos++; + switch(*curPos) + { + case 'h': + fontIcon.flipHorizontal = true; + break; + + case 'v': + fontIcon.flipVertical = true; + break; + + case ':': + breakArgs = true; + break; + + default: + return false; + } + } + } + if (*curPos != ':') return false; - const std::string fontIconName(text, curPos - text); + const std::string fontIconName(text, nameEnd - text); auto* materialEntry = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_MATERIAL, fontIconName.data()); if (materialEntry == nullptr) @@ -154,21 +182,43 @@ namespace Components return false; text = curPos + 1; - fontIconMaterial = material; + fontIcon.material = material; return true; } - float TextRenderer::DrawFontIcon(Game::Material* fontIconMaterial, const float x, const float y, const float sinAngle, const float cosAngle, const Game::Font_s* font, const float xScale, const float yScale, const unsigned color) + float TextRenderer::DrawFontIcon(const FontIconInfo& fontIcon, const float x, const float y, const float sinAngle, const float cosAngle, const Game::Font_s* font, const float xScale, const float yScale, const unsigned color) { - const auto* colorMap = GetFontIconColorMap(fontIconMaterial); + const auto* colorMap = GetFontIconColorMap(fontIcon.material); if (colorMap == nullptr) return 0; + float s0, t0, s1, t1; + if(fontIcon.flipHorizontal) + { + s0 = 1.0f; + s1 = 0.0f; + } + else + { + s0 = 0.0f; + s1 = 1.0f; + } + if(fontIcon.flipVertical) + { + t0 = 1.0f; + t1 = 0.0f; + } + else + { + t0 = 0.0f; + t1 = 1.0f; + } + const auto h = static_cast(font->pixelHeight) * yScale; const auto w = static_cast(font->pixelHeight) * (static_cast(colorMap->width) / static_cast(colorMap->height)) * xScale; const auto yy = y - (h + yScale * static_cast(font->pixelHeight)) * 0.5f; - Game::RB_DrawStretchPicRotate(fontIconMaterial, x, yy, w, h, 0.0, 0.0, 1.0, 1.0, sinAngle, cosAngle, color); + Game::RB_DrawStretchPicRotate(fontIcon.material, x, yy, w, h, s0, t0, s1, t1, sinAngle, cosAngle, color); return w; } @@ -356,11 +406,11 @@ namespace Components if(letter == ':') { - Game::Material* fontIconMaterial; - if(IsFontIcon(curText, fontIconMaterial)) + FontIconInfo fontIconInfo{}; + if(IsFontIcon(curText, fontIconInfo)) { RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot); - xa += DrawFontIcon(fontIconMaterial, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, ColorRgba(255, 255, 255, finalColor.array[3])); + xa += DrawFontIcon(fontIconInfo, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, ColorRgba(255, 255, 255, finalColor.array[3])); if (renderFlags & Game::TEXT_RENDERFLAG_PADDING) xa += xScale * padding; diff --git a/src/Components/Modules/TextRenderer.hpp b/src/Components/Modules/TextRenderer.hpp index 6254401c..22289dd3 100644 --- a/src/Components/Modules/TextRenderer.hpp +++ b/src/Components/Modules/TextRenderer.hpp @@ -42,6 +42,13 @@ namespace Components class TextRenderer : public Component { + struct FontIconInfo + { + Game::Material* material; + bool flipHorizontal; + bool flipVertical; + }; + struct HsvColor { unsigned char h; @@ -74,12 +81,11 @@ namespace Components TextRenderer(); private: - static unsigned HsvToRgb(HsvColor hsv); static Game::GfxImage* GetFontIconColorMap(Game::Material* fontIconMaterial); - static bool IsFontIcon(const char*& text, Game::Material*& fontIconMaterial); - static float DrawFontIcon(Game::Material* fontIconMaterial, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color); + static bool IsFontIcon(const char*& text, FontIconInfo& fontIcon); + static float DrawFontIcon(const FontIconInfo& fontIcon, float x, float y, float sinAngle, float cosAngle, const Game::Font_s* font, float xScale, float yScale, unsigned color); static float GetMonospaceWidth(Game::Font_s* font, int rendererFlags); static void GlowColor(Game::GfxColor* result, Game::GfxColor baseColor, Game::GfxColor forcedGlowColor, int renderFlags);