Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "engravingfontsprovider.h"
24 :
25 : #include "global/stringutils.h"
26 :
27 : #include "io/file.h"
28 : #include "log.h"
29 :
30 : using namespace mu;
31 : using namespace mu::engraving;
32 :
33 16 : void EngravingFontsProvider::deinit()
34 : {
35 16 : m_symbolFonts.clear();
36 16 : m_externalSymbolFonts.clear();
37 16 : m_fallback.font = nullptr;
38 16 : }
39 :
40 128 : void EngravingFontsProvider::addInternalFont(const std::string& name, const std::string& family, const muse::io::path_t& filePath)
41 : {
42 128 : muse::io::path_t basePath = muse::io::dirpath(filePath.toQString());
43 128 : muse::io::path_t metadataPath = basePath + "/metadata.json";
44 128 : std::shared_ptr<EngravingFont> f = std::make_shared<EngravingFont>(name, family, filePath, metadataPath);
45 128 : m_symbolFonts.push_back(f);
46 128 : m_fallback.font = nullptr;
47 128 : }
48 :
49 0 : void EngravingFontsProvider::addExternalFont(const std::string& name, const std::string& family, const muse::io::path_t& filePath,
50 : const muse::io::path_t& metadataPath)
51 : {
52 0 : addExternalFont(name, family, std::make_shared<muse::io::File>(filePath), std::make_shared<muse::io::File>(metadataPath));
53 0 : }
54 :
55 0 : void EngravingFontsProvider::addExternalFont(const std::string& name, const std::string& family, std::shared_ptr<muse::io::IODevice> font,
56 : std::shared_ptr<muse::io::IODevice> metadata)
57 : {
58 : UNUSED(family);
59 0 : std::shared_ptr<EngravingFont> f = std::make_shared<EngravingFont>(name, family, std::move(font), std::move(metadata));
60 0 : m_externalSymbolFonts.emplace(muse::strings::toLower(name), f);
61 0 : }
62 :
63 10636 : std::shared_ptr<EngravingFont> EngravingFontsProvider::doFontByName(const std::string& name) const
64 : {
65 : // External fonts should have higher priority than internal fonts
66 10636 : std::string name_lo = muse::strings::toLower(name);
67 10636 : auto it = m_externalSymbolFonts.find(name_lo);
68 10636 : if (it != m_externalSymbolFonts.end()) {
69 0 : return it->second;
70 : }
71 23099 : for (const std::shared_ptr<EngravingFont>& f : m_symbolFonts) {
72 23099 : if (muse::strings::toLower(f->name()) == name_lo) {
73 10636 : return f;
74 : }
75 : }
76 0 : return nullptr;
77 10636 : }
78 :
79 10620 : IEngravingFontPtr EngravingFontsProvider::fontByName(const std::string& name) const
80 : {
81 10620 : std::shared_ptr<EngravingFont> font = doFontByName(name);
82 10620 : if (!font) {
83 0 : font = doFallbackFont();
84 : }
85 :
86 10620 : font->ensureLoad();
87 21240 : return font;
88 10620 : }
89 :
90 0 : std::vector<IEngravingFontPtr> EngravingFontsProvider::fonts() const
91 : {
92 0 : std::vector<IEngravingFontPtr> fs;
93 0 : for (const std::shared_ptr<EngravingFont>& f : m_symbolFonts) {
94 0 : std::string name_lo = muse::strings::toLower(f->name());
95 0 : if (m_externalSymbolFonts.find(name_lo) == m_externalSymbolFonts.end()) {
96 0 : fs.push_back(f);
97 : }
98 0 : }
99 0 : for (const auto& [_, f] : m_externalSymbolFonts) {
100 0 : fs.push_back(f);
101 : }
102 0 : return fs;
103 0 : }
104 :
105 16 : void EngravingFontsProvider::setFallbackFont(const std::string& name)
106 : {
107 16 : m_fallback.name = name;
108 16 : m_fallback.font = nullptr;
109 16 : }
110 :
111 23159 : std::shared_ptr<EngravingFont> EngravingFontsProvider::doFallbackFont() const
112 : {
113 23159 : if (!m_fallback.font) {
114 16 : m_fallback.font = doFontByName(m_fallback.name);
115 16 : IF_ASSERT_FAILED(m_fallback.font) {
116 0 : return nullptr;
117 : }
118 : }
119 :
120 23159 : return m_fallback.font;
121 : }
122 :
123 11915 : IEngravingFontPtr EngravingFontsProvider::fallbackFont() const
124 : {
125 11915 : std::shared_ptr<EngravingFont> font = doFallbackFont();
126 11915 : font->ensureLoad();
127 23830 : return font;
128 11915 : }
129 :
130 11244 : bool EngravingFontsProvider::isFallbackFont(const IEngravingFont* f) const
131 : {
132 11244 : return doFallbackFont().get() == f;
133 : }
134 :
135 0 : void EngravingFontsProvider::clearExternalFonts()
136 : {
137 0 : m_externalSymbolFonts.clear();
138 0 : }
139 :
140 16 : void EngravingFontsProvider::loadAllFonts()
141 : {
142 144 : for (std::shared_ptr<EngravingFont>& f : m_symbolFonts) {
143 128 : f->ensureLoad();
144 : }
145 16 : for (const auto& [_, f] : m_externalSymbolFonts) {
146 0 : f->ensureLoad();
147 : }
148 16 : }
|