MythTV  master
mythfontmanager.cpp
Go to the documentation of this file.
1 #include <QDir>
2 #include <QFileInfo>
3 #include <QFontDatabase>
4 #include <QList>
5 #include <QMutexLocker>
6 
8 
9 #include "mythfontmanager.h"
10 
11 static MythFontManager *gFontManager = nullptr;
12 
13 #define LOC QString("MythFontManager: ")
14 static constexpr int8_t MAX_DIRS { 100 };
15 
29 void MythFontManager::LoadFonts(const QString &directory,
30  const QString &registeredFor)
31 {
32  int maxDirs = MAX_DIRS;
33  LoadFonts(directory, registeredFor, &maxDirs);
34 
35 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
36  QFontDatabase database;
37  QStringList families = database.families();
38 #else
39  QStringList families = QFontDatabase::families();
40 #endif
41  for (const QString & family : std::as_const(families))
42  {
43  QString result = QString("Font Family '%1': ").arg(family);
44 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
45  QStringList styles = database.styles(family);
46 #else
47  QStringList styles = QFontDatabase::styles(family);
48 #endif
49  for (const QString & style : std::as_const(styles))
50  {
51  result += QString("%1(").arg(style);
52 
53  QString sizes;
54 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
55  QList<int> pointList = database.smoothSizes(family, style);
56 #else
57  QList<int> pointList = QFontDatabase::smoothSizes(family, style);
58 #endif
59  for (int points : std::as_const(pointList))
60  sizes += QString::number(points) + ' ';
61 
62  result += QString("%1) ").arg(sizes.trimmed());
63  }
64 
65  LOG(VB_GUI, LOG_DEBUG, LOC + result.trimmed());
66  }
67 }
68 
81 void MythFontManager::LoadFonts(const QString &directory,
82  const QString &registeredFor, int *maxDirs)
83 {
84  if (directory.isEmpty() || directory == "/" || registeredFor.isEmpty())
85  return;
86  (*maxDirs)--;
87  if (*maxDirs < 1)
88  {
89  LOG(VB_GENERAL, LOG_WARNING, LOC +
90  "Reached the maximum directory depth "
91  "for a font directory structure. Terminating font scan.");
92  return;
93  }
94 
95  // Load the font files from this directory
96  LoadFontsFromDirectory(directory, registeredFor);
97  // Recurse through subdirectories
98  QDir dir(directory);
99  QFileInfoList files = dir.entryInfoList();
100  for (const auto& info : std::as_const(files))
101  {
102  // Skip '.' and '..' and other files starting with "." by checking
103  // baseName()
104  if (!info.baseName().isEmpty() && info.isDir())
105  LoadFonts(info.absoluteFilePath(), registeredFor, maxDirs);
106  if (*maxDirs <= 0)
107  break;
108  }
109 }
110 
117 void MythFontManager::ReleaseFonts(const QString &registeredFor)
118 {
119  if (registeredFor.isEmpty())
120  return;
121 
122  QMutexLocker locker(&m_lock);
123  for (FontPathToReference::iterator it = m_fontPathToReference.begin();
124  it != m_fontPathToReference.end();)
125  {
126  MythFontReference *fontRef = it.value();
127  if (registeredFor == fontRef->GetRegisteredFor())
128  {
129  LOG(VB_FILE, LOG_DEBUG, LOC +
130  QString("Removing application font '%1'")
131  .arg(fontRef->GetFontPath()));
132 
133  it = m_fontPathToReference.erase(it);
134  if (!IsFontFileLoaded(fontRef->GetFontPath()))
135  {
136  if (QFontDatabase::removeApplicationFont(fontRef->GetFontID()))
137  {
138  LOG(VB_FILE, LOG_DEBUG, LOC +
139  QString("Successfully removed application font '%1'")
140  .arg(fontRef->GetFontPath()));
141  }
142  else
143  {
144  LOG(VB_GENERAL, LOG_WARNING, LOC +
145  QString("Unable to remove application font '%1'")
146  .arg(fontRef->GetFontPath()));
147  }
148  }
149  delete fontRef;
150  }
151  else
152  {
153  ++it;
154  }
155  }
156 }
157 
167 void MythFontManager::LoadFontsFromDirectory(const QString &directory,
168  const QString &registeredFor)
169 {
170  if (directory.isEmpty() || directory == "/" || registeredFor.isEmpty())
171  return;
172 
173  LOG(VB_FILE, LOG_DEBUG, LOC +
174  QString("Scanning directory '%1' for font files.").arg(directory));
175 
176  QDir dir(directory);
177  QStringList nameFilters = QStringList() << "*.ttf" << "*.otf" << "*.ttc";
178  QFileInfoList fontFileInfos = dir.entryInfoList(nameFilters);
179  for (const auto & info : std::as_const(fontFileInfos)) {
180  LoadFontFile(info.absoluteFilePath(), registeredFor);
181  }
182 }
183 
190 void MythFontManager::LoadFontFile(const QString &fontPath,
191  const QString &registeredFor)
192 {
193  if (fontPath.isEmpty() || fontPath == "/" || registeredFor.isEmpty())
194  return;
195 
196  QMutexLocker locker(&m_lock);
197  if (IsFontFileLoaded(fontPath))
198  {
199  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
200  QString("Font file '%1' already loaded")
201  .arg(fontPath));
202 
203  if (!RegisterFont(fontPath, registeredFor))
204  {
205  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
206  QString("Unable to load font(s) in file '%1'")
207  .arg(fontPath));
208  }
209  }
210  else
211  {
212  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
213  QString("Loading font file: '%1'").arg(fontPath));
214 
215  int result = QFontDatabase::addApplicationFont(fontPath);
216  if (result > -1)
217  {
218  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
219  QString("In file '%1', found font(s) '%2'")
220  .arg(fontPath,
221  QFontDatabase::applicationFontFamilies(result)
222  .join(", ")));
223 
224  if (!RegisterFont(fontPath, registeredFor, result))
225  {
226  LOG(VB_GENERAL, LOG_WARNING, LOC +
227  QString("Unable to register font(s) in file '%1'")
228  .arg(fontPath));
229  }
230  }
231  else
232  {
233  LOG(VB_GENERAL, LOG_WARNING, LOC +
234  QString("Unable to load font(s) in file '%1'")
235  .arg(fontPath));
236  }
237  }
238 }
239 
248 bool MythFontManager::RegisterFont(const QString &fontPath,
249  const QString &registeredFor,
250  const int fontID)
251 {
252  int id = fontID;
253  if (id == -1)
254  {
255  QList<MythFontReference*> values;
256  values = m_fontPathToReference.values(fontPath);
257  if (values.isEmpty())
258  return false;
259  MythFontReference *ref = values.first();
260  if (ref == nullptr)
261  return false;
262  id = ref->GetFontID();
263  }
264  auto *fontReference = new MythFontReference(fontPath, registeredFor, id);
265  m_fontPathToReference.insert(fontPath, fontReference);
266  return true;
267 }
268 
274 bool MythFontManager::IsFontFileLoaded(const QString &fontPath)
275 {
276  QList<MythFontReference*> values = m_fontPathToReference.values(fontPath);
277  return !values.isEmpty();
278 }
279 
281 {
282  if (!gFontManager)
284  return gFontManager;
285 }
286 
288 {
290 }
291 
292 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythFontManager
Definition: mythfontmanager.h:17
LOC
#define LOC
Definition: mythfontmanager.cpp:13
MythFontManager::IsFontFileLoaded
bool IsFontFileLoaded(const QString &fontPath)
Checks whether the specified font file has already been loaded.
Definition: mythfontmanager.cpp:274
MythFontManager::m_lock
QMutex m_lock
Definition: mythfontmanager.h:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythfontmanager.h
mythlogging.h
MAX_DIRS
static constexpr int8_t MAX_DIRS
Definition: mythfontmanager.cpp:14
MythFontManager::MythFontManager
MythFontManager()=default
GetGlobalFontManager
MythFontManager * GetGlobalFontManager(void)
Definition: mythfontmanager.cpp:287
MythFontManager::RegisterFont
bool RegisterFont(const QString &fontPath, const QString &registeredFor, int fontID=-1)
Registers the font as being used by registeredFor.
Definition: mythfontmanager.cpp:248
gFontManager
static MythFontManager * gFontManager
Definition: mythfontmanager.cpp:11
MythFontManager::LoadFonts
void LoadFonts(const QString &directory, const QString &registeredFor)
Loads the fonts in font files within the given directory structure.
Definition: mythfontmanager.cpp:29
MythFontManager::LoadFontsFromDirectory
void LoadFontsFromDirectory(const QString &directory, const QString &registeredFor)
Loads fonts from font files in the specified directory.
Definition: mythfontmanager.cpp:167
MythFontReference::GetFontPath
QString GetFontPath(void) const
Definition: mythfontmanager.h:53
MythFontManager::m_fontPathToReference
FontPathToReference m_fontPathToReference
Definition: mythfontmanager.h:38
MythFontReference::GetFontID
int GetFontID(void) const
Definition: mythfontmanager.h:55
azlyrics.info
dictionary info
Definition: azlyrics.py:7
MythFontManager::ReleaseFonts
void ReleaseFonts(const QString &registeredFor)
Removes the font references for registeredFor, and unloads the application font if it's no longer in ...
Definition: mythfontmanager.cpp:117
MythFontReference::GetRegisteredFor
QString GetRegisteredFor(void) const
Definition: mythfontmanager.h:54
MythFontManager::GetGlobalFontManager
static MythFontManager * GetGlobalFontManager(void)
Definition: mythfontmanager.cpp:280
MythFontManager::LoadFontFile
void LoadFontFile(const QString &fontPath, const QString &registeredFor)
Loads fonts from the file specified in fontPath.
Definition: mythfontmanager.cpp:190
MythFontReference
Definition: mythfontmanager.h:44