diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp index c807d5011..ad1ae2eb2 100644 --- a/src/client/fontengine.cpp +++ b/src/client/fontengine.cpp @@ -80,7 +80,7 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec) irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail) { if (spec.mode == FM_Unspecified) { - spec.mode = m_currentMode; + spec.mode = s_default_font_mode; } else if (spec.mode == _FM_Fallback) { // Fallback font doesn't support these spec.bold = false; @@ -138,7 +138,7 @@ unsigned int FontEngine::getLineHeight(const FontSpec &spec) unsigned int FontEngine::getDefaultFontSize() { - return m_default_size[m_currentMode]; + return m_default_size[s_default_font_mode]; } unsigned int FontEngine::getFontSize(FontMode mode) @@ -222,11 +222,14 @@ void FontEngine::clearMediaFonts() refresh(); } -gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) +gui::IGUIFont *FontEngine::initFont(FontSpec spec) { assert(spec.mode != FM_Unspecified); assert(spec.size != FONT_SIZE_UNSPECIFIED); + if (spec.mode == _FM_Fallback) + spec.allow_server_media = false; + std::string setting_prefix = ""; if (spec.mode == FM_Mono) setting_prefix = "mono_"; @@ -256,18 +259,6 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha", font_shadow_alpha); - 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 media_name = spec.mode == FM_Mono - ? "mono" + setting_suffix - : (setting_suffix.empty() ? "" : setting_suffix.substr(1)); - if (media_name.empty()) - media_name = "regular"; - auto createFont = [&](gui::SGUITTFace *face) -> gui::CGUITTFont* { auto *font = gui::CGUITTFont::createTTFont(m_env, face, size, true, true, font_shadow, @@ -285,15 +276,31 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) return font; }; - auto it = m_media_faces.find(media_name); - if (spec.mode != _FM_Fallback && it != m_media_faces.end()) { - auto *face = it->second.get(); - if (auto *font = createFont(face)) - return font; - errorstream << "FontEngine: Cannot load media font '" << media_name << - "'. Falling back to client settings." << std::endl; + // Use the server-provided font media (if available) + if (spec.allow_server_media) { + std::string media_name = spec.mode == FM_Mono + ? "mono" + setting_suffix + : (setting_suffix.empty() ? "" : setting_suffix.substr(1)); + if (media_name.empty()) + media_name = "regular"; + + auto it = m_media_faces.find(media_name); + if (it != m_media_faces.end()) { + auto *face = it->second.get(); + if (auto *font = createFont(face)) + return font; + errorstream << "FontEngine: Cannot load media font '" << media_name << + "'. Falling back to client settings." << std::endl; + } } + // Use the local font files specified by the settings + 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[] = { g_settings->get(path_setting), Settings::getLayer(SL_DEFAULTS)->get(path_setting) diff --git a/src/client/fontengine.h b/src/client/fontengine.h index 0ed81f678..82949b250 100644 --- a/src/client/fontengine.h +++ b/src/client/fontengine.h @@ -23,10 +23,22 @@ namespace irr { #define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF enum FontMode : u8 { + /// Regular font (settings "font_path*", overwritable) FM_Standard = 0, + + /// Monospace font (settings "mono_font*", overwritable) FM_Mono, - _FM_Fallback, // do not use directly + + /// Use only in `FontEngine`. Fallback font to render glyphs that are not present + /// in the originally requested font (setting "fallback_font_path") + _FM_Fallback, + + /// Sum of all font modes FM_MaxMode, + + // ---------------------------- + + /// Request the defult font specified by `s_default_font_mode` FM_Unspecified }; @@ -37,15 +49,22 @@ struct FontSpec { bold(bold), italic(italic) {} + static const unsigned VARIANT_BITS = 3; + static const size_t MAX_VARIANTS = FM_MaxMode << VARIANT_BITS; + u16 getHash() const { - return (mode << 2) | (static_cast(bold) << 1) | static_cast(italic); + return (mode << VARIANT_BITS) + | (static_cast(allow_server_media) << 2) + | (static_cast(bold) << 1) + | static_cast(italic); } unsigned int size; FontMode mode; bool bold; bool italic; + bool allow_server_media = true; }; class FontEngine @@ -135,7 +154,7 @@ private: void updateCache(); /** initialize a new TTF font */ - gui::IGUIFont *initFont(const FontSpec &spec); + gui::IGUIFont *initFont(FontSpec spec); /** update current minetest skin with font changes */ void updateSkin(); @@ -155,7 +174,7 @@ private: std::recursive_mutex m_font_mutex; /** internal storage for caching fonts of different size */ - std::map m_font_cache[FM_MaxMode << 2]; + std::map m_font_cache[FontSpec::MAX_VARIANTS]; /** media-provided faces, indexed by filename (without extension) */ std::unordered_map> m_media_faces; @@ -168,7 +187,7 @@ private: bool m_default_italic = false; /** default font engine mode (fixed) */ - static const FontMode m_currentMode = FM_Standard; + static const FontMode s_default_font_mode = FM_Standard; bool m_needs_reload = false; diff --git a/src/gui/StyleSpec.h b/src/gui/StyleSpec.h index 3755e105f..f78a038c2 100644 --- a/src/gui/StyleSpec.h +++ b/src/gui/StyleSpec.h @@ -316,6 +316,8 @@ public: spec.bold = true; else if (modes[i] == "italic") spec.italic = true; + else if (modes[i] == "_no_server_media") // for internal use only + spec.allow_server_media = false; } if (!size.empty()) { diff --git a/src/gui/guiOpenURL.cpp b/src/gui/guiOpenURL.cpp index 7ce79b0e5..4c54556be 100644 --- a/src/gui/guiOpenURL.cpp +++ b/src/gui/guiOpenURL.cpp @@ -87,6 +87,12 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) ok = false; } + std::array styles {}; + for (auto &style : styles) + style.set(StyleSpec::Property::FONT, "_no_server_media"); + + auto font_standard = styles[0].getFont(); + /* Add stuff */ @@ -99,8 +105,9 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) std::wstring title = ok ? wstrgettext("Open URL?") : wstrgettext("Unable to open URL"); - gui::StaticText::add(Environment, title, rect, + auto *e = gui::StaticText::add(Environment, title, rect, false, true, this, -1); + e->setOverrideFont(font_standard); } ypos += 50 * s; @@ -108,8 +115,11 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) { core::rect rect(0, 0, 440 * s, 60 * s); - auto font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED, - ok ? FM_Mono : FM_Standard); + FontSpec fontspec(FONT_SIZE_UNSPECIFIED, FM_Mono, false, false); + fontspec.allow_server_media = false; + + auto font = ok ? g_fontengine->getFont(fontspec) : font_standard; + int scrollbar_width = Environment->getSkin()->getSize(gui::EGDS_SCROLLBAR_SIZE); int max_cols = (rect.getWidth() - scrollbar_width - 10) / font->getDimension(L"x").Width; @@ -131,14 +141,16 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) if (ok) { core::rect rect(0, 0, 100 * s, 40 * s); rect = rect + v2s32(size.X / 2 - 150 * s, ypos); - GUIButton::addButton(Environment, rect, m_tsrc, this, ID_open, + auto *e = GUIButton::addButton(Environment, rect, m_tsrc, this, ID_open, wstrgettext("Open").c_str()); + e->setStyles(styles); } { core::rect rect(0, 0, 100 * s, 40 * s); rect = rect + v2s32(size.X / 2 + 50 * s, ypos); - GUIButton::addButton(Environment, rect, m_tsrc, this, ID_cancel, + auto *e = GUIButton::addButton(Environment, rect, m_tsrc, this, ID_cancel, wstrgettext("Cancel").c_str()); + e->setStyles(styles); } }