Cache font directives

This commit is contained in:
Kae 2023-07-04 06:01:29 +10:00
parent 1d04c689ba
commit a45d16b4ed
4 changed files with 31 additions and 23 deletions

View File

@ -39,23 +39,21 @@ void FontTextureGroup::clearFonts() {
m_font = m_defaultFont; 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) { if (res.second) {
m_font->setPixelSize(size); m_font->setPixelSize(size);
auto pair = m_font->render(c); auto pair = m_font->render(c);
Image& image = pair.first; Image& image = pair.first;
if (!processingDirectives.empty()) { if (processingDirectives && *processingDirectives) {
try { try {
Vec2F preSize = Vec2F(image.size()); Vec2F preSize = Vec2F(image.size());
auto imageOperations = parseImageOperations(processingDirectives);
for (auto& imageOp : imageOperations) { for (auto& entry : processingDirectives->shared->entries)
if (auto border = imageOp.ptr<BorderImageOperation>()) processImageOperation(entry.operation, image);
border->includeTransparent = true;
}
image = processImageOperations(imageOperations, image);
res.first->second.offset = (preSize - Vec2F(image.size())) / 2; res.first->second.offset = (preSize - Vec2F(image.size())) / 2;
} }
catch (StarException&) { catch (StarException&) {
@ -76,10 +74,10 @@ const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Cha
} }
TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size) { 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; return glyphTexture(c, size, processingDirectives).texture;
} }

View File

@ -4,6 +4,7 @@
#include "StarColor.hpp" #include "StarColor.hpp"
#include "StarFont.hpp" #include "StarFont.hpp"
#include "StarRenderer.hpp" #include "StarRenderer.hpp"
#include "StarDirectives.hpp"
namespace Star { namespace Star {
@ -12,7 +13,7 @@ STAR_CLASS(FontTextureGroup);
class FontTextureGroup { class FontTextureGroup {
public: public:
// Font* is only included for key uniqueness and should not be dereferenced // Font* is only included for key uniqueness and should not be dereferenced
typedef tuple<String::Char, unsigned, String, Font*> GlyphDescriptor; typedef tuple<String::Char, unsigned, size_t, Font*> GlyphDescriptor;
struct GlyphTexture { struct GlyphTexture {
TexturePtr texture; TexturePtr texture;
@ -22,10 +23,10 @@ public:
FontTextureGroup(TextureGroupPtr textureGroup); 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);
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); unsigned glyphWidth(String::Char c, unsigned fontSize);

View File

@ -402,8 +402,15 @@ void TextPainter::setFontColor(Vec4B color) {
m_renderSettings.color = move(color); m_renderSettings.color = move(color);
} }
void TextPainter::setProcessingDirectives(String directives) { void TextPainter::setProcessingDirectives(StringView directives) {
m_renderSettings.directives = move(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<BorderImageOperation>())
border->includeTransparent = true;
}
}
} }
void TextPainter::setFont(String const& font) { void TextPainter::setFont(String const& font) {
@ -450,7 +457,7 @@ void TextPainter::applyCommands(StringView unsplitCommands) {
} else if (command.beginsWith("directives=")) { } else if (command.beginsWith("directives=")) {
// Honestly this is really stupid but I just couldn't help myself // Honestly this is really stupid but I just couldn't help myself
// Should probably limit in the future // Should probably limit in the future
m_renderSettings.directives = command.substr(11); setProcessingDirectives(command.substr(11));
} else { } else {
// expects both #... sequences and plain old color names. // expects both #... sequences and plain old color names.
Color c = Color(command); Color c = Color(command);
@ -559,6 +566,8 @@ RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position
else if (position.vAnchor == VerticalAnchor::TopAnchor) else if (position.vAnchor == VerticalAnchor::TopAnchor)
vOffset = -(float)m_fontSize; vOffset = -(float)m_fontSize;
Directives* directives = m_renderSettings.directives ? &m_renderSettings.directives : nullptr;
if (reallyRender) { if (reallyRender) {
if ((int)m_renderSettings.mode & (int)FontMode::Shadow) { if ((int)m_renderSettings.mode & (int)FontMode::Shadow) {
Color shadow = Color::Black; Color shadow = Color::Black;
@ -571,17 +580,17 @@ RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position
shadow.setAlpha(alphaU); shadow.setAlpha(alphaU);
//Kae: Draw only one shadow glyph instead of stacking two, alpha modified to appear perceptually the same as vanilla //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}); return RectF::withSize(position.pos + Vec2F(hOffset, vOffset), {(float)width, (int)m_fontSize});
} }
void TextPainter::renderGlyph(String::Char c, Vec2F const& screenPos, unsigned 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) if (!fontSize)
return; return;

View File

@ -78,7 +78,7 @@ public:
void setLineSpacing(float lineSpacing); void setLineSpacing(float lineSpacing);
void setMode(FontMode mode); void setMode(FontMode mode);
void setFontColor(Vec4B color); void setFontColor(Vec4B color);
void setProcessingDirectives(String directives); void setProcessingDirectives(StringView directives);
void setFont(String const& font); void setFont(String const& font);
void addFont(FontPtr const& font, String const& name); void addFont(FontPtr const& font, String const& name);
void reloadFonts(); void reloadFonts();
@ -90,14 +90,14 @@ private:
FontMode mode; FontMode mode;
Vec4B color; Vec4B color;
String font; String font;
String directives; Directives directives;
}; };
RectF doRenderText(StringView s, TextPositioning const& position, bool reallyRender, unsigned* charLimit); RectF doRenderText(StringView s, TextPositioning const& position, bool reallyRender, unsigned* charLimit);
RectF doRenderLine(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); 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; RendererPtr m_renderer;
FontTextureGroup m_fontTextureGroup; FontTextureGroup m_fontTextureGroup;