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;
}
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<BorderImageOperation>())
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;
}

View File

@ -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<String::Char, unsigned, String, Font*> GlyphDescriptor;
typedef tuple<String::Char, unsigned, size_t, Font*> 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);

View File

@ -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<BorderImageOperation>())
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;

View File

@ -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;