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 Q_FOREACH (
const QString &style, fontDB.styles( f.family() ) )
170 styledfont = fontDB.font( f.family(), style, defaultSize );
171 styledfont = styledfont.resolve( f );
172 if ( testFont.toString() == styledfont.toString() )
182 Q_FOREACH (
const QString &style, fontDB.styles( f.family() ) )
184 styledfont = fontDB.font( f.family(), style, defaultSize );
185 if ( QApplication::font() != styledfont )
200 styledfont.setPointSizeF( f.pointSizeF() );
202 else if ( f.pixelSize() != -1 )
204 styledfont.setPixelSize( f.pixelSize() );
206 styledfont.setCapitalization( f.capitalization() );
207 styledfont.setUnderline( f.underline() );
208 styledfont.setStrikeOut( f.strikeOut() );
209 styledfont.setWordSpacing( f.wordSpacing() );
210 styledfont.setLetterSpacing( QFont::AbsoluteSpacing, f.letterSpacing() );
221 return QStringLiteral(
"QGIS Vera Sans" );
227 bool fontsLoaded =
false;
230 QMap<QString, QString> fontStyles;
231 fontStyles.insert( QStringLiteral(
"Roman" ), QStringLiteral(
"QGIS-Vera/QGIS-Vera.ttf" ) );
232 fontStyles.insert( QStringLiteral(
"Oblique" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraIt.ttf" ) );
233 fontStyles.insert( QStringLiteral(
"Bold" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraBd.ttf" ) );
234 fontStyles.insert( QStringLiteral(
"Bold Oblique" ), QStringLiteral(
"QGIS-Vera/QGIS-VeraBI.ttf" ) );
236 QMap<QString, QString>::const_iterator f = fontStyles.constBegin();
237 for ( ; f != fontStyles.constEnd(); ++f )
239 QString fontstyle( f.key() );
240 QString fontpath( f.value() );
241 if ( !( loadstyles.contains( fontstyle ) || loadstyles.contains( QStringLiteral(
"All" ) ) ) )
248 QgsDebugMsg( QStringLiteral(
"Test font '%1 %2' already available" ).arg( fontFamily, fontstyle ) );
260 int fontID = QFontDatabase::addApplicationFont( fontPath );
261 loaded = ( fontID != -1 );
262 fontsLoaded = ( fontsLoaded || loaded );
263 QgsDebugMsg( QStringLiteral(
"Test font '%1 %2' %3 from filesystem [%4]" )
264 .arg( fontFamily, fontstyle, loaded ?
"loaded" :
"FAILED to load", fontPath ) );
266 QgsDebugMsg( QStringLiteral(
"font families in %1: %2" ).arg( fontID ).arg( db.applicationFontFamilies( fontID ).join(
"," ) ) );
270 QFile fontResource(
":/testdata/font/" + fontpath );
271 if ( fontResource.open( QIODevice::ReadOnly ) )
273 int fontID = QFontDatabase::addApplicationFontFromData( fontResource.readAll() );
274 loaded = ( fontID != -1 );
275 fontsLoaded = ( fontsLoaded || loaded );
277 QgsDebugMsg( QStringLiteral(
"Test font '%1' (%2) %3 from testdata.qrc" )
278 .arg( fontFamily, fontstyle, loaded ?
"loaded" :
"FAILED to load" ) );
293 QFontDatabase fontDB;
296 if ( !f.exactMatch() )
299 if ( style ==
"Roman" )
301 else if ( style ==
"Oblique" )
303 else if ( style ==
"Bold Oblique" )
304 modified =
"Bold Italic";
305 if ( !modified.isEmpty() )
308 if ( !f.exactMatch() )
311 QgsDebugMsg( QStringLiteral(
"Requested: %1" ).arg( f.toString() ) );
313 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() ) );
317 f.setBold( style.contains( QLatin1String(
"Bold" ) ) );
318 f.setItalic( style.contains( QLatin1String(
"Oblique" ) ) || style.contains( QLatin1String(
"Italic" ) ) );
325 QDomElement fontElem = document.createElement( elementName );
326 fontElem.setAttribute( QStringLiteral(
"description" ), font.toString() );
333 if ( element.isNull() )
338 font.fromString( element.attribute( QStringLiteral(
"description" ) ) );
339 if ( element.hasAttribute( QStringLiteral(
"style" ) ) )
349 if ( element.isNull() )
354 QDomNodeList nodeList = element.elementsByTagName( childNode );
355 if ( !nodeList.isEmpty() )
357 QDomElement fontElem = nodeList.at( 0 ).toElement();
368 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
370 QDomDocument fontDoc;
371 QDomElement fontElem =
toXmlElement( font, fontDoc, QStringLiteral(
"font" ) );
372 fontDoc.appendChild( fontElem );
373 mimeData->setText( fontDoc.toString() );
375 return mimeData.release();
387 QString text = data->text();
388 if ( !text.isEmpty() )
393 if ( doc.setContent( text ) )
395 elem = doc.documentElement();
397 if ( elem.nodeName() != QStringLiteral(
"font" ) )
398 elem = elem.firstChildElement( QStringLiteral(
"font" ) );
411 static QMap<QString, QString> createTranslatedStyleMap()
413 QMap<QString, QString> translatedStyleMap;
414 QStringList words = QStringList()
415 << QStringLiteral(
"Normal" )
416 << QStringLiteral(
"Regular" )
417 << QStringLiteral(
"Light" )
418 << QStringLiteral(
"Bold" )
419 << QStringLiteral(
"Black" )
420 << QStringLiteral(
"Demi" )
421 << QStringLiteral(
"Italic" )
422 << QStringLiteral(
"Oblique" );
423 Q_FOREACH (
const QString &word, words )
425 translatedStyleMap.insert( QCoreApplication::translate(
"QFontDatabase", qPrintable( word ) ), word );
427 return translatedStyleMap;
432 QStringList words = namedStyle.split(
' ', QString::SkipEmptyParts );
433 for (
int i = 0, n = words.length(); i < n; ++i )
435 words[i] = QCoreApplication::translate(
"QFontDatabase", words[i].toUtf8(),
nullptr, QCoreApplication::UnicodeUTF8 );
437 return words.join( QStringLiteral(
" " ) );
442 static QMap<QString, QString> translatedStyleMap = createTranslatedStyleMap();
443 QStringList words = namedStyle.split(
' ', QString::SkipEmptyParts );
444 for (
int i = 0, n = words.length(); i < n; ++i )
446 if ( translatedStyleMap.contains( words[i] ) )
448 words[i] = translatedStyleMap.value( words[i] );
452 QgsDebugMsg( QStringLiteral(
"Warning: style map does not contain %1" ).arg( words[i] ) );
455 return words.join( QStringLiteral(
" " ) );
460 QString css = QStringLiteral(
"font-family: " ) + font.family() +
';';
463 css += QLatin1String(
"font-style: " );
464 switch ( font.style() )
466 case QFont::StyleNormal:
467 css += QLatin1String(
"normal" );
469 case QFont::StyleItalic:
470 css += QLatin1String(
"italic" );
472 case QFont::StyleOblique:
473 css += QLatin1String(
"oblique" );
480 switch ( font.weight() )
488 case QFont::DemiBold:
500 case QFont::ExtraLight:
506 case QFont::ExtraBold:
510 css += QStringLiteral(
"font-weight: %1;" ).arg( cssWeight );
513 css += QStringLiteral(
"font-size: %1px;" ).arg( font.pointSizeF() >= 0 ? font.pointSizeF() * pointToPixelScale : font.pixelSize() );
520 if ( family.isEmpty() )
526 QStringList recentFamilies = settings.
value( QStringLiteral(
"fonts/recent" ) ).toStringList();
529 recentFamilies.removeAll( family );
532 recentFamilies.prepend( family );
535 recentFamilies = recentFamilies.mid( 0, 10 );
537 settings.
setValue( QStringLiteral(
"fonts/recent" ), recentFamilies );
543 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.