From dfe5c6bd0de55476944132017eb48bbf0970d8e9 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Date: Thu, 27 Aug 2015 15:02:02 +0200
Subject: [PATCH] WIP: QFontPrivate: Remove dependency on qt_default_dpi().

- Make dpi a private value member initialized to -1.
- Add a static int default DPI which is initialized to
  primary screen or High DPI DPI.
- Add accessor for dpi that checks whether a specific DPI
  is set on the font and returns that or the default DPI.

TODO: Another solution fixing the init sequence has been
found, patch is kept for reference should the problem
show again.

Task-number: QTBUG-47947
Change-Id: If5b54482c4e052df31ef78b45bef50a58ecdb436
---
 src/gui/image/qpaintengine_pic.cpp      |  2 +-
 src/gui/kernel/qhighdpiscaling.cpp      |  2 ++
 src/gui/kernel/qplatformintegration.cpp |  3 +++
 src/gui/text/qfont.cpp                  | 26 +++++++++++++++++++-------
 src/gui/text/qfont_p.h                  | 11 ++++++++++-
 src/gui/text/qfontdatabase.cpp          |  8 ++++----
 src/gui/text/qfontmetrics.cpp           |  8 ++++----
 src/gui/text/qtextengine.cpp            |  4 ++--
 8 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index 47480eb..d07a05f 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -493,7 +493,7 @@ void QPicturePaintEngine::drawTextItem(const QPointF &p , const QTextItem &ti)
         if (si.justified)
             justificationWidth = si.width.toReal();
 
-        d->s << p << ti.text() << fnt << ti.renderFlags() << double(fnt.d->dpi)/qt_defaultDpi() << justificationWidth;
+        d->s << p << ti.text() << fnt << ti.renderFlags() << double(fnt.d->dpi())/qt_defaultDpi() << justificationWidth;
         writeCmdLength(pos, /*brect=*/QRectF(), /*corr=*/false);
     } else if (d->pic_d->formatMajor >= 8) {
         // old old (buggy) format
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index daba9f9..7b0d280 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -36,6 +36,7 @@
 #include "qscreen.h"
 #include "qplatformintegration.h"
 #include "private/qscreen_p.h"
+#include "private/qfont_p.h"
 
 #include <QtCore/qdebug.h>
 
@@ -205,6 +206,7 @@ void QHighDpiScaling::updateHighDpiScaling()
     qreal sf = screenSubfactor(primaryScreen);
     QDpi primaryDpi = primaryScreen->logicalDpi();
     m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf);
+    QFontPrivate::setDefaultDpi(m_logicalDpi.second);
 }
 
 /*
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 457a420..2e3595d 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -40,6 +40,7 @@
 #include <QtGui/private/qguiapplication_p.h>
 #include <QtGui/private/qpixmap_raster_p.h>
 #include <private/qdnd_p.h>
+#include <private/qfont_p.h>
 #include <private/qsimpledrag_p.h>
 
 #ifndef QT_NO_SESSIONMANAGER
@@ -455,6 +456,8 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
     } else {
         QGuiApplicationPrivate::screen_list.append(screen);
     }
+    if (QFontPrivate::defaultDpi() <= 0)
+        QFontPrivate::setDefaultDpi(ps->logicalDpi().second);
     emit qGuiApp->screenAdded(screen);
 
     if (isPrimary)
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 7d9d007..956c791 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -164,20 +164,22 @@ Q_GUI_EXPORT int qt_defaultDpi()
     return qt_defaultDpiY();
 }
 
+int QFontPrivate::m_defaultDpi = -1;
+
 QFontPrivate::QFontPrivate()
-    : engineData(0), dpi(qt_defaultDpi()), screen(0),
+    : engineData(0), screen(0),
       underline(false), overline(false), strikeOut(false), kerning(true),
-      capital(0), letterSpacingIsAbsolute(false), scFont(0)
+      capital(0), letterSpacingIsAbsolute(false), scFont(0), m_dpi(-1)
 {
 }
 
 QFontPrivate::QFontPrivate(const QFontPrivate &other)
-    : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
+    : request(other.request), engineData(0), screen(other.screen),
       underline(other.underline), overline(other.overline),
       strikeOut(other.strikeOut), kerning(other.kerning),
       capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
       letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing),
-      scFont(other.scFont)
+      scFont(other.scFont), m_dpi(other.m_dpi)
 {
     if (scFont && scFont != this)
         scFont->ref.ref();
@@ -193,6 +195,16 @@ QFontPrivate::~QFontPrivate()
     scFont = 0;
 }
 
+void QFontPrivate::setDefaultDpi(int d)
+{
+    if (QCoreApplication::testAttribute(Qt::AA_Use96Dpi))
+        QFontPrivate::m_defaultDpi = 96;
+    else if (!qt_is_gui_used)
+        QFontPrivate::m_defaultDpi = 75;
+    else
+        QFontPrivate::m_defaultDpi = d;
+}
+
 extern QMutex *qt_fontdatabase_mutex();
 
 #define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
@@ -248,7 +260,7 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
 {
     Q_ASSERT(other != 0);
 
-    dpi = other->dpi;
+    m_dpi = other->m_dpi;
 
     if ((mask & QFont::AllPropertiesResolved) == QFont::AllPropertiesResolved) return;
 
@@ -544,9 +556,9 @@ QFont::QFont(const QFont &font, QPaintDevice *pd)
     Q_ASSERT(pd != 0);
     int dpi = pd->logicalDpiY();
     const int screen = 0;
-    if (font.d->dpi != dpi || font.d->screen != screen ) {
+    if (font.d->dpi() != dpi || font.d->screen != screen ) {
         d = new QFontPrivate(*font.d);
-        d->dpi = dpi;
+        d->setDpi(dpi);
         d->screen = screen;
     } else {
         d = font.d.data();
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 25b5ef0..7267c31 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -172,7 +172,13 @@ public:
     QAtomicInt ref;
     QFontDef request;
     mutable QFontEngineData *engineData;
-    int dpi;
+
+    int dpi() const { return m_dpi > 0 ? m_dpi : QFontPrivate::m_defaultDpi; }
+    void setDpi(int d) { m_dpi = d; }
+
+    static int defaultDpi() { return QFontPrivate::m_defaultDpi; }
+    static void setDefaultDpi(int d);
+
     int screen;
 
     uint underline  :  1;
@@ -200,6 +206,9 @@ public:
 
 private:
     QFontPrivate &operator=(const QFontPrivate &) { return *this; }
+
+    static int m_defaultDpi;
+    int m_dpi;
 };
 
 
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 8090812..87eaacb 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2660,11 +2660,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
     QFontDef req = d->request;
 
     if (req.pixelSize == -1) {
-        req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
+        req.pixelSize = std::floor(((req.pointSize * d->dpi()) / 72) * 100 + 0.5) / 100;
         req.pixelSize = qRound(req.pixelSize);
     }
     if (req.pointSize < 0)
-        req.pointSize = req.pixelSize*72.0/d->dpi;
+        req.pointSize = req.pixelSize*72.0/d->dpi();
     if (req.weight == 0)
         req.weight = QFont::Normal;
     if (req.stretch == 0)
@@ -2726,8 +2726,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
                     delete fe;
                 fe = 0;
             } else {
-                if (d->dpi > 0)
-                    fe->fontDef.pointSize = qreal(double((fe->fontDef.pixelSize * 72) / d->dpi));
+                if (d->dpi() > 0)
+                    fe->fontDef.pointSize = qreal(double((fe->fontDef.pixelSize * 72) / d->dpi()));
             }
         }
 
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 5bc9fe3..6e32733 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -166,9 +166,9 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
 {
     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
     const int screen = 0;
-    if (font.d->dpi != dpi || font.d->screen != screen ) {
+    if (font.d->dpi() != dpi || font.d->screen != screen ) {
         d = new QFontPrivate(*font.d);
-        d->dpi = dpi;
+        d->setDpi(dpi);
         d->screen = screen;
     } else {
         d = font.d.data();
@@ -1055,9 +1055,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
 {
     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
     const int screen = 0;
-    if (font.d->dpi != dpi || font.d->screen != screen ) {
+    if (font.d->dpi() != dpi || font.d->screen != screen ) {
         d = new QFontPrivate(*font.d);
-        d->dpi = dpi;
+        d->setDpi(dpi);
         d->screen = screen;
     } else {
         d = font.d.data();
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 6b98c14..280c4eb 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1053,7 +1053,7 @@ void QTextEngine::shapeText(int item) const
         wordSpacing = font.d->wordSpacing;
 
         if (letterSpacingIsAbsolute && letterSpacing.value())
-            letterSpacing *= font.d->dpi / qt_defaultDpiY();
+            letterSpacing *= font.d->dpi() / qt_defaultDpiY();
     }
 
 #ifdef QT_ENABLE_HARFBUZZ_NG
@@ -2873,7 +2873,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
         if (pdev)
             dpiScale = QFixed::fromReal(pdev->logicalDpiY() / qreal(qt_defaultDpiY()));
     } else {
-        dpiScale = QFixed::fromReal(fnt.d->dpi / qreal(qt_defaultDpiY()));
+        dpiScale = QFixed::fromReal(fnt.d->dpi() / qreal(qt_defaultDpiY()));
     }
 
     QList<QTextOption::Tab> tabArray = option.tabs();
-- 
1.9.1

