summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Hartmetz <andreas.hartmetz@kdab.com>2016-01-14 00:15:37 +0100
committerJani Heikkinen <jani.heikkinen@theqtcompany.com>2016-02-05 09:05:10 +0000
commitd870ea28656a2155c39a1aabefa1c56871a017e4 (patch)
treef5c5d14fb4edf63ad0b8ae1844500cecd55d68e9
parentd444d21a517c45c0fda0bdf955cbda61e0088be6 (diff)
Rerender natively rendered text items when DPI scaling changes.
The whole purpose of native rendering is to optimize precisely for a given pixel grid. DPI scaling can change when either settings of the current screen are changed, or when the window is moved to a different screen. Details: - add an ItemDevicePixelRatioHasChanged item change event - detect DPI scaling changes by watching screen (identity) and screen config changes - when DPI scaling changes, recursively send an ItemDevicePixelRatioHasChanged signal to all items with content - when a natively renderet TextItem catches such an event, call updateLayout() which automatically picks up the new logical DPI Task-number: QTBUG-49019 Change-Id: I9f4f8d1a7f2c172ed26c276294ab143161c4a48b Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--src/quick/items/qquickitem.h3
-rw-r--r--src/quick/items/qquicktext.cpp19
-rw-r--r--src/quick/items/qquickwindow.cpp39
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h3
6 files changed, 68 insertions, 3 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 02685a7d78..2dc7a29a30 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2068,6 +2068,10 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
\value ItemRotationHasChanged The item's rotation has changed.
ItemChangeData::realValue contains the new rotation.
+
+ \value ItemDevicePixelRatioHasChanged The device pixel ratio of the screen
+ the item is on has changed. ItemChangedData::realValue contains the new
+ device pixel ratio.
*/
/*!
@@ -5952,6 +5956,8 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
break;
case QQuickItem::ItemAntialiasingHasChanged:
+ // fall through
+ case QQuickItem::ItemDevicePixelRatioHasChanged:
q->itemChange(change, data);
break;
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index d92910ce9c..bda6dd4da5 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -166,7 +166,8 @@ public:
ItemOpacityHasChanged, // value.realValue
ItemActiveFocusHasChanged, // value.boolValue
ItemRotationHasChanged, // value.realValue
- ItemAntialiasingHasChanged // value.boolValue
+ ItemAntialiasingHasChanged, // value.boolValue
+ ItemDevicePixelRatioHasChanged // value.realValue
};
union ItemChangeData {
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 3aec464958..aa8f04e55d 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1455,7 +1455,8 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickText);
Q_UNUSED(value);
- if (change == ItemAntialiasingHasChanged) {
+ switch (change) {
+ case ItemAntialiasingHasChanged:
if (!antialiasing())
d->font.setStyleStrategy(QFont::NoAntialias);
else
@@ -1463,6 +1464,22 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
d->implicitWidthValid = false;
d->implicitHeightValid = false;
d->updateLayout();
+ break;
+
+ case ItemDevicePixelRatioHasChanged:
+ if (d->renderType == NativeRendering) {
+ // Native rendering optimizes for a given pixel grid, so its results must not be scaled.
+ // Text layout code respects the current device pixel ratio automatically, we only need
+ // to rerun layout after the ratio changed.
+ // Changes of implicit size should be minimal; they are hard to avoid.
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
+ d->updateLayout();
+ }
+ break;
+
+ default:
+ break;
}
QQuickItem::itemChange(change, value);
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index b93aa06336..24bac168ea 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -285,10 +285,43 @@ void QQuickWindow::update()
QQuickRenderControlPrivate::get(d->renderControl)->update();
}
+static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio)
+{
+ if (item->flags() & QQuickItem::ItemHasContents) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio);
+ }
+
+ QList <QQuickItem *> items = item->childItems();
+ for (int i = 0; i < items.size(); ++i)
+ updatePixelRatioHelper(items.at(i), pixelRatio);
+}
+
+void QQuickWindow::physicalDpiChanged()
+{
+ Q_D(QQuickWindow);
+ const qreal newPixelRatio = screen()->devicePixelRatio();
+ if (qFuzzyCompare(newPixelRatio, d->devicePixelRatio))
+ return;
+ d->devicePixelRatio = newPixelRatio;
+ if (d->contentItem)
+ updatePixelRatioHelper(d->contentItem, newPixelRatio);
+}
+
void QQuickWindow::handleScreenChanged(QScreen *screen)
{
Q_D(QQuickWindow);
- Q_UNUSED(screen)
+ if (screen) {
+ physicalDpiChanged();
+ // When physical DPI changes on the same screen, either the resolution or the device pixel
+ // ratio changed. We must check what it is. Device pixel ratio does not have its own
+ // ...Changed() signal.
+ d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)),
+ this, SLOT(physicalDpiChanged()));
+ } else {
+ disconnect(d->physicalDpiChangedConnection);
+ }
+
d->forcePolish();
}
@@ -407,6 +440,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, touchMouseId(-1)
, touchMousePressTimestamp(0)
, dirtyItemList(0)
+ , devicePixelRatio(0)
, context(0)
, renderer(0)
, windowManager(0)
@@ -459,6 +493,9 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
Q_ASSERT(windowManager || renderControl);
+ if (QScreen *screen = q->screen())
+ devicePixelRatio = screen->devicePixelRatio();
+
QSGContext *sg;
if (renderControl) {
QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 9f8ad095cd..d4ffb100de 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -196,6 +196,7 @@ protected:
private Q_SLOTS:
void maybeUpdate();
void cleanupSceneGraph();
+ void physicalDpiChanged();
void handleScreenChanged(QScreen *screen);
void setTransientParent_helper(QQuickWindow *window);
void runJobsAfterSwap();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 623707140e..787958ef86 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -205,6 +205,9 @@ public:
QVector<QQuickItem *> itemsToPolish;
+ qreal devicePixelRatio;
+ QMetaObject::Connection physicalDpiChangedConnection;
+
void updateDirtyNodes();
void cleanupNodes();
void cleanupNodesOnShutdown();