23 #include <QApplication> 26 #include <QFontDatabase> 28 #include <QStringList> 34 QFontInfo fi = QFontInfo( f );
35 return fi.exactMatch();
40 QFont tmpFont = QFont( family );
42 return tmpFont.family().startsWith( family, Qt::CaseInsensitive );
51 if ( fontDB.styles( family ).contains( style ) )
55 QString modified( style );
56 if ( style ==
"Roman" )
58 if ( style ==
"Oblique" )
60 if ( style ==
"Bold Oblique" )
61 modified =
"Bold Italic";
62 if ( fontDB.styles( family ).contains( modified ) )
72 QStringList fontFamilies = fontDB.families();
75 QList<QString>::const_iterator it = fontFamilies.constBegin();
76 for ( ; it != fontFamilies.constEnd(); ++it )
79 if ( it->startsWith( family, Qt::CaseInsensitive ) )
86 *match = ( *it == family );
102 QFont f = QFont( family );
103 *chosen = f.family();
124 if ( fontstyle.isEmpty() )
129 QFontDatabase fontDB;
142 if ( fontstyle == fontDB.styleString( f ) )
147 QFont appfont = QApplication::font();
148 int defaultSize = appfont.pointSize();
151 bool foundmatch =
false;
154 styledfont = fontDB.font( f.family(), fontstyle, defaultSize );
155 if ( appfont != styledfont || fontstyle != fontDB.styleString( f ) )
162 if ( fallback && !foundmatch )
164 QFont testFont = QFont( f );
165 testFont.setPointSize( defaultSize );
168 const auto constFamily = fontDB.styles( f.family() );
169 for (
const QString &style : constFamily )
171 styledfont = fontDB.font( f.family(), style, defaultSize );
172 styledfont = styledfont.resolve( f );
173 if ( testFont.toString() == styledfont.toString() )
183 const auto constFamily = fontDB.styles( f.family() );
184 for (
const QString &style : constFamily )
186 styledfont = fontDB.font( f.family(), style, defaultSize );
187 if ( QApplication::font() != styledfont )
202 styledfont.setPointSizeF( f.pointSizeF() );
204 else if ( f.pixelSize() != -1 )
206 styledfont.setPixelSize( f.pixelSize() );
208 styledfont.setCapitalization( f.capitalization() );
209 styledfont.setUnderline( f.underline() );
210 styledfont.setStrikeOut( f.strikeOut() );
211 styledfont.setWordSpacing( f.wordSpacing() );
212 styledfont.setLetterSpacing( QFont::AbsoluteSpacing, f.letterSpacing() );
223 return QStringLiteral(
"QGIS Vera Sans" );
229 bool fontsLoaded =
false;
232 QMap<QString, QString> fontStyles;
233 fontStyles.insert( QStringLiteral(
"Roman" ), QStringLiteral(
"QGIS-Vera/QGIS-Vera.ttf" ) );
234 fontStyles.insert( QStringLiteral(
"Oblique" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraIt.ttf" ) );
235 fontStyles.insert( QStringLiteral(
"Bold" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraBd.ttf" ) );
236 fontStyles.insert( QStringLiteral(
"Bold Oblique" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraBI.ttf" ) );
238 QMap<QString, QString>::const_iterator f = fontStyles.constBegin();
239 for ( ; f != fontStyles.constEnd(); ++f )
241 QString fontstyle( f.key() );
242 QString fontpath( f.value() );
243 if ( !( loadstyles.contains( fontstyle ) || loadstyles.contains( QStringLiteral(
"All" ) ) ) )
250 QgsDebugMsg( QStringLiteral(
"Test font '%1 %2' already available" ).arg( fontFamily, fontstyle ) );
262 int fontID = QFontDatabase::addApplicationFont( fontPath );
263 loaded = ( fontID != -1 );
264 fontsLoaded = ( fontsLoaded || loaded );
265 QgsDebugMsg( QStringLiteral(
"Test font '%1 %2' %3 from filesystem [%4]" )
266 .arg( fontFamily, fontstyle, loaded ?
"loaded" :
"FAILED to load", fontPath ) );
268 QgsDebugMsg( QStringLiteral(
"font families in %1: %2" ).arg( fontID ).arg( db.applicationFontFamilies( fontID ).join(
"," ) ) );
272 QFile fontResource(
":/testdata/font/" + fontpath );
273 if ( fontResource.open( QIODevice::ReadOnly ) )
275 int fontID = QFontDatabase::addApplicationFontFromData( fontResource.readAll() );
276 loaded = ( fontID != -1 );
277 fontsLoaded = ( fontsLoaded || loaded );
279 QgsDebugMsg( QStringLiteral(
"Test font '%1' (%2) %3 from testdata.qrc" )
280 .arg( fontFamily, fontstyle, loaded ?
"loaded" :
"FAILED to load" ) );
295 QFontDatabase fontDB;
298 if ( !f.exactMatch() )
301 if ( style ==
"Roman" )
303 else if ( style ==
"Oblique" )
305 else if ( style ==
"Bold Oblique" )
306 modified =
"Bold Italic";
307 if ( !modified.isEmpty() )
310 if ( !f.exactMatch() )
313 QgsDebugMsg( QStringLiteral(
"Requested: %1" ).arg( f.toString() ) );
315 QgsDebugMsg( QStringLiteral(
"Replaced: %1,%2,%3,%4,%5,%6,%7,%8,%9,%10" ).arg( fi.family() ).arg( fi.pointSizeF() ).arg( fi.pixelSize() ).arg( fi.styleHint() ).arg( fi.weight() ).arg( fi.style() ).arg( fi.underline() ).arg( fi.strikeOut() ).arg( fi.fixedPitch() ).arg( fi.rawMode() ) );
319 f.setBold( style.contains( QLatin1String(
"Bold" ) ) );
320 f.setItalic( style.contains( QLatin1String(
"Oblique" ) ) || style.contains( QLatin1String(
"Italic" ) ) );
327 QDomElement fontElem = document.createElement( elementName );
328 fontElem.setAttribute( QStringLiteral(
"description" ), font.toString() );
335 if ( element.isNull() )
340 font.fromString( element.attribute( QStringLiteral(
"description" ) ) );
341 if ( element.hasAttribute( QStringLiteral(
"style" ) ) )
351 if ( element.isNull() )
356 QDomNodeList nodeList = element.elementsByTagName( childNode );
357 if ( !nodeList.isEmpty() )
359 QDomElement fontElem = nodeList.at( 0 ).toElement();
370 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
372 QDomDocument fontDoc;
373 QDomElement fontElem =
toXmlElement( font, fontDoc, QStringLiteral(
"font" ) );
374 fontDoc.appendChild( fontElem );
375 mimeData->setText( fontDoc.toString() );
377 return mimeData.release();
389 QString text = data->text();
390 if ( !text.isEmpty() )
395 if ( doc.setContent( text ) )
397 elem = doc.documentElement();
399 if ( elem.nodeName() != QStringLiteral(
"font" ) )
400 elem = elem.firstChildElement( QStringLiteral(
"font" ) );
413 static QMap<QString, QString> createTranslatedStyleMap()
415 QMap<QString, QString> translatedStyleMap;
416 QStringList words = QStringList()
417 << QStringLiteral(
"Normal" )
418 << QStringLiteral(
"Regular" )
419 << QStringLiteral(
"Light" )
420 << QStringLiteral(
"Bold" )
421 << QStringLiteral(
"Black" )
422 << QStringLiteral(
"Demi" )
423 << QStringLiteral(
"Italic" )
424 << QStringLiteral(
"Oblique" );
425 const auto constWords = words;
426 for (
const QString &word : constWords )
428 translatedStyleMap.insert( QCoreApplication::translate(
"QFontDatabase", qPrintable( word ) ), word );
430 return translatedStyleMap;
435 QStringList words = namedStyle.split(
' ', QString::SkipEmptyParts );
436 for (
int i = 0, n = words.length(); i < n; ++i )
438 words[i] = QCoreApplication::translate(
"QFontDatabase", words[i].toUtf8(),
nullptr, QCoreApplication::UnicodeUTF8 );
440 return words.join( QStringLiteral(
" " ) );
445 static QMap<QString, QString> translatedStyleMap = createTranslatedStyleMap();
446 QStringList words = namedStyle.split(
' ', QString::SkipEmptyParts );
447 for (
int i = 0, n = words.length(); i < n; ++i )
449 if ( translatedStyleMap.contains( words[i] ) )
451 words[i] = translatedStyleMap.value( words[i] );
455 QgsDebugMsg( QStringLiteral(
"Warning: style map does not contain %1" ).arg( words[i] ) );
458 return words.join( QStringLiteral(
" " ) );
463 QString css = QStringLiteral(
"font-family: " ) + font.family() +
';';
466 css += QLatin1String(
"font-style: " );
467 switch ( font.style() )
469 case QFont::StyleNormal:
470 css += QLatin1String(
"normal" );
472 case QFont::StyleItalic:
473 css += QLatin1String(
"italic" );
475 case QFont::StyleOblique:
476 css += QLatin1String(
"oblique" );
483 switch ( font.weight() )
491 case QFont::DemiBold:
503 case QFont::ExtraLight:
509 case QFont::ExtraBold:
513 css += QStringLiteral(
"font-weight: %1;" ).arg( cssWeight );
516 css += QStringLiteral(
"font-size: %1px;" ).arg( font.pointSizeF() >= 0 ? font.pointSizeF() * pointToPixelScale : font.pixelSize() );
523 if ( family.isEmpty() )
529 QStringList recentFamilies = settings.
value( QStringLiteral(
"fonts/recent" ) ).toStringList();
532 recentFamilies.removeAll( family );
535 recentFamilies.prepend( family );
538 recentFamilies = recentFamilies.mid( 0, 10 );
540 settings.
setValue( QStringLiteral(
"fonts/recent" ), recentFamilies );
546 return settings.
value( QStringLiteral(
"fonts/recent" ) ).toStringList();
static QFont fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QFont.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
static bool setFromXmlElement(QFont &font, const QDomElement &element)
Sets the properties of a font to match the properties stored in an XML element.
static bool fontFamilyHasStyle(const QString &family, const QString &style)
Check whether font family on system has specific style.
static bool isRunningFromBuildDir()
Indicates whether running from build directory (not installed)
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static QString asCSS(const QFont &font, double pointToPixelMultiplier=1.0)
Returns a CSS string representing the specified font as closely as possible.
static QStringList recentFontFamilies()
Returns a list of recently used font families.
static bool fontFamilyOnSystem(const QString &family)
Check whether font family is on system in a quick manner, which does not compare [foundry].
static QFont getStandardTestFont(const QString &style="Roman", int pointsize=12)
Gets standard test font with specific style.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static bool loadStandardTestFonts(const QStringList &loadstyles)
Loads standard test fonts from filesystem or qrc resource.
static QString standardTestFontFamily()
Gets standard test font family.
static void addRecentFontFamily(const QString &family)
Adds a font family to the list of recently used font families.
static QString untranslateNamedStyle(const QString &namedStyle)
Returns the english named style of a font, if possible.
static QString buildSourcePath()
Returns path to the source directory. Valid only when running from build directory.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static bool fontMatchOnSystem(const QFont &f)
Check whether exact font is on system.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
static QMimeData * toMimeData(const QFont &font)
Returns new mime data representing the specified font settings.