mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-06 17:41: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:
parent
5b2b2c7796
commit
f1364b1e0b
4 changed files with 72 additions and 32 deletions
|
@ -80,7 +80,7 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec)
|
||||||
irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
|
irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
|
||||||
{
|
{
|
||||||
if (spec.mode == FM_Unspecified) {
|
if (spec.mode == FM_Unspecified) {
|
||||||
spec.mode = m_currentMode;
|
spec.mode = s_default_font_mode;
|
||||||
} else if (spec.mode == _FM_Fallback) {
|
} else if (spec.mode == _FM_Fallback) {
|
||||||
// Fallback font doesn't support these
|
// Fallback font doesn't support these
|
||||||
spec.bold = false;
|
spec.bold = false;
|
||||||
|
@ -138,7 +138,7 @@ unsigned int FontEngine::getLineHeight(const FontSpec &spec)
|
||||||
|
|
||||||
unsigned int FontEngine::getDefaultFontSize()
|
unsigned int FontEngine::getDefaultFontSize()
|
||||||
{
|
{
|
||||||
return m_default_size[m_currentMode];
|
return m_default_size[s_default_font_mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int FontEngine::getFontSize(FontMode mode)
|
unsigned int FontEngine::getFontSize(FontMode mode)
|
||||||
|
@ -222,11 +222,14 @@ void FontEngine::clearMediaFonts()
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
gui::IGUIFont *FontEngine::initFont(FontSpec spec)
|
||||||
{
|
{
|
||||||
assert(spec.mode != FM_Unspecified);
|
assert(spec.mode != FM_Unspecified);
|
||||||
assert(spec.size != FONT_SIZE_UNSPECIFIED);
|
assert(spec.size != FONT_SIZE_UNSPECIFIED);
|
||||||
|
|
||||||
|
if (spec.mode == _FM_Fallback)
|
||||||
|
spec.allow_server_media = false;
|
||||||
|
|
||||||
std::string setting_prefix = "";
|
std::string setting_prefix = "";
|
||||||
if (spec.mode == FM_Mono)
|
if (spec.mode == FM_Mono)
|
||||||
setting_prefix = "mono_";
|
setting_prefix = "mono_";
|
||||||
|
@ -256,18 +259,6 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
||||||
g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha",
|
g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha",
|
||||||
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 createFont = [&](gui::SGUITTFace *face) -> gui::CGUITTFont* {
|
||||||
auto *font = gui::CGUITTFont::createTTFont(m_env,
|
auto *font = gui::CGUITTFont::createTTFont(m_env,
|
||||||
face, size, true, true, font_shadow,
|
face, size, true, true, font_shadow,
|
||||||
|
@ -285,15 +276,31 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
||||||
return font;
|
return font;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto it = m_media_faces.find(media_name);
|
// Use the server-provided font media (if available)
|
||||||
if (spec.mode != _FM_Fallback && it != m_media_faces.end()) {
|
if (spec.allow_server_media) {
|
||||||
auto *face = it->second.get();
|
std::string media_name = spec.mode == FM_Mono
|
||||||
if (auto *font = createFont(face))
|
? "mono" + setting_suffix
|
||||||
return font;
|
: (setting_suffix.empty() ? "" : setting_suffix.substr(1));
|
||||||
errorstream << "FontEngine: Cannot load media font '" << media_name <<
|
if (media_name.empty())
|
||||||
"'. Falling back to client settings." << std::endl;
|
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[] = {
|
std::string fallback_settings[] = {
|
||||||
g_settings->get(path_setting),
|
g_settings->get(path_setting),
|
||||||
Settings::getLayer(SL_DEFAULTS)->get(path_setting)
|
Settings::getLayer(SL_DEFAULTS)->get(path_setting)
|
||||||
|
|
|
@ -23,10 +23,22 @@ namespace irr {
|
||||||
#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
|
#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
|
||||||
|
|
||||||
enum FontMode : u8 {
|
enum FontMode : u8 {
|
||||||
|
/// Regular font (settings "font_path*", overwritable)
|
||||||
FM_Standard = 0,
|
FM_Standard = 0,
|
||||||
|
|
||||||
|
/// Monospace font (settings "mono_font*", overwritable)
|
||||||
FM_Mono,
|
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,
|
FM_MaxMode,
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
|
||||||
|
/// Request the defult font specified by `s_default_font_mode`
|
||||||
FM_Unspecified
|
FM_Unspecified
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,15 +49,22 @@ struct FontSpec {
|
||||||
bold(bold),
|
bold(bold),
|
||||||
italic(italic) {}
|
italic(italic) {}
|
||||||
|
|
||||||
|
static const unsigned VARIANT_BITS = 3;
|
||||||
|
static const size_t MAX_VARIANTS = FM_MaxMode << VARIANT_BITS;
|
||||||
|
|
||||||
u16 getHash() const
|
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;
|
unsigned int size;
|
||||||
FontMode mode;
|
FontMode mode;
|
||||||
bool bold;
|
bool bold;
|
||||||
bool italic;
|
bool italic;
|
||||||
|
bool allow_server_media = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontEngine
|
class FontEngine
|
||||||
|
@ -135,7 +154,7 @@ private:
|
||||||
void updateCache();
|
void updateCache();
|
||||||
|
|
||||||
/** initialize a new TTF font */
|
/** initialize a new TTF font */
|
||||||
gui::IGUIFont *initFont(const FontSpec &spec);
|
gui::IGUIFont *initFont(FontSpec spec);
|
||||||
|
|
||||||
/** update current minetest skin with font changes */
|
/** update current minetest skin with font changes */
|
||||||
void updateSkin();
|
void updateSkin();
|
||||||
|
@ -155,7 +174,7 @@ private:
|
||||||
std::recursive_mutex m_font_mutex;
|
std::recursive_mutex m_font_mutex;
|
||||||
|
|
||||||
/** internal storage for caching fonts of different size */
|
/** 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) */
|
/** media-provided faces, indexed by filename (without extension) */
|
||||||
std::unordered_map<std::string, irr_ptr<gui::SGUITTFace>> m_media_faces;
|
std::unordered_map<std::string, irr_ptr<gui::SGUITTFace>> m_media_faces;
|
||||||
|
@ -168,7 +187,7 @@ private:
|
||||||
bool m_default_italic = false;
|
bool m_default_italic = false;
|
||||||
|
|
||||||
/** default font engine mode (fixed) */
|
/** 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;
|
bool m_needs_reload = false;
|
||||||
|
|
||||||
|
|
|
@ -316,6 +316,8 @@ public:
|
||||||
spec.bold = true;
|
spec.bold = true;
|
||||||
else if (modes[i] == "italic")
|
else if (modes[i] == "italic")
|
||||||
spec.italic = true;
|
spec.italic = true;
|
||||||
|
else if (modes[i] == "_no_server_media") // for internal use only
|
||||||
|
spec.allow_server_media = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!size.empty()) {
|
if (!size.empty()) {
|
||||||
|
|
|
@ -87,6 +87,12 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize)
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::array<StyleSpec, StyleSpec::NUM_STATES> styles {};
|
||||||
|
for (auto &style : styles)
|
||||||
|
style.set(StyleSpec::Property::FONT, "_no_server_media");
|
||||||
|
|
||||||
|
auto font_standard = styles[0].getFont();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Add stuff
|
Add stuff
|
||||||
*/
|
*/
|
||||||
|
@ -99,8 +105,9 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize)
|
||||||
std::wstring title = ok
|
std::wstring title = ok
|
||||||
? wstrgettext("Open URL?")
|
? wstrgettext("Open URL?")
|
||||||
: wstrgettext("Unable to 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);
|
false, true, this, -1);
|
||||||
|
e->setOverrideFont(font_standard);
|
||||||
}
|
}
|
||||||
|
|
||||||
ypos += 50 * s;
|
ypos += 50 * s;
|
||||||
|
@ -108,8 +115,11 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize)
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 440 * s, 60 * s);
|
core::rect<s32> rect(0, 0, 440 * s, 60 * s);
|
||||||
|
|
||||||
auto font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED,
|
FontSpec fontspec(FONT_SIZE_UNSPECIFIED, FM_Mono, false, false);
|
||||||
ok ? FM_Mono : FM_Standard);
|
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 scrollbar_width = Environment->getSkin()->getSize(gui::EGDS_SCROLLBAR_SIZE);
|
||||||
int max_cols = (rect.getWidth() - scrollbar_width - 10) / font->getDimension(L"x").Width;
|
int max_cols = (rect.getWidth() - scrollbar_width - 10) / font->getDimension(L"x").Width;
|
||||||
|
|
||||||
|
@ -131,14 +141,16 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize)
|
||||||
if (ok) {
|
if (ok) {
|
||||||
core::rect<s32> rect(0, 0, 100 * s, 40 * s);
|
core::rect<s32> rect(0, 0, 100 * s, 40 * s);
|
||||||
rect = rect + v2s32(size.X / 2 - 150 * s, ypos);
|
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());
|
wstrgettext("Open").c_str());
|
||||||
|
e->setStyles(styles);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 100 * s, 40 * s);
|
core::rect<s32> rect(0, 0, 100 * s, 40 * s);
|
||||||
rect = rect + v2s32(size.X / 2 + 50 * s, ypos);
|
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());
|
wstrgettext("Cancel").c_str());
|
||||||
|
e->setStyles(styles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue