From 0c20dda1da1b6e93d38d67983eb4b3635b958c14 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 8 Sep 2021 09:38:30 +0800 Subject: [PATCH] Remove SF_DISABLE_URL_HIGHLIGHT flag to avoid conflicts with cache Manually remove the URL highlighting if needed --- lib/irrlicht/include/GlyphLayout.h | 9 ++- src/font/font_manager.cpp | 79 +++++++++---------- src/guiengine/engine.cpp | 3 +- src/guiengine/message_queue.cpp | 1 + src/guiengine/widgets/CGUIEditBox.cpp | 8 +- src/guiengine/widgets/CGUISTKListBox.cpp | 3 +- .../online/networking_lobby.cpp | 3 +- 7 files changed, 58 insertions(+), 48 deletions(-) diff --git a/lib/irrlicht/include/GlyphLayout.h b/lib/irrlicht/include/GlyphLayout.h index 6f82c948f..ae46fb3d9 100644 --- a/lib/irrlicht/include/GlyphLayout.h +++ b/lib/irrlicht/include/GlyphLayout.h @@ -23,8 +23,7 @@ namespace gui enum ShapeFlag { SF_DISABLE_CACHE = 1, /* Disable caching glyph layouts. */ -SF_DISABLE_URL_HIGHLIGHT = 2, /* Disable URL highlight. */ -SF_ENABLE_CLUSTER_TEST = 4, /* If on getCluster will work on these layouts, which the original string will be stored, it will be turned on too if any URL is found. */ +SF_ENABLE_CLUSTER_TEST = 2, /* If on getCluster will work on these layouts, which the original string will be stored, it will be turned on too if any URL is found. */ }; enum GlyphLayoutFlag @@ -344,6 +343,12 @@ inline bool getDrawOffset(const core::rect& position, bool hcenter, return true; } +inline void removeHighlightedURL(std::vector& gls) +{ + for (GlyphLayout& gl : gls) + gl.flags &= ~gui::GLF_URL; +} + namespace Private { /** Used it only for single line (ie without line breaking mark). */ diff --git a/src/font/font_manager.cpp b/src/font/font_manager.cpp index 284b54af6..bd5e6476e 100644 --- a/src/font/font_manager.cpp +++ b/src/font/font_manager.cpp @@ -333,51 +333,50 @@ void FontManager::shape(const std::u32string& text, return 0; }; - bool save_orig_string = (shape_flag & gui::SF_ENABLE_CLUSTER_TEST) != 0; - if ((shape_flag & gui::SF_DISABLE_URL_HIGHLIGHT) == 0) + // Auto URL highlighting for http:// or https:// + size_t pos = text.find(U"http://", 0); + while (pos != std::u32string::npos) { - size_t pos = text.find(U"http://", 0); - while (pos != std::u32string::npos) + // Find nearest newline or whitespace + size_t newline_pos = text.find(U'\n', pos + 1); + size_t space_pos = text.find(U' ', pos + 1); + size_t end_pos = std::u32string::npos; + if (newline_pos != std::u32string::npos || + space_pos != std::u32string::npos) { - // Find nearest newline or whitespace - size_t newline_pos = text.find(U'\n', pos + 1); - size_t space_pos = text.find(U' ', pos + 1); - size_t end_pos = std::u32string::npos; - if (newline_pos != std::u32string::npos || - space_pos != std::u32string::npos) - { - if (space_pos > newline_pos) - end_pos = newline_pos; - else - end_pos = space_pos; - } + if (space_pos > newline_pos) + end_pos = newline_pos; else - end_pos = text.size(); - end_pos = fix_end_pos(text, pos, end_pos); - http_pos.emplace_back((int)pos, (int)end_pos); - pos = text.find(U"http://", pos + 1); - } - pos = text.find(U"https://", 0); - while (pos != std::u32string::npos) - { - size_t newline_pos = text.find(U'\n', pos + 1); - size_t space_pos = text.find(U' ', pos + 1); - size_t end_pos = std::u32string::npos; - if (newline_pos != std::u32string::npos || - space_pos != std::u32string::npos) - { - if (space_pos > newline_pos) - end_pos = newline_pos; - else - end_pos = space_pos; - } - else - end_pos = text.size(); - end_pos = fix_end_pos(text, pos, end_pos); - http_pos.emplace_back((int)pos, (int)end_pos); - pos = text.find(U"https://", pos + 1); + end_pos = space_pos; } + else + end_pos = text.size(); + end_pos = fix_end_pos(text, pos, end_pos); + http_pos.emplace_back((int)pos, (int)end_pos); + pos = text.find(U"http://", pos + 1); } + pos = text.find(U"https://", 0); + while (pos != std::u32string::npos) + { + size_t newline_pos = text.find(U'\n', pos + 1); + size_t space_pos = text.find(U' ', pos + 1); + size_t end_pos = std::u32string::npos; + if (newline_pos != std::u32string::npos || + space_pos != std::u32string::npos) + { + if (space_pos > newline_pos) + end_pos = newline_pos; + else + end_pos = space_pos; + } + else + end_pos = text.size(); + end_pos = fix_end_pos(text, pos, end_pos); + http_pos.emplace_back((int)pos, (int)end_pos); + pos = text.find(U"https://", pos + 1); + } + + bool save_orig_string = (shape_flag & gui::SF_ENABLE_CLUSTER_TEST) != 0; if (!http_pos.empty()) save_orig_string = true; diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index eb4f37405..5434366a0 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1501,7 +1501,8 @@ namespace GUIEngine core::dimension2d(screen_w, text_height)); GL32_draw2DRectangle(Skin::getColor("tips_background::neutral"), tipRect); std::vector gls; - Private::g_font->initGlyphLayouts(g_tips_string, gls, gui::SF_DISABLE_URL_HIGHLIGHT); + Private::g_font->initGlyphLayouts(g_tips_string, gls); + gui::removeHighlightedURL(gls); Private::g_font->draw(gls, tipRect, Skin::getColor("brighttext::neutral"), true /* hcenter */, true /* vcenter */); diff --git a/src/guiengine/message_queue.cpp b/src/guiengine/message_queue.cpp index 6f32011e0..3acd73473 100644 --- a/src/guiengine/message_queue.cpp +++ b/src/guiengine/message_queue.cpp @@ -146,6 +146,7 @@ public: const unsigned height = m_screen_size.Height; m_font = GUIEngine::getFont(); m_font->initGlyphLayouts(m_message, m_gls); + gui::removeHighlightedURL(m_gls); // Reserve space for 3 lines of text, it will occupy the circle const int max_width = width - (brp.m_left_border + brp.m_right_border) - (m_font->getHeightPerLine() * 3); diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index c8200be80..d4ac91e05 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -953,7 +953,8 @@ void CGUIEditBox::draw() const s32 realcbgn = m_cursor_pos; const s32 realcend = m_cursor_pos + (s32)m_composing_text.size(); total.insert(m_cursor_pos, m_composing_text); - font_manager->shape(total, ct, gui::SF_DISABLE_URL_HIGHLIGHT); + font_manager->shape(total, ct); + gui::removeHighlightedURL(ct); for (unsigned i = 0; i < ct.size(); i++) { GlyphLayout& glyph = ct[i]; @@ -1542,7 +1543,10 @@ void CGUIEditBox::updateGlyphLayouts() m_glyph_layouts); } else - font_manager->shape(m_edit_text, m_glyph_layouts, gui::SF_DISABLE_URL_HIGHLIGHT); + { + font_manager->shape(m_edit_text, m_glyph_layouts); + gui::removeHighlightedURL(m_glyph_layouts); + } Text = StringUtils::utf32ToWide(m_edit_text); #endif } diff --git a/src/guiengine/widgets/CGUISTKListBox.cpp b/src/guiengine/widgets/CGUISTKListBox.cpp index d61496d2d..69f81f1d9 100644 --- a/src/guiengine/widgets/CGUISTKListBox.cpp +++ b/src/guiengine/widgets/CGUISTKListBox.cpp @@ -591,8 +591,7 @@ void CGUISTKListBox::draw() Font->initGlyphLayouts(Items[i].m_contents[x].m_text, Items[i].m_contents[x].m_glyph_layouts); // Remove highlighted link if cache already has it - for (gui::GlyphLayout& gl : Items[i].m_contents[x].m_glyph_layouts) - gl.flags &= ~gui::GLF_URL; + gui::removeHighlightedURL(Items[i].m_contents[x].m_glyph_layouts); if (Items[i].m_word_wrap) { gui::breakGlyphLayouts(Items[i].m_contents[x].m_glyph_layouts, diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 7be8715cd..a95e8f4c1 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -347,7 +347,8 @@ void NetworkingLobby::addMoreServerInfo(core::stringw info) const float box_height = m_text_bubble->getDimension().Height; std::vector cur_info; font_manager->initGlyphLayouts(info, cur_info, gui::SF_DISABLE_CACHE | - gui::SF_DISABLE_URL_HIGHLIGHT | gui::SF_ENABLE_CLUSTER_TEST); + gui::SF_ENABLE_CLUSTER_TEST); + gui::removeHighlightedURL(cur_info); gui::IGUIFont* font = GUIEngine::getFont(); gui::breakGlyphLayouts(cur_info, box_width, font->getInverseShaping(), font->getScale());