From 30ab9184ad452c892ddd02126ff52d7c7b5f5c38 Mon Sep 17 00:00:00 2001
From: Paul Olav Tvete <paul.tvete@theqtcompany.com>
Date: Tue, 16 Jun 2015 13:16:03 +0200
Subject: [PATCH] Only turn off font hinting when really scaling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We don't want to turn off font hinting based on whether auto-scaling is on,
otherwise Qt Creator will look bad on a low-DPI screen. Instead, we turn it
off only if we have at least one screen that is scaled.

QHighDpiScaling::isActive() now means that there is actual scaling going on.
There is currently no need for the old meaning, so this change does not include
QHighDpiScaling::isEnabled().

Note that nothing can save us from the case where there is one high-DPI and
one low-DPI screen.  In that case we choose looking bad on the low-DPI screen
instead of looking like crap on the high-DPI screen. Also note that our font
system we doesn't allow us to change our minds on hinting later when screens
are plugged in or removed.

Change-Id: I14a4ec7a49f4ba74a4c74684c7b951d0a71b951d
Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
---
 src/gui/kernel/qguiapplication.cpp            |  4 +-
 src/gui/kernel/qhighdpiscaling.cpp            | 47 ++++++++++++++-----
 src/gui/kernel/qhighdpiscaling_p.h            |  7 ++-
 .../fontconfig/qfontconfigdatabase.cpp        |  5 +-
 4 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 7866f65b7e5..448a71fe6b1 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1119,7 +1119,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
     QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
 
 
-    QHighDpiScaling::initHighDPiScaling();
+    QHighDpiScaling::initHighDpiScaling();
 
     // Load the platform integration
     QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
@@ -1183,6 +1183,8 @@ void QGuiApplicationPrivate::createPlatformIntegration()
 
     if (!icon.isEmpty())
         forcedWindowIcon = QDir::isAbsolutePath(icon) ? QIcon(icon) : QIcon::fromTheme(icon);
+
+    QHighDpiScaling::updateHighDpiScaling();
 }
 
 /*!
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 56fd38486d9..2fee06c77d6 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -124,23 +124,41 @@ static inline qreal initialScaleFactor()
 
 qreal QHighDpiScaling::m_factor;
 bool QHighDpiScaling::m_active; //"overall active" - is there any scale factor set.
-bool QHighDpiScaling::m_perScreenActive; // different screens may have different scale
 bool QHighDpiScaling::m_usePixelDensity; // use scale factor from platform plugin
+bool QHighDpiScaling::m_pixelDensityScalingActive; // pixel density scale factor > 1
+bool QHighDpiScaling::m_globalScalingActive; // global scale factor is active
+bool QHighDpiScaling::m_screenFactorSet; // QHighDpiScaling::setScreenFactor has been used
 
 /*
     Initializes the QHighDpiScaling global variables. Called before the
     platform plugin is created.
 */
-void QHighDpiScaling::initHighDPiScaling()
+void QHighDpiScaling::initHighDpiScaling()
 {
     m_factor = initialScaleFactor();
     bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet(autoScreenEnvVar)
                                          || qgetenv(legacyDevicePixelEnvVar).toLower() == "auto";
 
-    // m_active below is "overall active" - is there any scale factor set.
-    m_active = !qFuzzyCompare(m_factor, qreal(1)) || usePlatformPluginPixelDensity;
+    m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1));
     m_usePixelDensity = usePlatformPluginPixelDensity;
-    m_perScreenActive = m_usePixelDensity;
+    m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below
+
+    // we update m_active in updateHighDpiScaling, but while we create the
+    // screens, we have to assume that m_usePixelDensity implies scaling
+    m_active = m_globalScalingActive || m_usePixelDensity;
+}
+
+void QHighDpiScaling::updateHighDpiScaling()
+{
+    if (m_usePixelDensity && !m_pixelDensityScalingActive) {
+        Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
+            if (!qFuzzyCompare(screenSubfactor(screen->handle()), qreal(1))) {
+                m_pixelDensityScalingActive = true;
+                break;
+            }
+        }
+    }
+    m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
 }
 
 /*
@@ -148,14 +166,15 @@ void QHighDpiScaling::initHighDPiScaling()
 */
 void QHighDpiScaling::setGlobalFactor(qreal factor)
 {
-    if (qFuzzyCompare(factor, QHighDpiScaling::m_factor))
+    if (qFuzzyCompare(factor, m_factor))
         return;
     if (!QGuiApplication::allWindows().isEmpty()) {
         qWarning() << Q_FUNC_INFO << "QHighDpiScaling::setFactor: Should only be called when no windows exist.";
     }
 
-    QHighDpiScaling::m_active = !qFuzzyCompare(factor, qreal(1));
-    QHighDpiScaling::m_factor = QHighDpiScaling::m_active ? factor : qreal(1);
+    m_globalScalingActive = !qFuzzyCompare(factor, qreal(1));
+    m_factor = m_globalScalingActive ? factor : qreal(1);
+    m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
     Q_FOREACH (QScreen *screen, QGuiApplication::screens())
          screen->d_func()->updateHighDpi();
 }
@@ -167,8 +186,8 @@ static const char *scaleFactorProperty = "_q_scaleFactor";
 */
 void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
 {
+    m_screenFactorSet = true;
     m_active = true;
-    m_perScreenActive = true;
     screen->setProperty(scaleFactorProperty, QVariant(factor));
 
     //### dirty hack to force re-evaluation of screen geometry
@@ -215,12 +234,14 @@ QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatform
 qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
 {
     qreal factor = qreal(1.0);
-    if (m_perScreenActive && screen) {
+    if (screen) {
         if (m_usePixelDensity)
             factor *= screen->pixelDensity();
-        QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
-        if (screenFactor.isValid())
-            factor *= screenFactor.toReal();
+        if (m_screenFactorSet) {
+            QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
+            if (screenFactor.isValid())
+                factor *= screenFactor.toReal();
+        }
     }
     return factor;
 }
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index bf967d10ade..d60be865182 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -60,7 +60,8 @@ class QPlatformScreen;
 
 class Q_GUI_EXPORT QHighDpiScaling {
 public:
-    static void initHighDPiScaling();
+    static void initHighDpiScaling();
+    static void updateHighDpiScaling();
     static void setGlobalFactor(qreal factor);
     static void setScreenFactor(QScreen *window, qreal factor);
 
@@ -77,8 +78,10 @@ private:
 
     static qreal m_factor;
     static bool m_active;
-    static bool m_perScreenActive;
     static bool m_usePixelDensity;
+    static bool m_globalScalingActive;
+    static bool m_pixelDensityScalingActive;
+    static bool m_screenFactorSet;
 };
 
 // Coordinate system conversion functions:
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 112bb8e0a63..c40bbf41b18 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -33,6 +33,7 @@
 
 #include "qfontconfigdatabase_p.h"
 #include "qfontenginemultifontconfig_p.h"
+#include "qhighdpiscaling_p.h"
 
 #include <QtCore/QList>
 #include <QtCore/QElapsedTimer>
@@ -553,10 +554,8 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
         break;
     }
 
-    if (QGuiApplication::platformNativeInterface()->nativeResourceForScreen("nofonthinting",
-                         QGuiApplication::primaryScreen())) {
+    if (QHighDpiScaling::isActive())
         return QFontEngine::HintNone;
-    }
 
     int hint_style = 0;
     if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
-- 
GitLab