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 
7 #include "mythfontmanager.h"
8 #include "mythlogging.h"
9 
10 static MythFontManager *gFontManager = nullptr;
11 
12 #define LOC QString("MythFontManager: ")
13 #define MAX_DIRS 100
14 
28 void MythFontManager::LoadFonts(const QString &directory,
29  const QString &registeredFor)
30 {
31  int maxDirs = MAX_DIRS;
32  LoadFonts(directory, registeredFor, &maxDirs);
33 
34  QFontDatabase database;
35  for (const QString & family : database.families())
36  {
37  QString result = QString("Font Family '%1': ").arg(family);
38  for (const QString & style : database.styles(family))
39  {
40  result += QString("%1(").arg(style);
41 
42  QString sizes;
43  for (int points : database.smoothSizes(family, style))
44  sizes += QString::number(points) + ' ';
45 
46  result += QString("%1) ").arg(sizes.trimmed());
47  }
48 
49  LOG(VB_GUI, LOG_DEBUG, LOC + result.trimmed());
50  }
51 }
52 
65 void MythFontManager::LoadFonts(const QString &directory,
66  const QString &registeredFor, int *maxDirs)
67 {
68  if (directory.isEmpty() || directory == "/" || registeredFor.isEmpty())
69  return;
70  (*maxDirs)--;
71  if (*maxDirs < 1)
72  {
73  LOG(VB_GENERAL, LOG_WARNING, LOC +
74  "Reached the maximum directory depth "
75  "for a font directory structure. Terminating font scan.");
76  return;
77  }
78 
79  // Load the font files from this directory
80  LoadFontsFromDirectory(directory, registeredFor);
81  // Recurse through subdirectories
82  QDir dir(directory);
83  QFileInfoList files = dir.entryInfoList();
84  QFileInfo info;
85  for (QFileInfoList::const_iterator it = files.begin();
86  ((it != files.end()) && (*maxDirs > 0)); ++it)
87  {
88  info = *it;
89  // Skip '.' and '..' and other files starting with "." by checking
90  // baseName()
91  if (!info.baseName().isEmpty() && info.isDir())
92  LoadFonts(info.absoluteFilePath(), registeredFor, maxDirs);
93  }
94 }
95 
102 void MythFontManager::ReleaseFonts(const QString &registeredFor)
103 {
104  if (registeredFor.isEmpty())
105  return;
106 
107  QMutexLocker locker(&m_lock);
108  for (FontPathToReference::iterator it = m_fontPathToReference.begin();
109  it != m_fontPathToReference.end();)
110  {
111  MythFontReference *fontRef = it.value();
112  if (registeredFor == fontRef->GetRegisteredFor())
113  {
114  LOG(VB_FILE, LOG_DEBUG, LOC +
115  QString("Removing application font '%1'")
116  .arg(fontRef->GetFontPath()));
117 
118  it = m_fontPathToReference.erase(it);
119  if (!IsFontFileLoaded(fontRef->GetFontPath()))
120  {
121  if (QFontDatabase::removeApplicationFont(fontRef->GetFontID()))
122  {
123  LOG(VB_FILE, LOG_DEBUG, LOC +
124  QString("Successfully removed application font '%1'")
125  .arg(fontRef->GetFontPath()));
126  }
127  else
128  {
129  LOG(VB_GENERAL, LOG_WARNING, LOC +
130  QString("Unable to remove application font '%1'")
131  .arg(fontRef->GetFontPath()));
132  }
133  }
134  delete fontRef;
135  }
136  else
137  {
138  ++it;
139  }
140  }
141 }
142 
152 void MythFontManager::LoadFontsFromDirectory(const QString &directory,
153  const QString &registeredFor)
154 {
155  if (directory.isEmpty() || directory == "/" || registeredFor.isEmpty())
156  return;
157 
158  LOG(VB_FILE, LOG_DEBUG, LOC +
159  QString("Scanning directory '%1' for font files.").arg(directory));
160 
161  QDir dir(directory);
162  QStringList nameFilters = QStringList() << "*.ttf" << "*.otf" << "*.ttc";
163  QStringList fontFiles = dir.entryList(nameFilters);
164  for (QStringList::const_iterator it = fontFiles.begin();
165  it != fontFiles.end(); ++it)
166  {
167  LoadFontFile(dir.absoluteFilePath(*it), registeredFor);
168  }
169 }
170 
177 void MythFontManager::LoadFontFile(const QString &fontPath,
178  const QString &registeredFor)
179 {
180  if (fontPath.isEmpty() || fontPath == "/" || registeredFor.isEmpty())
181  return;
182 
183  QMutexLocker locker(&m_lock);
184  if (IsFontFileLoaded(fontPath))
185  {
186  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
187  QString("Font file '%1' already loaded")
188  .arg(fontPath));
189 
190  if (!RegisterFont(fontPath, registeredFor))
191  {
192  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
193  QString("Unable to load font(s) in file '%1'")
194  .arg(fontPath));
195  }
196  }
197  else
198  {
199  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
200  QString("Loading font file: '%1'").arg(fontPath));
201 
202  int result = QFontDatabase::addApplicationFont(fontPath);
203  if (result > -1)
204  {
205  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
206  QString("In file '%1', found font(s) '%2'")
207  .arg(fontPath)
208  .arg(QFontDatabase::applicationFontFamilies(result)
209  .join(", ")));
210 
211  if (!RegisterFont(fontPath, registeredFor, result))
212  {
213  LOG(VB_GENERAL, LOG_WARNING, LOC +
214  QString("Unable to register font(s) in file '%1'")
215  .arg(fontPath));
216  }
217  }
218  else
219  {
220  LOG(VB_GENERAL, LOG_WARNING, LOC +
221  QString("Unable to load font(s) in file '%1'")
222  .arg(fontPath));
223  }
224  }
225 }
226 
235 bool MythFontManager::RegisterFont(const QString &fontPath,
236  const QString &registeredFor,
237  const int fontID)
238 {
239  int id = fontID;
240  if (id == -1)
241  {
242  QList<MythFontReference*> values;
243  values = m_fontPathToReference.values(fontPath);
244  if (values.isEmpty())
245  return false;
246  MythFontReference *ref = values.first();
247  if (ref == nullptr)
248  return false;
249  id = ref->GetFontID();
250  }
251  auto *fontReference = new MythFontReference(fontPath, registeredFor, id);
252  m_fontPathToReference.insert(fontPath, fontReference);
253  return true;
254 }
255 
261 bool MythFontManager::IsFontFileLoaded(const QString &fontPath)
262 {
263  QList<MythFontReference*> values = m_fontPathToReference.values(fontPath);
264  return !values.isEmpty();
265 }
266 
268 {
269  if (!gFontManager)
271  return gFontManager;
272 }
273 
275 {
277 }
278 
279 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythFontManager
Definition: mythfontmanager.h:18
LOC
#define LOC
Definition: mythfontmanager.cpp:12
MythFontManager::IsFontFileLoaded
bool IsFontFileLoaded(const QString &fontPath)
Checks whether the specified font file has already been loaded.
Definition: mythfontmanager.cpp:261
arg
arg(title).arg(filename).arg(doDelete))
MythFontManager::m_lock
QMutex m_lock
Definition: mythfontmanager.h:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
mythfontmanager.h
MAX_DIRS
#define MAX_DIRS
Definition: mythfontmanager.cpp:13
mythlogging.h
MythFontManager::MythFontManager
MythFontManager()=default
GetGlobalFontManager
MythFontManager * GetGlobalFontManager(void)
Definition: mythfontmanager.cpp:274
MythFontManager::RegisterFont
bool RegisterFont(const QString &fontPath, const QString &registeredFor, int fontID=-1)
Registers the font as being used by registeredFor.
Definition: mythfontmanager.cpp:235
gFontManager
static MythFontManager * gFontManager
Definition: mythfontmanager.cpp:10
MythFontManager::LoadFonts
void LoadFonts(const QString &directory, const QString &registeredFor)
Loads the fonts in font files within the given directory structure.
Definition: mythfontmanager.cpp:28
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1171
MythFontManager::LoadFontsFromDirectory
void LoadFontsFromDirectory(const QString &directory, const QString &registeredFor)
Loads fonts from font files in the specified directory.
Definition: mythfontmanager.cpp:152
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
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:102
MythFontReference::GetRegisteredFor
QString GetRegisteredFor(void) const
Definition: mythfontmanager.h:54
MythFontManager::GetGlobalFontManager
static MythFontManager * GetGlobalFontManager(void)
Definition: mythfontmanager.cpp:267
MythFontManager::LoadFontFile
void LoadFontFile(const QString &fontPath, const QString &registeredFor)
Loads fonts from the file specified in fontPath.
Definition: mythfontmanager.cpp:177
MythFontReference
Definition: mythfontmanager.h:45