1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-10-05 19:31:04 +00:00

GUI: Use the client's fonts for 'Open URL?' dialogues

This popup is related to user safety, thus it should not
use server-provided font media files.
This commit is contained in:
SmallJoker 2025-03-15 15:30:35 +01:00 committed by SmallJoker
parent 5b2b2c7796
commit f1364b1e0b
4 changed files with 72 additions and 32 deletions

View file

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

View file

@ -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<u8>(bold) << 1) | static_cast<u8>(italic);
return (mode << VARIANT_BITS)
| (static_cast<u8>(allow_server_media) << 2)
| (static_cast<u8>(bold) << 1)
| static_cast<u8>(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<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FontSpec::MAX_VARIANTS];
/** media-provided faces, indexed by filename (without extension) */
std::unordered_map<std::string, irr_ptr<gui::SGUITTFace>> 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;