Don't hardcode the default families in qfont_qpa.cpp
authorPierre Rossi <pierre.rossi@nokia.com>
Thu, 22 Mar 2012 16:12:32 +0000 (17:12 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 10 Apr 2012 10:49:34 +0000 (12:49 +0200)
Since different platforms come with different fonts, we should
probably leave it up to the platform to decide which family to use.

Change-Id: I18bb81c0ce87cc7e9ac7f3abaeae1b41c0ce8410
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
src/gui/text/qfont_qpa.cpp
src/gui/text/qfontdatabase.h
src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
src/plugins/platforms/windows/qwindowsfontdatabase.cpp
src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
tests/auto/gui/text/qfont/tst_qfont.cpp

index 6576f23..b73b030 100644 (file)
@@ -75,35 +75,12 @@ void QFont::setRawName(const QString &)
 
 QString QFont::defaultFamily() const
 {
-    QString familyName;
-    switch(d->request.styleHint) {
-        case QFont::SansSerif:
-            familyName = QString::fromLatin1("sans-serif");
-            break;
-        case QFont::Serif:
-            familyName = QString::fromLatin1("serif");
-            break;
-        case QFont::TypeWriter:
-        case QFont::Monospace:
-            familyName = QString::fromLatin1("monospace");
-            break;
-        case QFont::Cursive:
-            familyName = QString::fromLatin1("cursive");
-            break;
-        case QFont::Fantasy:
-            familyName = QString::fromLatin1("fantasy");
-            break;
-        case QFont::Decorative:
-            familyName = QString::fromLatin1("decorative");
-            break;
-        case QFont::System:
-        default:
-            familyName = QString();
-            break;
-    }
-
-    return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(familyName);
-
+    QPlatformFontDatabase *fontDB = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
+    const QStringList fallbacks = fontDB->fallbacksForFamily(QString(), QFont::StyleNormal
+                                      , QFont::StyleHint(d->request.styleHint), QUnicodeTables::Common);
+    if (!fallbacks.isEmpty())
+        return fallbacks.first();
+    return QString();
 }
 
 QString QFont::lastResortFamily() const
index b30f7da..f0830f2 100644 (file)
@@ -46,8 +46,6 @@
 #include <QtCore/qstring.h>
 #include <QtGui/qfont.h>
 
-class tst_QFont;
-
 QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
@@ -162,9 +160,6 @@ private:
     friend class QFontEngineMultiXLFD;
     friend class QFontEngineMultiQWS;
     friend class QFontEngineMultiQPA;
-#ifdef QT_BUILD_INTERNAL
-    friend class ::tst_QFont;
-#endif
 
     QFontDatabasePrivate *d;
 };
index bf05433..9ad9b96 100644 (file)
@@ -291,8 +291,15 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
         stylehint = "serif";
         break;
     case QFont::TypeWriter:
+    case QFont::Monospace:
         stylehint = "monospace";
         break;
+    case QFont::Cursive:
+        stylehint = "cursive";
+        break;
+    case QFont::Fantasy:
+        stylehint = "fantasy";
+        break;
     default:
         break;
     }
index c1c25dd..3fc40f4 100644 (file)
@@ -698,6 +698,32 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const
     QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
     if (!result.isEmpty())
         return result;
+
+    switch (styleHint) {
+        case QFont::Times:
+            result << QString::fromLatin1("Times New Roman");
+            break;
+        case QFont::Courier:
+            result << QString::fromLatin1("Courier New");
+            break;
+        case QFont::Monospace:
+            result << QString::fromLatin1("Courier New");
+            break;
+        case QFont::Cursive:
+            result << QString::fromLatin1("Comic Sans MS");
+            break;
+        case QFont::Fantasy:
+            result << QString::fromLatin1("Impact");
+            break;
+        case QFont::Decorative:
+            result << QString::fromLatin1("Old English");
+            break;
+        case QFont::Helvetica:
+        case QFont::System:
+        default:
+            result << QString::fromLatin1("Arial");
+    }
+
     if (QWindowsContext::verboseFonts)
         qDebug() << __FUNCTION__ << family << style << styleHint
                  << script << result << m_families.size();
index e84f0c7..246b5b3 100644 (file)
@@ -422,6 +422,31 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString family, con
     QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
     if (!result.isEmpty())
         return result;
+
+    switch (styleHint) {
+        case QFont::Times:
+            result << QString::fromLatin1("Times New Roman");
+            break;
+        case QFont::Courier:
+            result << QString::fromLatin1("Courier New");
+            break;
+        case QFont::Monospace:
+            result << QString::fromLatin1("Courier New");
+            break;
+        case QFont::Cursive:
+            result << QString::fromLatin1("Comic Sans MS");
+            break;
+        case QFont::Fantasy:
+            result << QString::fromLatin1("Impact");
+            break;
+        case QFont::Decorative:
+            result << QString::fromLatin1("Old English");
+            break;
+        case QFont::Helvetica:
+        case QFont::System:
+        default:
+            result << QString::fromLatin1("Arial");
+    }
     if (QWindowsContext::verboseFonts)
         qDebug() << __FUNCTION__ << family << style << styleHint
                  << script << result << m_families;
index 1cedfa5..ea26b92 100644 (file)
@@ -75,10 +75,8 @@ private slots:
     void serializeSpacing();
     void lastResortFont();
     void styleName();
-#ifdef QT_BUILD_INTERNAL
     void defaultFamily_data();
     void defaultFamily();
-#endif
 };
 
 // Testing get/set functions
@@ -623,36 +621,62 @@ void tst_QFont::styleName()
 #endif
 }
 
-#ifdef QT_BUILD_INTERNAL
+QString getPlatformGenericFont(const char* genericName)
+{
+#if defined(Q_OS_UNIX) && !defined(QT_NO_FONTCONFIG)
+    QProcess p;
+    p.start(QLatin1String("fc-match"), (QStringList() << "-f%{family}" << genericName));
+    if (!p.waitForStarted())
+        qWarning("fc-match cannot be started: %s", qPrintable(p.errorString()));
+    if (p.waitForFinished())
+        return QString::fromLatin1(p.readAllStandardOutput());
+#endif
+    return QLatin1String(genericName);
+}
+
+static inline QByteArray msgNotAcceptableFont(const QString &defaultFamily, const QStringList &acceptableFamilies)
+{
+    QString res = QString::fromLatin1("Font family '%1' is not one of the following accaptable results: ").arg(defaultFamily);
+    Q_FOREACH (const QString &family, acceptableFamilies)
+        res += QString::fromLatin1("\n %1").arg(family);
+    return res.toLocal8Bit();
+}
+
 Q_DECLARE_METATYPE(QFont::StyleHint)
 void tst_QFont::defaultFamily_data()
 {
     QTest::addColumn<QFont::StyleHint>("styleHint");
-    QTest::addColumn<QString>("defaultFamily");
-
-    QTest::newRow("serif") << QFont::Times << "serif";
-    QTest::newRow("monospace") << QFont::Monospace << "monospace";
-    QTest::newRow("sans-serif") << QFont::SansSerif << "sans-serif";
-    QTest::newRow("cursive") << QFont::Cursive << "cursive";
-    QTest::newRow("fantasy") << QFont::Fantasy << "fantasy";
-    QTest::newRow("old english") << QFont::OldEnglish << "Old English";
+    QTest::addColumn<QStringList>("acceptableFamilies");
+
+    QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << getPlatformGenericFont("serif"));
+    QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << getPlatformGenericFont("monospace"));
+    QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << getPlatformGenericFont("cursive"));
+    QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino"  << getPlatformGenericFont("fantasy"));
+    QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << getPlatformGenericFont("sans-serif"));
 }
 
 void tst_QFont::defaultFamily()
 {
     QFETCH(QFont::StyleHint, styleHint);
-    QFETCH(QString, defaultFamily);
-
-    QFontDatabase db;
-    if (!db.hasFamily(defaultFamily))
-        QSKIP("Font family is not available on the system");
+    QFETCH(QStringList, acceptableFamilies);
 
     QFont f;
+    QFontDatabase db;
     f.setStyleHint(styleHint);
-    QCOMPARE(QFontDatabase::resolveFontFamilyAlias(f.defaultFamily()), QFontDatabase::resolveFontFamilyAlias(defaultFamily));
+    const QString familyForHint(f.defaultFamily());
 
+    // it should at least return a family that is available.
+    QVERIFY(db.hasFamily(familyForHint));
+
+    bool isAcceptable = false;
+    Q_FOREACH (const QString& family, acceptableFamilies) {
+        if (!familyForHint.compare(family, Qt::CaseInsensitive)) {
+            isAcceptable = true;
+            break;
+        }
+    }
+    QVERIFY2(isAcceptable, msgNotAcceptableFont(familyForHint, acceptableFamilies));
 }
-#endif // QT_BUILD_INTERNAL
 
 QTEST_MAIN(tst_QFont)
 #include "tst_qfont.moc"