From 84c0db36eb7109f7d9f728b731dda6261af4ff5f Mon Sep 17 00:00:00 2001 From: Joachim Schmitz Date: Tue, 9 Jun 2026 18:39:29 +0200 Subject: [PATCH 1/2] Fix finding external Musical Text Fonts if those don't have a space before the "Text" in their filename --- src/notation/internal/engravingfontscontroller.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/notation/internal/engravingfontscontroller.cpp b/src/notation/internal/engravingfontscontroller.cpp index c6b7c13373f65..7ab43750e8cb3 100644 --- a/src/notation/internal/engravingfontscontroller.cpp +++ b/src/notation/internal/engravingfontscontroller.cpp @@ -137,19 +137,19 @@ void EngravingFontsController::scanDirectory(const muse::io::path_t& path, bool symbolFontPath = findFontPath(tmp.replace(" ", "")); } - muse::io::path_t textFontPath = findFontPath(fontName + " Text"); if (symbolFontPath.empty()) { - QString tmp = fontName; - symbolFontPath = findFontPath(tmp.replace(" ", "") + "Text"); + LOGE() << "Music font \"" << fontName << "\" for " << metadataPath << " not found"; + continue; } + muse::io::path_t textFontPath = findFontPath(fontName + " Text"); if (textFontPath.empty()) { - textFontPath = symbolFontPath; + QString tmp = fontName; + textFontPath = findFontPath(tmp.replace(" ", "") + "Text"); } - if (symbolFontPath.empty()) { - LOGE() << "Music font \"" << fontName << "\" for " << metadataPath << " not found"; - continue; + if (textFontPath.empty()) { + textFontPath = symbolFontPath; } LOGI() << "Adding custom SMuFL font: " << fontName From 0fc75df19b23185b818cdfdeba09f181d5ae6682 Mon Sep 17 00:00:00 2001 From: Joachim Schmitz Date: Thu, 11 Jun 2026 17:32:12 +0200 Subject: [PATCH 2/2] Fix seaching an external SMuFL font's metadata.json So far all fonts I've encountered have their metadata.json named "FontName.json" (mixed case, possible containing spaces, same as the fontname itself, the only documented option for non-private fonts), "fontname_metadata.json" (all lowercase, no spaces) or "metadata.json" (lowercase), so let's search for these, in that order and stop at the 1st hit. As a last reseort leave the previous iteration method (which stops at the last match for "*.json"). --- .../internal/engravingfontscontroller.cpp | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/notation/internal/engravingfontscontroller.cpp b/src/notation/internal/engravingfontscontroller.cpp index 7ab43750e8cb3..fe4e0df13ea44 100644 --- a/src/notation/internal/engravingfontscontroller.cpp +++ b/src/notation/internal/engravingfontscontroller.cpp @@ -98,24 +98,36 @@ void EngravingFontsController::scanDirectory(const muse::io::path_t& path, bool while (iterator.hasNext()) { iterator.next(); QString fontDir = iterator.filePath(); - muse::io::path_t metadataPath; - - { - QDirIterator jsonFilesIterator(fontDir, { "*.json" }, QDir::Files); - while (jsonFilesIterator.hasNext()) { - jsonFilesIterator.next(); - metadataPath = jsonFilesIterator.filePath(); + QString fontName = iterator.fileName(); + muse::io::path_t metadataPath = fontDir + "/" + fontName + ".json"; + QFile fi(metadataPath.toQString()); + if (!fi.exists()) { + if (isPrivate) { + metadataPath = fontDir + "/" + fontName.toLower().replace(" ", "_") + "_metadata.json"; + fi.setFileName(metadataPath.toQString()); + if (!fi.exists()) { + metadataPath = fontDir + "/" + "metadata.json"; + fi.setFileName(metadataPath.toQString()); + } + if (!fi.exists()) { + metadataPath = muse::io::path_t(); + QDirIterator jsonFilesIterator(fontDir, { "*.json" }, QDir::Files); + while (jsonFilesIterator.hasNext()) { + jsonFilesIterator.next(); + metadataPath = jsonFilesIterator.filePath(); + } + if (metadataPath.empty()) { + continue; + } + } + } else { + continue; } } - if (metadataPath.empty()) { - continue; - } - // We assume the font name is the same as the directory name, // but maybe we should instead read the metadata.json file to get the font name - QString fontName = iterator.fileName(); QString fontFamily = fontName; if (fontName.contains(u"Text")) {