summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorSmallJoker <mk939@ymail.com>2019-10-17 20:40:50 +0200
committerSmallJoker <SmallJoker@users.noreply.github.com>2019-11-03 11:45:33 +0100
commit388ea737f5d37d637556bf40890948bfc36734ce (patch)
tree2017f52301eb54bfd14d0da9804f337bc956a1f7 /src/client
parent72416a6a1f75d56abfad0f486e57fd32579b3604 (diff)
downloadminetest-388ea737f5d37d637556bf40890948bfc36734ce.tar.gz
minetest-388ea737f5d37d637556bf40890948bfc36734ce.tar.bz2
minetest-388ea737f5d37d637556bf40890948bfc36734ce.zip
Clean up font caching, fix bitmap fonts
Diffstat (limited to 'src/client')
-rw-r--r--src/client/fontengine.cpp117
-rw-r--r--src/client/fontengine.h68
2 files changed, 90 insertions, 95 deletions
diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp
index 8120f82df..26ceda4c5 100644
--- a/src/client/fontengine.cpp
+++ b/src/client/fontengine.cpp
@@ -41,11 +41,6 @@ static void font_setting_changed(const std::string &name, void *userdata)
g_fontengine->readSettings();
}
-unsigned int get_font_cache_index(FontMode mode, bool bold = false, bool italic = false)
-{
- return (mode << 2) | (bold << 1) | italic;
-}
-
/******************************************************************************/
FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) :
m_settings(main_settings),
@@ -106,45 +101,45 @@ void FontEngine::cleanCache()
}
/******************************************************************************/
-irr::gui::IGUIFont *FontEngine::getFont(unsigned int font_size, FontMode mode,
- bool bold, bool italic)
+irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec)
{
- if (mode == FM_Unspecified) {
- mode = m_currentMode;
+ if (spec.mode == FM_Unspecified) {
+ spec.mode = m_currentMode;
} else if (m_currentMode == FM_Simple) {
// Freetype disabled -> Force simple mode
- mode = (mode == FM_Mono || mode == FM_SimpleMono) ?
- FM_SimpleMono : FM_Simple;
+ spec.mode = (spec.mode == FM_Mono ||
+ spec.mode == FM_SimpleMono) ?
+ FM_SimpleMono : FM_Simple;
+ // Support for those could be added, but who cares?
+ spec.bold = false;
+ spec.italic = false;
}
// Fallback to default size
- if (font_size == FONT_SIZE_UNSPECIFIED)
- font_size = m_default_size[mode];
-
- unsigned int cache_index = get_font_cache_index(mode, bold, italic);
-
- const auto &cache = m_font_cache[cache_index];
-
- if (cache.find(font_size) == cache.end()) {
- if (mode == FM_Simple || mode == FM_SimpleMono)
- initSimpleFont(font_size, mode);
- else
- initFont(font_size, mode, bold, italic);
- }
+ if (spec.size == FONT_SIZE_UNSPECIFIED)
+ spec.size = m_default_size[spec.mode];
+
+ const auto &cache = m_font_cache[spec.getHash()];
+ auto it = cache.find(spec.size);
+ if (it != cache.end())
+ return it->second;
+
+ // Font does not yet exist
+ gui::IGUIFont *font = nullptr;
+ if (spec.mode == FM_Simple || spec.mode == FM_SimpleMono)
+ font = initSimpleFont(spec);
+ else
+ font = initFont(spec);
- if (m_font_cache[cache_index].find(font_size) ==
- m_font_cache[cache_index].end())
- initFont(font_size, mode, bold, italic);
+ m_font_cache[spec.getHash()][spec.size] = font;
- const auto &font = cache.find(font_size);
- return font != cache.end() ? font->second : nullptr;
+ return font;
}
/******************************************************************************/
-unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode,
- bool bold, bool italic)
+unsigned int FontEngine::getTextHeight(const FontSpec &spec)
{
- irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
+ irr::gui::IGUIFont *font = getFont(spec);
// use current skin font as fallback
if (font == NULL) {
@@ -156,10 +151,9 @@ unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode,
}
/******************************************************************************/
-unsigned int FontEngine::getTextWidth(const std::wstring& text,
- unsigned int font_size, FontMode mode, bool bold, bool italic)
+unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec)
{
- irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
+ irr::gui::IGUIFont *font = getFont(spec);
// use current skin font as fallback
if (font == NULL) {
@@ -172,10 +166,9 @@ unsigned int FontEngine::getTextWidth(const std::wstring& text,
/** get line height for a specific font (including empty room between lines) */
-unsigned int FontEngine::getLineHeight(unsigned int font_size, FontMode mode,
- bool bold, bool italic)
+unsigned int FontEngine::getLineHeight(const FontSpec &spec)
{
- irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
+ irr::gui::IGUIFont *font = getFont(spec);
// use current skin font as fallback
if (font == NULL) {
@@ -250,21 +243,14 @@ void FontEngine::updateFontCache()
}
/******************************************************************************/
-void FontEngine::initFont(unsigned int basesize, FontMode mode,
- bool bold, bool italic)
+gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
{
- assert(mode != FM_Unspecified);
- assert(basesize != FONT_SIZE_UNSPECIFIED);
-
- int cache_index = get_font_cache_index(mode, bold, italic);
-
- if (m_font_cache[cache_index].find(basesize) !=
- m_font_cache[cache_index].end())
- return;
+ assert(spec.mode != FM_Unspecified);
+ assert(spec.size != FONT_SIZE_UNSPECIFIED);
std::string setting_prefix = "";
- switch (mode) {
+ switch (spec.mode) {
case FM_Fallback:
setting_prefix = "fallback_";
break;
@@ -276,12 +262,14 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode,
break;
}
- std::string setting_suffix = (bold) ?
- ((italic) ? "_bold_italic" : "_bold") :
- ((italic) ? "_italic" : "");
+ std::string setting_suffix = "";
+ if (spec.bold)
+ setting_suffix.append("_bold");
+ if (spec.italic)
+ setting_suffix.append("_italic");
u32 size = std::floor(RenderingEngine::getDisplayDensity() *
- m_settings->getFloat("gui_scaling") * basesize);
+ m_settings->getFloat("gui_scaling") * spec.size);
if (size == 0) {
errorstream << "FontEngine: attempt to use font size 0" << std::endl;
@@ -310,10 +298,8 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode,
font_path.c_str(), size, true, true, font_shadow,
font_shadow_alpha);
- if (font) {
- m_font_cache[cache_index][basesize] = font;
- return;
- }
+ if (font)
+ return font;
errorstream << "FontEngine: Cannot load '" << font_path <<
"'. Trying to fall back to another path." << std::endl;
@@ -332,12 +318,13 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode,
}
/** initialize a font without freetype */
-void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
+gui::IGUIFont *FontEngine::initSimpleFont(const FontSpec &spec)
{
- assert(mode == FM_Simple || mode == FM_SimpleMono);
+ assert(spec.mode == FM_Simple || spec.mode == FM_SimpleMono);
+ assert(spec.size != FONT_SIZE_UNSPECIFIED);
const std::string &font_path = m_settings->get(
- (mode == FM_SimpleMono) ? "mono_font_path" : "font_path");
+ (spec.mode == FM_SimpleMono) ? "mono_font_path" : "font_path");
size_t pos_dot = font_path.find_last_of('.');
std::string basename = font_path;
@@ -346,19 +333,16 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
if (ending == ".ttf") {
errorstream << "FontEngine: Found font \"" << font_path
<< "\" but freetype is not available." << std::endl;
- return;
+ return nullptr;
}
if (ending == ".xml" || ending == ".png")
basename = font_path.substr(0, pos_dot);
- if (basesize == FONT_SIZE_UNSPECIFIED)
- basesize = DEFAULT_FONT_SIZE;
-
u32 size = std::floor(
RenderingEngine::getDisplayDensity() *
m_settings->getFloat("gui_scaling") *
- basesize);
+ spec.size);
irr::gui::IGUIFont *font = nullptr;
std::string font_extensions[] = { ".png", ".xml" };
@@ -400,6 +384,5 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
}
}
- if (font)
- m_font_cache[get_font_cache_index(mode)][basesize] = font;
+ return font;
}
diff --git a/src/client/fontengine.h b/src/client/fontengine.h
index ecffc7660..53f14c45f 100644
--- a/src/client/fontengine.h
+++ b/src/client/fontengine.h
@@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
-enum FontMode {
+enum FontMode : u8 {
FM_Standard = 0,
FM_Mono,
FM_Fallback,
@@ -39,6 +39,24 @@ enum FontMode {
FM_Unspecified
};
+struct FontSpec {
+ FontSpec(unsigned int font_size, FontMode mode, bool bold, bool italic) :
+ size(font_size),
+ mode(mode),
+ bold(bold),
+ italic(italic) {}
+
+ u16 getHash()
+ {
+ return (mode << 2) | (bold << 1) | italic;
+ }
+
+ unsigned int size;
+ FontMode mode;
+ bool bold;
+ bool italic;
+};
+
class FontEngine
{
public:
@@ -47,62 +65,60 @@ public:
~FontEngine();
- /** get Font */
- irr::gui::IGUIFont *getFont(unsigned int font_size, FontMode mode,
- bool bold, bool italic);
+ // Get best possible font specified by FontSpec
+ irr::gui::IGUIFont *getFont(FontSpec spec);
irr::gui::IGUIFont *getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
- return getFont(font_size, mode, m_default_bold, m_default_italic);
+ FontSpec spec(font_size, mode, m_default_bold, m_default_italic);
+ return getFont(spec);
}
/** get text height for a specific font */
- unsigned int getTextHeight(unsigned int font_size, FontMode mode,
- bool bold, bool italic);
+ unsigned int getTextHeight(const FontSpec &spec);
/** get text width if a text for a specific font */
unsigned int getTextHeight(
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
- return getTextHeight(font_size, mode, m_default_bold, m_default_italic);
+ FontSpec spec(font_size, mode, m_default_bold, m_default_italic);
+ return getTextHeight(spec);
}
- unsigned int getTextWidth(const std::wstring& text,
- unsigned int font_size, FontMode mode, bool bold, bool italic);
+ unsigned int getTextWidth(const std::wstring &text, const FontSpec &spec);
/** get text width if a text for a specific font */
unsigned int getTextWidth(const std::wstring& text,
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
- return getTextWidth(text, font_size, mode, m_default_bold,
- m_default_italic);
+ FontSpec spec(font_size, mode, m_default_bold, m_default_italic);
+ return getTextWidth(text, spec);
}
- unsigned int getTextWidth(const std::string& text,
- unsigned int font_size, FontMode mode, bool bold, bool italic)
+ unsigned int getTextWidth(const std::string &text, const FontSpec &spec)
{
- return getTextWidth(utf8_to_wide(text), font_size, mode, bold, italic);
+ return getTextWidth(utf8_to_wide(text), spec);
}
unsigned int getTextWidth(const std::string& text,
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
- return getTextWidth(utf8_to_wide(text), font_size, mode, m_default_bold,
- m_default_italic);
+ FontSpec spec(font_size, mode, m_default_bold, m_default_italic);
+ return getTextWidth(utf8_to_wide(text), spec);
}
/** get line height for a specific font (including empty room between lines) */
- unsigned int getLineHeight(unsigned int font_size, FontMode mode, bool bold,
- bool italic);
+ unsigned int getLineHeight(const FontSpec &spec);
unsigned int getLineHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
- return getLineHeight(font_size, mode, m_default_bold, m_default_italic);
+ FontSpec spec(font_size, mode, m_default_bold, m_default_italic);
+ return getLineHeight(spec);
}
/** get default font size */
@@ -119,14 +135,10 @@ private:
void updateFontCache();
/** initialize a new font */
- void initFont(
- unsigned int basesize,
- FontMode mode,
- bool bold,
- bool italic);
+ gui::IGUIFont *initFont(const FontSpec &spec);
/** initialize a font without freetype */
- void initSimpleFont(unsigned int basesize, FontMode mode);
+ gui::IGUIFont *initSimpleFont(const FontSpec &spec);
/** update current minetest skin with font changes */
void updateSkin();
@@ -147,8 +159,8 @@ private:
unsigned int m_default_size[FM_MaxMode];
/** default bold and italic */
- bool m_default_bold;
- bool m_default_italic;
+ bool m_default_bold = false;
+ bool m_default_italic = false;
/** current font engine mode */
FontMode m_currentMode = FM_Standard;