From a45d16b4ed2698361ff68c5502bcabfc908099a7 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 4 Jul 2023 06:01:29 +1000 Subject: [PATCH] Cache font directives --- source/rendering/StarFontTextureGroup.cpp | 20 +++++++++----------- source/rendering/StarFontTextureGroup.hpp | 7 ++++--- source/rendering/StarTextPainter.cpp | 21 +++++++++++++++------ source/rendering/StarTextPainter.hpp | 6 +++--- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/source/rendering/StarFontTextureGroup.cpp b/source/rendering/StarFontTextureGroup.cpp index 6a33d32..a951358 100644 --- a/source/rendering/StarFontTextureGroup.cpp +++ b/source/rendering/StarFontTextureGroup.cpp @@ -39,23 +39,21 @@ void FontTextureGroup::clearFonts() { m_font = m_defaultFont; } -const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Char c, unsigned size, String const& processingDirectives) +const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Char c, unsigned size, Directives const* processingDirectives) { - auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives, m_font.get() }, GlyphTexture()); + auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives ? processingDirectives->hash() : 0, m_font.get()}, GlyphTexture()); if (res.second) { m_font->setPixelSize(size); auto pair = m_font->render(c); Image& image = pair.first; - if (!processingDirectives.empty()) { + if (processingDirectives && *processingDirectives) { try { Vec2F preSize = Vec2F(image.size()); - auto imageOperations = parseImageOperations(processingDirectives); - for (auto& imageOp : imageOperations) { - if (auto border = imageOp.ptr()) - border->includeTransparent = true; - } - image = processImageOperations(imageOperations, image); + + for (auto& entry : processingDirectives->shared->entries) + processImageOperation(entry.operation, image); + res.first->second.offset = (preSize - Vec2F(image.size())) / 2; } catch (StarException&) { @@ -76,10 +74,10 @@ const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Cha } TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size) { - return glyphTexture(c, size, "").texture; + return glyphTexture(c, size, nullptr).texture; } -TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size, String const& processingDirectives) { +TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size, Directives const* processingDirectives) { return glyphTexture(c, size, processingDirectives).texture; } diff --git a/source/rendering/StarFontTextureGroup.hpp b/source/rendering/StarFontTextureGroup.hpp index 6bbb120..ecca6f6 100644 --- a/source/rendering/StarFontTextureGroup.hpp +++ b/source/rendering/StarFontTextureGroup.hpp @@ -4,6 +4,7 @@ #include "StarColor.hpp" #include "StarFont.hpp" #include "StarRenderer.hpp" +#include "StarDirectives.hpp" namespace Star { @@ -12,7 +13,7 @@ STAR_CLASS(FontTextureGroup); class FontTextureGroup { public: // Font* is only included for key uniqueness and should not be dereferenced - typedef tuple GlyphDescriptor; + typedef tuple GlyphDescriptor; struct GlyphTexture { TexturePtr texture; @@ -22,10 +23,10 @@ public: FontTextureGroup(TextureGroupPtr textureGroup); - const GlyphTexture& glyphTexture(String::Char, unsigned fontSize, String const& processingDirectives); + const GlyphTexture& glyphTexture(String::Char, unsigned fontSize, Directives const* processingDirectives = nullptr); TexturePtr glyphTexturePtr(String::Char, unsigned fontSize); - TexturePtr glyphTexturePtr(String::Char, unsigned fontSize, String const& processingDirectives); + TexturePtr glyphTexturePtr(String::Char, unsigned fontSize, Directives const* processingDirectives = nullptr); unsigned glyphWidth(String::Char c, unsigned fontSize); diff --git a/source/rendering/StarTextPainter.cpp b/source/rendering/StarTextPainter.cpp index d6078dc..3e6c618 100644 --- a/source/rendering/StarTextPainter.cpp +++ b/source/rendering/StarTextPainter.cpp @@ -402,8 +402,15 @@ void TextPainter::setFontColor(Vec4B color) { m_renderSettings.color = move(color); } -void TextPainter::setProcessingDirectives(String directives) { - m_renderSettings.directives = move(directives); +void TextPainter::setProcessingDirectives(StringView directives) { + m_renderSettings.directives = String(directives); + if (m_renderSettings.directives) { + m_renderSettings.directives.loadOperations(); + for (auto& entry : m_renderSettings.directives.shared->entries) { + if (auto border = entry.operation.ptr()) + border->includeTransparent = true; + } + } } void TextPainter::setFont(String const& font) { @@ -450,7 +457,7 @@ void TextPainter::applyCommands(StringView unsplitCommands) { } else if (command.beginsWith("directives=")) { // Honestly this is really stupid but I just couldn't help myself // Should probably limit in the future - m_renderSettings.directives = command.substr(11); + setProcessingDirectives(command.substr(11)); } else { // expects both #... sequences and plain old color names. Color c = Color(command); @@ -559,6 +566,8 @@ RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position else if (position.vAnchor == VerticalAnchor::TopAnchor) vOffset = -(float)m_fontSize; + Directives* directives = m_renderSettings.directives ? &m_renderSettings.directives : nullptr; + if (reallyRender) { if ((int)m_renderSettings.mode & (int)FontMode::Shadow) { Color shadow = Color::Black; @@ -571,17 +580,17 @@ RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position shadow.setAlpha(alphaU); //Kae: Draw only one shadow glyph instead of stacking two, alpha modified to appear perceptually the same as vanilla - renderGlyph(c, position.pos + Vec2F(hOffset, vOffset - 2), m_fontSize, 1, shadow.toRgba(), m_renderSettings.directives); + renderGlyph(c, position.pos + Vec2F(hOffset, vOffset - 2), m_fontSize, 1, shadow.toRgba(), directives); } - renderGlyph(c, position.pos + Vec2F(hOffset, vOffset), m_fontSize, 1, m_renderSettings.color, m_renderSettings.directives); + renderGlyph(c, position.pos + Vec2F(hOffset, vOffset), m_fontSize, 1, m_renderSettings.color, directives); } return RectF::withSize(position.pos + Vec2F(hOffset, vOffset), {(float)width, (int)m_fontSize}); } void TextPainter::renderGlyph(String::Char c, Vec2F const& screenPos, unsigned fontSize, - float scale, Vec4B const& color, String const& processingDirectives) { + float scale, Vec4B const& color, Directives const* processingDirectives) { if (!fontSize) return; diff --git a/source/rendering/StarTextPainter.hpp b/source/rendering/StarTextPainter.hpp index 1a0b1d9..7f132fd 100644 --- a/source/rendering/StarTextPainter.hpp +++ b/source/rendering/StarTextPainter.hpp @@ -78,7 +78,7 @@ public: void setLineSpacing(float lineSpacing); void setMode(FontMode mode); void setFontColor(Vec4B color); - void setProcessingDirectives(String directives); + void setProcessingDirectives(StringView directives); void setFont(String const& font); void addFont(FontPtr const& font, String const& name); void reloadFonts(); @@ -90,14 +90,14 @@ private: FontMode mode; Vec4B color; String font; - String directives; + Directives directives; }; RectF doRenderText(StringView s, TextPositioning const& position, bool reallyRender, unsigned* charLimit); RectF doRenderLine(StringView s, TextPositioning const& position, bool reallyRender, unsigned* charLimit); RectF doRenderGlyph(String::Char c, TextPositioning const& position, bool reallyRender); - void renderGlyph(String::Char c, Vec2F const& screenPos, unsigned fontSize, float scale, Vec4B const& color, String const& processingDirectives); + void renderGlyph(String::Char c, Vec2F const& screenPos, unsigned fontSize, float scale, Vec4B const& color, Directives const* processingDirectives = nullptr); RendererPtr m_renderer; FontTextureGroup m_fontTextureGroup;