From abb70401f00c0f87a0d8b06bf5b06c564534f4d2 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 19baa7fe7e4b8..6585e7950dcec 100644 --- a/src/notation/internal/engravingfontscontroller.cpp +++ b/src/notation/internal/engravingfontscontroller.cpp @@ -141,19 +141,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 5909a2846a6b6e577cfb1d7262e92b09821d0a83 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 6585e7950dcec..3ad68e1ec3939 100644 --- a/src/notation/internal/engravingfontscontroller.cpp +++ b/src/notation/internal/engravingfontscontroller.cpp @@ -102,24 +102,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")) {