From f34a3e2145acd513dfa62ff55fb7742a0cb4ae61 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 31 Dec 2024 12:50:20 -0500 Subject: [PATCH 1/3] Add check for symbolic font in fontconfig code --- .../source/scwx/qt/manager/font_manager.cpp | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/font_manager.cpp b/scwx-qt/source/scwx/qt/manager/font_manager.cpp index 72779f67..89a1643f 100644 --- a/scwx-qt/source/scwx/qt/manager/font_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/font_manager.cpp @@ -472,6 +472,7 @@ FontManager::Impl::MatchFontFile(const std::string& family, FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast(kFcTrueType_.c_str())); + FcPatternAddBool(pattern, FC_SYMBOL, FcFalse); if (!styles.empty()) { @@ -485,29 +486,51 @@ FontManager::Impl::MatchFontFile(const std::string& family, FcDefaultSubstitute(pattern); // Find matching font - FcResult result; - FcPattern* match = FcFontMatch(nullptr, pattern, &result); + FcResult result {}; + FcFontSet* matches = FcFontSort(nullptr, pattern, FcFalse, nullptr, &result); FontRecord record {}; - if (match != nullptr) + if (matches != nullptr) { - FcChar8* fcFamily; - FcChar8* fcStyle; - FcChar8* fcFile; - - // Match was found, get properties - if (FcPatternGetString(match, FC_FAMILY, 0, &fcFamily) == FcResultMatch && - FcPatternGetString(match, FC_STYLE, 0, &fcStyle) == FcResultMatch && - FcPatternGetString(match, FC_FILE, 0, &fcFile) == FcResultMatch) + for (int i = 0; i < matches->nfont; i++) { - record.family_ = reinterpret_cast(fcFamily); - record.style_ = reinterpret_cast(fcStyle); - record.filename_ = reinterpret_cast(fcFile); + FcPattern* match = + // Using C code requires pointer arithmetic + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + FcFontRenderPrepare(nullptr, pattern, matches->fonts[i]); + if (match == nullptr) + { + continue; + } + FcChar8* fcFamily = nullptr; + FcChar8* fcStyle = nullptr; + FcChar8* fcFile = nullptr; + FcBool fcSymbol = FcFalse; - logger_->debug("Found matching font: {}:{} ({})", - record.family_, - record.style_, - record.filename_); + // Match was found, get properties + if (FcPatternGetString(match, FC_FAMILY, 0, &fcFamily) == + FcResultMatch && + FcPatternGetString(match, FC_STYLE, 0, &fcStyle) == + FcResultMatch && + FcPatternGetString(match, FC_FILE, 0, &fcFile) == FcResultMatch && + FcPatternGetBool(match, FC_SYMBOL, 0, &fcSymbol) == + FcResultMatch && + fcSymbol == FcFalse /*Must check fcSymbol manually*/) + { + record.family_ = reinterpret_cast(fcFamily); + record.style_ = reinterpret_cast(fcStyle); + record.filename_ = reinterpret_cast(fcFile); + + logger_->debug("Found matching font: {}:{} ({}) {}", + record.family_, + record.style_, + record.filename_, + fcSymbol); + FcPatternDestroy(match); + break; + } + + FcPatternDestroy(match); } } @@ -517,7 +540,7 @@ FontManager::Impl::MatchFontFile(const std::string& family, } // Cleanup - FcPatternDestroy(match); + FcFontSetDestroy(matches); FcPatternDestroy(pattern); return record; From f7a55ec85b7a64468869819240ffd2ca299f095f Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 31 Dec 2024 13:03:12 -0500 Subject: [PATCH 2/3] Add logging for unloaded fonts in case a similar error happens again. --- scwx-qt/source/scwx/qt/map/map_widget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index df45024a..d569f27e 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -1619,6 +1619,11 @@ void MapWidgetImpl::ImGuiCheckFonts() ImGui_ImplOpenGL3_CreateFontsTexture(); } + if (!model::ImGuiContextModel::Instance().font_atlas()->IsBuilt()) + { + logger_->error("ImGui font atlas could not be built."); + } + imGuiFontsBuildCount_ = currentImGuiFontsBuildCount; } From 2e973bf6549f8bc0ecea148f7632b6946a9e5ff8 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 10 Jan 2025 09:57:38 -0500 Subject: [PATCH 3/3] Modified font atlas not build logging to only log once --- scwx-qt/source/scwx/qt/map/map_widget.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index d569f27e..ab7b0cf6 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -1619,9 +1619,12 @@ void MapWidgetImpl::ImGuiCheckFonts() ImGui_ImplOpenGL3_CreateFontsTexture(); } - if (!model::ImGuiContextModel::Instance().font_atlas()->IsBuilt()) + static bool haveLogged = false; + if (!model::ImGuiContextModel::Instance().font_atlas()->IsBuilt() && + !haveLogged) { logger_->error("ImGui font atlas could not be built."); + haveLogged = true; } imGuiFontsBuildCount_ = currentImGuiFontsBuildCount;