6 #include <QCoreApplication>
7 #include <QDomDocument>
9 #include <QFontDatabase>
11 #include <QRegularExpression>
21 #define LOC QString("MythFontProperties: ")
23 #define KEEP_OLD_NAMES 1 // NOLINT(cppcoreguidelines-macro-usage)
56 const QColor &color,
int alpha)
141 int newStretch = lroundf((
float)
m_stretch * ((
float)stretch / 100.0F));
146 m_face.setStretch(newStretch);
158 float pixels = (float)points / 72.0F * 100.0F;
175 const QDomElement &element,
182 static bool s_showAvailable =
true;
183 bool fromBase =
false;
187 if (element.tagName() ==
"font")
189 LOG(VB_GENERAL, LOG_WARNING,
LOC +
190 QString(
"File %1: Use of 'font' is deprecated in favour of "
194 QString name = element.attribute(
"name",
"");
198 filename, element,
"Font requires a name");
203 QString base = element.attribute(
"from",
"");
218 QString(
"Specified base font '%1' does not exist.").arg(base));
231 QString
face = element.attribute(
"face",
"");
237 "Font needs a face");
244 newFont->m_face.setFamily(
face);
253 QString(
"Attempting to define '%1'\n\t\t\t"
254 "with face '%2', but it already "
255 "exists with face '%3'")
256 .arg(name, QFontInfo(newFont->m_face).family(),
257 (
tmp) ? QFontInfo(
tmp->m_face).family() :
"ERROR"));
263 QString hint = element.attribute(
"stylehint",
"");
266 newFont->m_face.setStyleHint((QFont::StyleHint)hint.toInt());
269 for (QDomNode child = element.firstChild(); !child.isNull();
270 child = child.nextSibling())
272 QDomElement
info = child.toElement();
275 if (
info.tagName() ==
"size")
279 else if (
info.tagName() ==
"pixelsize")
283 else if (
info.tagName() ==
"color")
287 else if (
info.tagName() ==
"gradient")
291 else if (
info.tagName() ==
"shadowcolor")
295 else if (
info.tagName() ==
"shadowoffset")
297 newFont->m_hasShadow =
true;
300 else if (
info.tagName() ==
"shadowalpha")
304 else if (
info.tagName() ==
"outlinecolor")
308 else if (
info.tagName() ==
"outlinesize")
310 newFont->m_hasOutline =
true;
313 else if (
info.tagName() ==
"outlinealpha")
317 else if (
info.tagName() ==
"italics")
321 else if (
info.tagName() ==
"letterspacing")
323 newFont->m_face.setLetterSpacing(QFont::AbsoluteSpacing,
326 else if (
info.tagName() ==
"wordspacing")
330 else if (
info.tagName() ==
"decoration")
333 QStringList values = dec.split(
',');
335 QStringList::Iterator it;
336 for ( it = values.begin(); it != values.end(); ++it )
338 if (*it ==
"underline")
339 newFont->m_face.setUnderline(
true);
340 else if (*it ==
"overline")
341 newFont->m_face.setOverline(
true);
342 else if (*it ==
"strikeout")
343 newFont->m_face.setStrikeOut(
true);
346 else if (
info.tagName() ==
"weight")
350 if (weight ==
"thin" ||
352 newFont->m_face.setWeight(QFont::Thin);
353 else if (weight ==
"extralight" ||
355 weight ==
"ultralight" ||
358 newFont->m_face.setWeight(QFont::ExtraLight);
359 else if (weight ==
"light" ||
361 newFont->m_face.setWeight(QFont::Light);
362 else if (weight ==
"normal" ||
364 newFont->m_face.setWeight(QFont::Normal);
365 else if (weight ==
"medium" ||
367 newFont->m_face.setWeight(QFont::Medium);
368 else if (weight ==
"demibold" ||
370 newFont->m_face.setWeight(QFont::DemiBold);
371 else if (weight ==
"bold" ||
373 newFont->m_face.setWeight(QFont::Bold);
374 else if (weight ==
"extrabold" ||
376 newFont->m_face.setWeight(QFont::ExtraBold);
377 else if (weight ==
"black" ||
379 weight ==
"ultrablack" ||
382 newFont->m_face.setWeight(QFont::Black);
384 newFont->m_face.setWeight(QFont::Normal);
386 else if (
info.tagName() ==
"stretch")
390 if (stretch ==
"ultracondensed" ||
392 newFont->m_stretch = QFont::UltraCondensed;
393 else if (stretch ==
"extracondensed" ||
395 newFont->m_stretch = QFont::ExtraCondensed;
396 else if (stretch ==
"condensed" ||
398 newFont->m_stretch = QFont::Condensed;
399 else if (stretch ==
"semicondensed" ||
401 newFont->m_stretch = QFont::SemiCondensed;
402 else if (stretch ==
"unstretched" ||
404 newFont->m_stretch = QFont::Unstretched;
405 else if (stretch ==
"semiexpanded" ||
407 newFont->m_stretch = QFont::SemiExpanded;
408 else if (stretch ==
"expanded" ||
410 newFont->m_stretch = QFont::Expanded;
411 else if (stretch ==
"extraexpanded" ||
413 newFont->m_stretch = QFont::ExtraExpanded;
414 else if (stretch ==
"ultraexpanded" ||
416 newFont->m_stretch = QFont::UltraExpanded;
418 newFont->m_stretch = QFont::Unstretched;
420 newFont->m_face.setStretch(newFont->m_stretch);
425 QString(
"Unknown tag in font '%1'").arg(name));
432 if (size <= 0 && pixelsize <= 0 && !fromBase)
435 "Font size must be greater than 0.");
441 newFont->SetPixelSize(pixelsize);
445 newFont->SetPointSize(size);
450 static const QRegularExpression re {
"\\[.*]" };
451 QFontInfo fi(newFont->m_face);
453 fi.family().remove(re).trimmed();
454 if (newFont->m_face.family() != fi_family)
457 QString(
"Failed to load '%1', got '%2' instead")
458 .arg(newFont->m_face.family(), fi.family()));
462 LOG(VB_GUI, LOG_DEBUG,
"Available fonts:");
464 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
465 QFontDatabase database;
466 QStringList families = database.families();
468 QStringList families = QFontDatabase::families();
470 for (
const QString & family : std::as_const(families))
472 QStringList family_styles;
474 family_styles << family +
"::";
475 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
476 QStringList styles = database.styles(family);
478 QStringList styles = QFontDatabase::styles(family);
480 for (
const QString & style : std::as_const(styles))
482 family_styles << style +
":";
486 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
487 QList<int> pointList = database.smoothSizes(family, style);
489 QList<int> pointList = QFontDatabase::smoothSizes(family, style);
491 for (
int points : std::as_const(pointList))
496 sizes += QString::number(points);
500 family_styles << sizes.trimmed();
502 LOG(VB_GUI, LOG_DEBUG, family_styles.join(
" "));
504 s_showAvailable =
false;
510 QString(
"loaded '%1'").arg(fi.family()));
536 if (!font || text.isEmpty())
541 LOG(VB_GENERAL, LOG_ERR,
LOC +
542 QString(
"Already have a font: %1").arg(text));
584 height = rect.height();
587 QMap<QString, MythFontProperties>::iterator it;
590 (*it).Rescale(height);