diff options
author | sfan5 <sfan5@live.de> | 2021-03-29 19:55:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-29 19:55:24 +0200 |
commit | 8d89f5f0cc1db47542bd355babad06b6bda54f51 (patch) | |
tree | 50cab3ca26b0c6e3f8f6435fb0ffcc47f6b50e1c /src/client | |
parent | 5f4c78a77d99834887a714944899df92a4ebb573 (diff) | |
download | minetest-8d89f5f0cc1db47542bd355babad06b6bda54f51.tar.gz minetest-8d89f5f0cc1db47542bd355babad06b6bda54f51.tar.bz2 minetest-8d89f5f0cc1db47542bd355babad06b6bda54f51.zip |
Replace fallback font nonsense with automatic per-glyph fallback (#11084)
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/fontengine.cpp | 95 | ||||
-rw-r--r-- | src/client/fontengine.h | 8 |
2 files changed, 49 insertions, 54 deletions
diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp index 47218c0d9..0382c2f18 100644 --- a/src/client/fontengine.cpp +++ b/src/client/fontengine.cpp @@ -56,7 +56,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) : readSettings(); - if (m_currentMode == FM_Standard) { + if (m_currentMode != FM_Simple) { g_settings->registerChangedCallback("font_size", font_setting_changed, NULL); g_settings->registerChangedCallback("font_bold", font_setting_changed, NULL); g_settings->registerChangedCallback("font_italic", font_setting_changed, NULL); @@ -66,12 +66,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) : g_settings->registerChangedCallback("font_path_bolditalic", font_setting_changed, NULL); g_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL); g_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL); - } - else if (m_currentMode == FM_Fallback) { - g_settings->registerChangedCallback("fallback_font_size", font_setting_changed, NULL); g_settings->registerChangedCallback("fallback_font_path", font_setting_changed, NULL); - g_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed, NULL); - g_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed, NULL); } g_settings->registerChangedCallback("mono_font_path", font_setting_changed, NULL); @@ -102,6 +97,11 @@ void FontEngine::cleanCache() /******************************************************************************/ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec) { + return getFont(spec, false); +} + +irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail) +{ if (spec.mode == FM_Unspecified) { spec.mode = m_currentMode; } else if (m_currentMode == FM_Simple) { @@ -112,6 +112,10 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec) // Support for those could be added, but who cares? spec.bold = false; spec.italic = false; + } else if (spec.mode == _FM_Fallback) { + // Fallback font doesn't support these either + spec.bold = false; + spec.italic = false; } // Fallback to default size @@ -130,6 +134,13 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec) else font = initFont(spec); + if (!font && !may_fail) { + errorstream << "Minetest cannot continue without a valid font. " + "Please correct the 'font_path' setting or install the font " + "file in the proper location." << std::endl; + abort(); + } + m_font_cache[spec.getHash()][spec.size] = font; return font; @@ -204,20 +215,9 @@ unsigned int FontEngine::getFontSize(FontMode mode) void FontEngine::readSettings() { if (USE_FREETYPE && g_settings->getBool("freetype")) { - m_default_size[FM_Standard] = g_settings->getU16("font_size"); - m_default_size[FM_Fallback] = g_settings->getU16("fallback_font_size"); - m_default_size[FM_Mono] = g_settings->getU16("mono_font_size"); - - /*~ DO NOT TRANSLATE THIS LITERALLY! - This is a special string. Put either "no" or "yes" - into the translation field (literally). - Choose "yes" if the language requires use of the fallback - font, "no" otherwise. - The fallback font is (normally) required for languages with - non-Latin script, like Chinese. - When in doubt, test your translation. */ - m_currentMode = is_yes(gettext("needs_fallback_font")) ? - FM_Fallback : FM_Standard; + m_default_size[FM_Standard] = g_settings->getU16("font_size"); + m_default_size[_FM_Fallback] = g_settings->getU16("font_size"); + m_default_size[FM_Mono] = g_settings->getU16("mono_font_size"); m_default_bold = g_settings->getBool("font_bold"); m_default_italic = g_settings->getBool("font_italic"); @@ -271,18 +271,8 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) assert(spec.size != FONT_SIZE_UNSPECIFIED); std::string setting_prefix = ""; - - switch (spec.mode) { - case FM_Fallback: - setting_prefix = "fallback_"; - break; - case FM_Mono: - case FM_SimpleMono: - setting_prefix = "mono_"; - break; - default: - break; - } + if (spec.mode == FM_Mono) + setting_prefix = "mono_"; std::string setting_suffix = ""; if (spec.bold) @@ -305,38 +295,41 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha", font_shadow_alpha); - std::string wanted_font_path; - wanted_font_path = g_settings->get(setting_prefix + "font_path" + setting_suffix); + std::string path_setting; + if (spec.mode == _FM_Fallback) + path_setting = "fallback_font_path"; + else + path_setting = setting_prefix + "font_path" + setting_suffix; std::string fallback_settings[] = { - wanted_font_path, - g_settings->get("fallback_font_path"), - Settings::getLayer(SL_DEFAULTS)->get(setting_prefix + "font_path") + g_settings->get(path_setting), + Settings::getLayer(SL_DEFAULTS)->get(path_setting) }; #if USE_FREETYPE for (const std::string &font_path : fallback_settings) { - irr::gui::IGUIFont *font = gui::CGUITTFont::createTTFont(m_env, + gui::CGUITTFont *font = gui::CGUITTFont::createTTFont(m_env, font_path.c_str(), size, true, true, font_shadow, font_shadow_alpha); - if (font) - return font; - - errorstream << "FontEngine: Cannot load '" << font_path << + if (!font) { + errorstream << "FontEngine: Cannot load '" << font_path << "'. Trying to fall back to another path." << std::endl; - } - + continue; + } - // give up - errorstream << "minetest can not continue without a valid font. " - "Please correct the 'font_path' setting or install the font " - "file in the proper location" << std::endl; + if (spec.mode != _FM_Fallback) { + FontSpec spec2(spec); + spec2.mode = _FM_Fallback; + font->setFallback(getFont(spec2, true)); + } + return font; + } #else - errorstream << "FontEngine: Tried to load freetype fonts but Minetest was" - " not compiled with that library." << std::endl; + errorstream << "FontEngine: Tried to load TTF font but Minetest was" + " compiled without Freetype." << std::endl; #endif - abort(); + return nullptr; } /** initialize a font without freetype */ diff --git a/src/client/fontengine.h b/src/client/fontengine.h index e27ef60e9..3d389ea48 100644 --- a/src/client/fontengine.h +++ b/src/client/fontengine.h @@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., enum FontMode : u8 { FM_Standard = 0, FM_Mono, - FM_Fallback, + _FM_Fallback, // do not use directly FM_Simple, FM_SimpleMono, FM_MaxMode, @@ -47,7 +47,7 @@ struct FontSpec { bold(bold), italic(italic) {} - u16 getHash() + u16 getHash() const { return (mode << 2) | (static_cast<u8>(bold) << 1) | static_cast<u8>(italic); } @@ -132,10 +132,12 @@ public: void readSettings(); private: + irr::gui::IGUIFont *getFont(FontSpec spec, bool may_fail); + /** update content of font cache in case of a setting change made it invalid */ void updateFontCache(); - /** initialize a new font */ + /** initialize a new TTF font */ gui::IGUIFont *initFont(const FontSpec &spec); /** initialize a font without freetype */ |