QHighDPI: Fix broken scaling of QPoint(F)

For some reason, the overload resolution of the
High DPI scale() functions introduced by
b6ded193ee chose the
wrong overloads for QPointF and/or QPoint; it fell
back to the generic template intended for qreal,
QSize, etc, ignoring the origin. Remove the
template and spell out all overloads.

Fixes: QTBUG-77255
Change-Id: I5661f16f7326f65156f646f430f5a0c71d5302d2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
bb10
Friedemann Kleint 2019-07-31 10:23:39 +02:00
parent 3d7bd7ad19
commit 174061f9f3
4 changed files with 103 additions and 3 deletions

View File

@ -59,6 +59,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtGui/qregion.h>
#include <QtGui/qscreen.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qwindow.h>
QT_BEGIN_NAMESPACE
@ -117,13 +118,26 @@ private:
namespace QHighDpi {
template <typename T>
inline T scale(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
inline qreal scale(qreal value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
{
Q_UNUSED(origin)
return value * scaleFactor;
}
inline QSize scale(const QSize &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
{
return value * scaleFactor;
}
inline QSizeF scale(const QSizeF &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
{
return value * scaleFactor;
}
inline QVector2D scale(const QVector2D &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
{
return value * float(scaleFactor);
}
inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
{
return (pos - origin) * scaleFactor + origin;

View File

@ -11,6 +11,7 @@ SUBDIRS=\
qguimetatype \
qguitimer \
qguivariant \
qhighdpiscaling \
qinputmethod \
qkeyevent \
qkeysequence \
@ -35,6 +36,8 @@ win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop
!qtHaveModule(network): SUBDIRS -= \
qguieventloop
!qtConfig(highdpiscaling): SUBDIRS -= qhighdpiscaling
!qtConfig(opengl): SUBDIRS -= qopenglwindow
android|uikit: SUBDIRS -= qclipboard

View File

@ -0,0 +1,6 @@
CONFIG += testcase
TARGET = tst_qhighdpiscaling
QT += core-private gui-private testlib
SOURCES += tst_qhighdpiscaling.cpp

View File

@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <private/qhighdpiscaling_p.h>
#include <qpa/qplatformscreen.h>
#include <QtTest/QtTest>
class tst_QHighDpiScaling: public QObject
{
Q_OBJECT
private slots:
void scale();
};
// Emulate the case of a High DPI secondary screen
class MyPlatformScreen : public QPlatformScreen
{
public:
QRect geometry() const override { return QRect(3840, 0, 3840, 1920); }
QRect availableGeometry() const override { return geometry(); }
int depth() const override { return 32; }
QImage::Format format() const override { return QImage::Format_ARGB32_Premultiplied; }
};
// QTBUG-77255: Test some scaling overloads
void tst_QHighDpiScaling::scale()
{
QHighDpiScaling::setGlobalFactor(2);
QScopedPointer<QPlatformScreen> screen(new MyPlatformScreen);
qreal nativeValue = 10;
const qreal value = QHighDpi::fromNativePixels(nativeValue, screen.data());
QCOMPARE(value, qreal(5));
QCOMPARE(QHighDpi::toNativePixels(value, screen.data()), nativeValue);
// 10, 10 within screen should translate to 5,5 with origin preserved
const QPoint nativePoint = screen->geometry().topLeft() + QPoint(10, 10);
const QPoint point = QHighDpi::fromNativePixels(nativePoint, screen.data());
QCOMPARE(point, QPoint(3845, 5));
QCOMPARE(QHighDpi::toNativePixels(point, screen.data()), nativePoint);
const QPointF nativePointF(nativePoint);
const QPointF pointF = QHighDpi::fromNativePixels(nativePointF, screen.data());
QCOMPARE(pointF, QPointF(3845, 5));
QCOMPARE(QHighDpi::toNativePixels(pointF, screen.data()), nativePointF);
}
#include "tst_qhighdpiscaling.moc"
QTEST_MAIN(tst_QHighDpiScaling);