From 72416a6a1f75d56abfad0f486e57fd32579b3604 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Tue, 10 Sep 2019 15:11:26 +0200 Subject: Formspec: add hypertext element --- src/client/fontengine.cpp | 70 +++++++++++++++++++++++++++++++++++------------ src/client/fontengine.h | 61 ++++++++++++++++++++++++++++++++++------- src/client/hud.cpp | 70 +++++++++++++++++++++++++++++++---------------- src/client/hud.h | 12 ++++++++ 4 files changed, 163 insertions(+), 50 deletions(-) (limited to 'src/client') diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp index 858d6780e..8120f82df 100644 --- a/src/client/fontengine.cpp +++ b/src/client/fontengine.cpp @@ -41,6 +41,11 @@ 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), @@ -59,7 +64,12 @@ FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) : if (m_currentMode == FM_Standard) { m_settings->registerChangedCallback("font_size", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_bold", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_italic", font_setting_changed, NULL); m_settings->registerChangedCallback("font_path", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_path_bold", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_path_italic", font_setting_changed, NULL); + m_settings->registerChangedCallback("font_path_bolditalic", font_setting_changed, NULL); m_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL); m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL); } @@ -96,7 +106,8 @@ void FontEngine::cleanCache() } /******************************************************************************/ -irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode) +irr::gui::IGUIFont *FontEngine::getFont(unsigned int font_size, FontMode mode, + bool bold, bool italic) { if (mode == FM_Unspecified) { mode = m_currentMode; @@ -110,22 +121,30 @@ irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode) if (font_size == FONT_SIZE_UNSPECIFIED) font_size = m_default_size[mode]; - const auto &cache = m_font_cache[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); + initFont(font_size, mode, bold, italic); } + if (m_font_cache[cache_index].find(font_size) == + m_font_cache[cache_index].end()) + initFont(font_size, mode, bold, italic); + const auto &font = cache.find(font_size); return font != cache.end() ? font->second : nullptr; } /******************************************************************************/ -unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode) +unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode, + bool bold, bool italic) { - irr::gui::IGUIFont* font = getFont(font_size, mode); + irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic); // use current skin font as fallback if (font == NULL) { @@ -138,9 +157,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) + unsigned int font_size, FontMode mode, bool bold, bool italic) { - irr::gui::IGUIFont* font = getFont(font_size, mode); + irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic); // use current skin font as fallback if (font == NULL) { @@ -153,9 +172,10 @@ 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) +unsigned int FontEngine::getLineHeight(unsigned int font_size, FontMode mode, + bool bold, bool italic) { - irr::gui::IGUIFont* font = getFont(font_size, mode); + irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic); // use current skin font as fallback if (font == NULL) { @@ -183,6 +203,10 @@ void FontEngine::readSettings() m_currentMode = is_yes(gettext("needs_fallback_font")) ? FM_Fallback : FM_Standard; + + m_default_bold = m_settings->getBool("font_bold"); + m_default_italic = m_settings->getBool("font_italic"); + } else { m_currentMode = FM_Simple; } @@ -226,14 +250,17 @@ void FontEngine::updateFontCache() } /******************************************************************************/ -void FontEngine::initFont(unsigned int basesize, FontMode mode) +void FontEngine::initFont(unsigned int basesize, FontMode mode, + bool bold, bool italic) { assert(mode != FM_Unspecified); assert(basesize != FONT_SIZE_UNSPECIFIED); - if (m_font_cache[mode].find(basesize) != m_font_cache[mode].end()) - return; + 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; std::string setting_prefix = ""; @@ -249,8 +276,13 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode) break; } + std::string setting_suffix = (bold) ? + ((italic) ? "_bold_italic" : "_bold") : + ((italic) ? "_italic" : ""); + u32 size = std::floor(RenderingEngine::getDisplayDensity() * m_settings->getFloat("gui_scaling") * basesize); + if (size == 0) { errorstream << "FontEngine: attempt to use font size 0" << std::endl; errorstream << " display density: " << RenderingEngine::getDisplayDensity() << std::endl; @@ -260,10 +292,14 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode) u16 font_shadow = 0; u16 font_shadow_alpha = 0; g_settings->getU16NoEx(setting_prefix + "font_shadow", font_shadow); - g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha", font_shadow_alpha); + 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 fallback_settings[] = { - m_settings->get(setting_prefix + "font_path"), + wanted_font_path, m_settings->get("fallback_font_path"), m_settings->getDefault(setting_prefix + "font_path") }; @@ -275,7 +311,7 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode) font_shadow_alpha); if (font) { - m_font_cache[mode][basesize] = font; + m_font_cache[cache_index][basesize] = font; return; } @@ -340,7 +376,7 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode) path.str(""); // Clear path << basename << "_" << (size + offset * sign) << ext; - if (!fs::PathExists(path.str())) + if (!fs::PathExists(path.str())) continue; font = m_env->getFont(path.str().c_str()); @@ -365,5 +401,5 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode) } if (font) - m_font_cache[mode][basesize] = font; + m_font_cache[get_font_cache_index(mode)][basesize] = font; } diff --git a/src/client/fontengine.h b/src/client/fontengine.h index 62aa71897..ecffc7660 100644 --- a/src/client/fontengine.h +++ b/src/client/fontengine.h @@ -48,29 +48,62 @@ public: ~FontEngine(); /** get Font */ - irr::gui::IGUIFont* getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED, - FontMode mode=FM_Unspecified); + irr::gui::IGUIFont *getFont(unsigned int font_size, FontMode mode, + bool bold, bool italic); + + 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); + } /** get text height for a specific font */ - unsigned int getTextHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED, - FontMode mode=FM_Unspecified); + unsigned int getTextHeight(unsigned int font_size, FontMode mode, + bool bold, bool italic); /** get text width if a text for a specific font */ - unsigned int getTextWidth(const std::string& text, + unsigned int getTextHeight( unsigned int font_size=FONT_SIZE_UNSPECIFIED, FontMode mode=FM_Unspecified) { - return getTextWidth(utf8_to_wide(text)); + return getTextHeight(font_size, mode, m_default_bold, m_default_italic); } + unsigned int getTextWidth(const std::wstring& text, + unsigned int font_size, FontMode mode, bool bold, bool italic); + /** 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); + FontMode mode=FM_Unspecified) + { + return getTextWidth(text, font_size, mode, m_default_bold, + m_default_italic); + } + + unsigned int getTextWidth(const std::string& text, + unsigned int font_size, FontMode mode, bool bold, bool italic) + { + return getTextWidth(utf8_to_wide(text), font_size, mode, bold, italic); + } + + 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); + } /** 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(unsigned int font_size=FONT_SIZE_UNSPECIFIED, - FontMode mode=FM_Unspecified); + FontMode mode=FM_Unspecified) + { + return getLineHeight(font_size, mode, m_default_bold, m_default_italic); + } /** get default font size */ unsigned int getDefaultFontSize(); @@ -86,7 +119,11 @@ private: void updateFontCache(); /** initialize a new font */ - void initFont(unsigned int basesize, FontMode mode=FM_Unspecified); + void initFont( + unsigned int basesize, + FontMode mode, + bool bold, + bool italic); /** initialize a font without freetype */ void initSimpleFont(unsigned int basesize, FontMode mode); @@ -104,11 +141,15 @@ private: gui::IGUIEnvironment* m_env = nullptr; /** internal storage for caching fonts of different size */ - std::map m_font_cache[FM_MaxMode]; + std::map m_font_cache[FM_MaxMode << 2]; /** default font size to use */ unsigned int m_default_size[FM_MaxMode]; + /** default bold and italic */ + bool m_default_bold; + bool m_default_italic; + /** current font engine mode */ FontMode m_currentMode = FM_Standard; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 291d03816..304a3ab16 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -608,23 +608,24 @@ void Hud::resizeHotbar() { struct MeshTimeInfo { u64 time; - scene::IMesh *mesh; + scene::IMesh *mesh = nullptr; }; -void drawItemStack(video::IVideoDriver *driver, +void drawItemStack( + video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, const core::rect &rect, const core::rect *clip, Client *client, - ItemRotationKind rotation_kind) + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed) { static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; - static thread_local bool enable_animations = - g_settings->getBool("inventory_items_animations"); if (item.empty()) { - if (rotation_kind < IT_ROT_NONE) { + if (rotation_kind < IT_ROT_NONE && rotation_kind != IT_ROT_OTHER) { rotation_time_infos[rotation_kind].mesh = NULL; } return; @@ -639,7 +640,7 @@ void drawItemStack(video::IVideoDriver *driver, s32 delta = 0; if (rotation_kind < IT_ROT_NONE) { MeshTimeInfo &ti = rotation_time_infos[rotation_kind]; - if (mesh != ti.mesh) { + if (mesh != ti.mesh && rotation_kind != IT_ROT_OTHER) { ti.mesh = mesh; ti.time = porting::getTimeMs(); } else { @@ -677,9 +678,16 @@ void drawItemStack(video::IVideoDriver *driver, core::matrix4 matrix; matrix.makeIdentity(); + static thread_local bool enable_animations = + g_settings->getBool("inventory_items_animations"); + if (enable_animations) { - float timer_f = (float) delta / 5000.0; - matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0)); + float timer_f = (float) delta / 5000.f; + matrix.setRotationDegrees(v3f( + angle.X + rotation_speed.X * 3.60f * timer_f, + angle.Y + rotation_speed.Y * 3.60f * timer_f, + angle.Z + rotation_speed.Z * 3.60f * timer_f) + ); } driver->setTransform(video::ETS_WORLD, matrix); @@ -695,15 +703,18 @@ void drawItemStack(video::IVideoDriver *driver, // because these meshes are not buffered. assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER); video::SColor c = basecolor; + if (imesh->buffer_colors.size() > j) { ItemPartColor *p = &imesh->buffer_colors[j]; if (p->override_base) c = p->color; } + if (imesh->needs_shading) colorizeMeshBuffer(buf, &c); else setMeshBufferColor(buf, c); + video::SMaterial &material = buf->getMaterial(); material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; material.Lighting = false; @@ -726,12 +737,12 @@ void drawItemStack(video::IVideoDriver *driver, } } - if(def.type == ITEM_TOOL && item.wear != 0) - { + if (def.type == ITEM_TOOL && item.wear != 0) { // Draw a progressbar - float barheight = rect.getHeight()/16; - float barpad_x = rect.getWidth()/16; - float barpad_y = rect.getHeight()/16; + float barheight = rect.getHeight() / 16; + float barpad_x = rect.getWidth() / 16; + float barpad_y = rect.getHeight() / 16; + core::rect progressrect( rect.UpperLeftCorner.X + barpad_x, rect.LowerRightCorner.Y - barpad_y - barheight, @@ -739,18 +750,19 @@ void drawItemStack(video::IVideoDriver *driver, rect.LowerRightCorner.Y - barpad_y); // Shrink progressrect by amount of tool damage - float wear = item.wear / 65535.0; + float wear = item.wear / 65535.0f; int progressmid = wear * progressrect.UpperLeftCorner.X + - (1-wear) * progressrect.LowerRightCorner.X; + (1 - wear) * progressrect.LowerRightCorner.X; // Compute progressbar color // wear = 0.0: green // wear = 0.5: yellow // wear = 1.0: red - video::SColor color(255,255,255,255); + video::SColor color(255, 255, 255, 255); int wear_i = MYMIN(std::floor(wear * 600), 511); wear_i = MYMIN(wear_i + 10, 511); + if (wear_i <= 255) color.set(255, wear_i, 255, 0); else @@ -760,18 +772,17 @@ void drawItemStack(video::IVideoDriver *driver, progressrect2.LowerRightCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); - color = video::SColor(255,0,0,0); + color = video::SColor(255, 0, 0, 0); progressrect2 = progressrect; progressrect2.UpperLeftCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); } - if(font != NULL && item.count >= 2) - { + if (font != NULL && item.count >= 2) { // Get the item count as a string std::string text = itos(item.count); v2u32 dim = font->getDimension(utf8_to_wide(text).c_str()); - v2s32 sdim(dim.X,dim.Y); + v2s32 sdim(dim.X, dim.Y); core::rect rect2( /*rect.UpperLeftCorner, @@ -780,10 +791,23 @@ void drawItemStack(video::IVideoDriver *driver, sdim ); - video::SColor bgcolor(128,0,0,0); + video::SColor bgcolor(128, 0, 0, 0); driver->draw2DRectangle(bgcolor, rect2, clip); - video::SColor color(255,255,255,255); + video::SColor color(255, 255, 255, 255); font->draw(text.c_str(), rect2, color, false, false, clip); } } + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind) +{ + drawItemStack(driver, font, item, rect, clip, client, rotation_kind, + v3s16(0, 0, 0), v3s16(0, 100, 0)); +} diff --git a/src/client/hud.h b/src/client/hud.h index 693d2adee..d9b5e0686 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -122,6 +122,7 @@ enum ItemRotationKind IT_ROT_SELECTED, IT_ROT_HOVERED, IT_ROT_DRAGGED, + IT_ROT_OTHER, IT_ROT_NONE, // Must be last, also serves as number }; @@ -133,4 +134,15 @@ void drawItemStack(video::IVideoDriver *driver, Client *client, ItemRotationKind rotation_kind); +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect &rect, + const core::rect *clip, + Client *client, + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed); + #endif -- cgit v1.2.3