Coverage Report

Created: 2025-07-23 08:13

/src/qtbase/src/gui/kernel/qhighdpiscaling_p.h
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the QtGui module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#ifndef QHIGHDPISCALING_P_H
41
#define QHIGHDPISCALING_P_H
42
43
//
44
//  W A R N I N G
45
//  -------------
46
//
47
// This file is not part of the Qt API.  It exists purely as an
48
// implementation detail.  This header file may change from version to
49
// version without notice, or even be removed.
50
//
51
// We mean it.
52
//
53
54
#include <QtGui/private/qtguiglobal_p.h>
55
#include <QtCore/qmargins.h>
56
#include <QtCore/qmath.h>
57
#include <QtCore/qrect.h>
58
#include <QtCore/qvector.h>
59
#include <QtCore/qloggingcategory.h>
60
#include <QtGui/qregion.h>
61
#include <QtGui/qscreen.h>
62
#include <QtGui/qvector2d.h>
63
#include <QtGui/qwindow.h>
64
65
QT_BEGIN_NAMESPACE
66
67
Q_DECLARE_LOGGING_CATEGORY(lcScaling);
68
69
class QScreen;
70
class QPlatformScreen;
71
typedef QPair<qreal, qreal> QDpi;
72
73
#ifndef QT_NO_HIGHDPISCALING
74
class Q_GUI_EXPORT QHighDpiScaling {
75
    Q_GADGET
76
public:
77
    enum class DpiAdjustmentPolicy {
78
        Unset,
79
        Enabled,
80
        Disabled,
81
        UpOnly
82
    };
83
    Q_ENUM(DpiAdjustmentPolicy)
84
85
    QHighDpiScaling() = delete;
86
    ~QHighDpiScaling() = delete;
87
    QHighDpiScaling(const QHighDpiScaling &) = delete;
88
    QHighDpiScaling &operator=(const QHighDpiScaling &) = delete;
89
    QHighDpiScaling(QHighDpiScaling &&) = delete;
90
    QHighDpiScaling &operator=(QHighDpiScaling &&) = delete;
91
92
    static void initHighDpiScaling();
93
    static void updateHighDpiScaling();
94
    static void setGlobalFactor(qreal factor);
95
    static void setScreenFactor(QScreen *screen, qreal factor);
96
97
0
    static bool isActive() { return m_active; }
98
99
    struct ScaleAndOrigin
100
    {
101
        qreal factor;
102
        QPoint origin;
103
    };
104
    static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr);
105
    static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr);
106
    static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr);
107
108
    template<typename C>
109
0
    static qreal factor(C *context, QPoint *nativePosition = nullptr) {
110
0
        return scaleAndOrigin(context, nativePosition).factor;
111
0
    }
Unexecuted instantiation: double QHighDpiScaling::factor<QScreen const>(QScreen const*, QPoint*)
Unexecuted instantiation: double QHighDpiScaling::factor<QWindow const>(QWindow const*, QPoint*)
Unexecuted instantiation: double QHighDpiScaling::factor<QPlatformScreen>(QPlatformScreen*, QPoint*)
Unexecuted instantiation: double QHighDpiScaling::factor<QScreen>(QScreen*, QPoint*)
Unexecuted instantiation: double QHighDpiScaling::factor<QPlatformScreen const>(QPlatformScreen const*, QPoint*)
Unexecuted instantiation: double QHighDpiScaling::factor<QWindow>(QWindow*, QPoint*)
112
113
    static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
114
    static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
115
    static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
116
    static QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
117
    static QDpi logicalDpi(const QScreen *screen);
118
119
private:
120
    static qreal rawScaleFactor(const QPlatformScreen *screen);
121
    static qreal roundScaleFactor(qreal rawFactor);
122
    static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
123
    static qreal screenSubfactor(const QPlatformScreen *screen);
124
125
    static qreal m_factor;
126
    static bool m_active;
127
    static bool m_usePixelDensity;
128
    static bool m_globalScalingActive;
129
    static bool m_pixelDensityScalingActive;
130
    static bool m_screenFactorSet;
131
    static QDpi m_logicalDpi;
132
};
133
134
// Coordinate system conversion functions:
135
// QHighDpi::fromNativePixels   : from physical(screen/backing) to logical pixels
136
// QHighDpi::toNativePixels              : from logical to physical pixels
137
138
namespace QHighDpi {
139
140
inline qreal scale(qreal value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
141
0
{
142
0
    return value * scaleFactor;
143
0
}
144
145
inline QSize scale(const QSize &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
146
0
{
147
0
    return value * scaleFactor;
148
0
}
149
150
inline QSizeF scale(const QSizeF &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
151
0
{
152
0
    return value * scaleFactor;
153
0
}
154
155
inline QVector2D scale(const QVector2D &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
156
0
{
157
0
    return value * float(scaleFactor);
158
0
}
159
160
inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
161
0
{
162
0
     return (pos - origin) * scaleFactor + origin;
163
0
}
164
165
inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
166
0
{
167
0
     return (pos - origin) * scaleFactor + origin;
168
0
}
169
170
inline QRect scale(const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
171
0
{
172
0
    return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
173
0
}
174
175
inline QRectF scale(const QRectF &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
176
0
{
177
0
    return QRectF(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
178
0
}
179
180
inline QMargins scale(const QMargins &margins, qreal scaleFactor, QPoint origin = QPoint(0, 0))
181
0
{
182
0
    Q_UNUSED(origin)
183
0
    return QMargins(qRound(qreal(margins.left()) * scaleFactor), qRound(qreal(margins.top()) * scaleFactor),
184
0
                    qRound(qreal(margins.right()) * scaleFactor), qRound(qreal(margins.bottom()) * scaleFactor));
185
0
}
186
187
template <typename T>
188
QVector<T> scale(const QVector<T> &vector, qreal scaleFactor, QPoint origin = QPoint(0, 0))
189
0
{
190
0
    if (!QHighDpiScaling::isActive())
191
0
        return vector;
192
193
0
    QVector<T> scaled;
194
0
    scaled.reserve(vector.size());
195
0
    for (const T &item : vector)
196
0
        scaled.append(scale(item, scaleFactor, origin));
197
0
    return scaled;
198
0
}
199
200
inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = QPoint(0, 0))
201
0
{
202
0
    if (!QHighDpiScaling::isActive())
203
0
        return region;
204
205
0
    QRegion scaled;
206
0
    for (const QRect &rect : region)
207
0
        scaled += scale(QRectF(rect), scaleFactor, origin).toRect();
208
0
    return scaled;
209
0
}
210
211
template <typename T>
212
0
inline QPoint position(T) { return QPoint(); }
Unexecuted instantiation: QPoint QHighDpi::position<QMargins>(QMargins)
Unexecuted instantiation: QPoint QHighDpi::position<QVector2D>(QVector2D)
Unexecuted instantiation: QPoint QHighDpi::position<QVector<QPointF> >(QVector<QPointF>)
213
0
inline QPoint position(QPoint point) { return point; }
214
0
inline QPoint position(QPointF point) { return point.toPoint(); }
215
0
inline QPoint position(QRect rect) { return rect.center(); }
216
0
inline QPoint position(QRectF rect) { return rect.center().toPoint(); }
217
218
template <typename T, typename C>
219
T fromNativePixels(const T &value, const C *context)
220
0
{
221
0
    QPoint nativePosition = position(value);
222
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context, &nativePosition);
223
0
    return scale(value, qreal(1) / so.factor, so.origin);
224
0
}
Unexecuted instantiation: QRect QHighDpi::fromNativePixels<QRect, QWindow>(QRect const&, QWindow const*)
Unexecuted instantiation: QMargins QHighDpi::fromNativePixels<QMargins, QWindow>(QMargins const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativePixels<QPoint, QWindow>(QPoint const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativePixels<QPoint, QScreen>(QPoint const&, QScreen const*)
Unexecuted instantiation: QPointF QHighDpi::fromNativePixels<QPointF, QWindow>(QPointF const&, QWindow const*)
Unexecuted instantiation: QVector2D QHighDpi::fromNativePixels<QVector2D, QWindow>(QVector2D const&, QWindow const*)
Unexecuted instantiation: QVector<QPointF> QHighDpi::fromNativePixels<QVector<QPointF>, QWindow>(QVector<QPointF> const&, QWindow const*)
Unexecuted instantiation: QRectF QHighDpi::fromNativePixels<QRectF, QWindow>(QRectF const&, QWindow const*)
225
226
template <typename T, typename C>
227
T toNativePixels(const T &value, const C *context)
228
0
{
229
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
230
0
    return scale(value, so.factor, so.origin);
231
0
}
Unexecuted instantiation: QPoint QHighDpi::toNativePixels<QPoint, QScreen>(QPoint const&, QScreen const*)
Unexecuted instantiation: QPointF QHighDpi::toNativePixels<QPointF, QScreen>(QPointF const&, QScreen const*)
Unexecuted instantiation: QRect QHighDpi::toNativePixels<QRect, QScreen>(QRect const&, QScreen const*)
Unexecuted instantiation: QRect QHighDpi::toNativePixels<QRect, QWindow>(QRect const&, QWindow const*)
Unexecuted instantiation: QSize QHighDpi::toNativePixels<QSize, QWindow>(QSize const&, QWindow const*)
Unexecuted instantiation: QRectF QHighDpi::toNativePixels<QRectF, QWindow>(QRectF const&, QWindow const*)
Unexecuted instantiation: QVector2D QHighDpi::toNativePixels<QVector2D, QWindow>(QVector2D const&, QWindow const*)
Unexecuted instantiation: QVector<QPointF> QHighDpi::toNativePixels<QVector<QPointF>, QWindow>(QVector<QPointF> const&, QWindow const*)
Unexecuted instantiation: double QHighDpi::toNativePixels<double, QWindow>(double const&, QWindow const*)
232
233
template <typename T, typename C>
234
T fromNativeLocalPosition(const T &value, const C *context)
235
0
{
236
0
    return scale(value, qreal(1) / QHighDpiScaling::factor(context));
237
0
}
Unexecuted instantiation: QRect QHighDpi::fromNativeLocalPosition<QRect, QWindow>(QRect const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativeLocalPosition<QPoint, QWindow>(QPoint const&, QWindow const*)
Unexecuted instantiation: QPointF QHighDpi::fromNativeLocalPosition<QPointF, QWindow>(QPointF const&, QWindow const*)
238
239
template <typename T, typename C>
240
T toNativeLocalPosition(const T &value, const C *context)
241
0
{
242
0
    return scale(value, QHighDpiScaling::factor(context));
243
0
}
Unexecuted instantiation: QRect QHighDpi::toNativeLocalPosition<QRect, QScreen>(QRect const&, QScreen const*)
Unexecuted instantiation: QPoint QHighDpi::toNativeLocalPosition<QPoint, QWindow>(QPoint const&, QWindow const*)
Unexecuted instantiation: QPointF QHighDpi::toNativeLocalPosition<QPointF, QWindow>(QPointF const&, QWindow const*)
244
245
template <typename T>
246
inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
247
0
{
248
0
    return scale(value, qreal(1) / scaleFactor, origin);
249
0
}
Unexecuted instantiation: QRect QHighDpi::fromNative<QRect>(QRect const&, double, QPoint)
Unexecuted instantiation: QSize QHighDpi::fromNative<QSize>(QSize const&, double, QPoint)
250
251
template <typename T>
252
inline T toNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
253
0
{
254
0
    return scale(value, scaleFactor, origin);
255
0
}
Unexecuted instantiation: QPoint QHighDpi::toNative<QPoint>(QPoint const&, double, QPoint)
Unexecuted instantiation: QSize QHighDpi::toNative<QSize>(QSize const&, double, QPoint)
256
257
inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
258
0
{
259
0
    return scale(rect, qreal(1) / QHighDpiScaling::factor(screen), screenOrigin);
260
0
}
261
262
inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
263
0
{
264
0
    return QRect(nativeScreenGeometry.topLeft(),
265
0
                 scale(nativeScreenGeometry.size(), qreal(1) / QHighDpiScaling::factor(screen)));
266
0
}
267
268
inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
269
0
{
270
0
    return scale(pixelRegion, qreal(1) / QHighDpiScaling::factor(window));
271
0
}
272
273
// When mapping expose events to Qt rects: round top/left towards the origin and
274
// bottom/right away from the origin, making sure that we cover the whole window.
275
inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
276
0
{
277
0
    if (!QHighDpiScaling::isActive())
278
0
        return pixelRegion;
279
280
0
    const qreal scaleFactor = QHighDpiScaling::factor(window);
281
0
    QRegion pointRegion;
282
0
    for (const QRectF rect: pixelRegion) {
283
0
        const QPointF topLeftP = rect.topLeft() / scaleFactor;
284
0
        const QSizeF sizeP = rect.size() / scaleFactor;
285
0
        pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())),
286
0
                             QPoint(qCeil(topLeftP.x() + sizeP.width()  - 1.0),
287
0
                                    qCeil(topLeftP.y() + sizeP.height() - 1.0)));
288
0
    }
289
0
    return pointRegion;
290
0
}
291
292
inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
293
0
{
294
0
    return scale(pointRegion, QHighDpiScaling::factor(window));
295
0
}
296
297
} // namespace QHighDpi
298
#else // QT_NO_HIGHDPISCALING
299
class Q_GUI_EXPORT QHighDpiScaling {
300
public:
301
    static inline void initHighDpiScaling() {}
302
    static inline void updateHighDpiScaling() {}
303
    static inline void setGlobalFactor(qreal) {}
304
    static inline void setScreenFactor(QScreen *, qreal) {}
305
306
    static inline bool isActive() { return false; }
307
    static inline qreal factor(const QWindow *) { return 1.0; }
308
    static inline qreal factor(const QScreen *) { return 1.0; }
309
    static inline qreal factor(const QPlatformScreen *) { return 1.0; }
310
    static inline QPoint origin(const QScreen *) { return QPoint(); }
311
    static inline QPoint origin(const QPlatformScreen *) { return QPoint(); }
312
    static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
313
    static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
314
    static inline QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window) { return pos; }
315
    static inline QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window) { return pos; }
316
    static inline QDpi logicalDpi(const QScreen *screen) { return QDpi(-1,-1); }
317
};
318
319
namespace QHighDpi {
320
    template <typename T> inline
321
    T toNative(const T &value, ...) { return value; }
322
    template <typename T> inline
323
    T fromNative(const T &value, ...) { return value; }
324
325
    template <typename T> inline
326
    T fromNativeLocalPosition(const T &value, ...) { return value; }
327
    template <typename T> inline
328
    T toNativeLocalPosition(const T &value, ...) { return value; }
329
330
    template <typename T> inline
331
    T fromNativeLocalRegion(const T &value, ...) { return value; }
332
    template <typename T> inline
333
    T fromNativeLocalExposedRegion(const T &value, ...) { return value; }
334
    template <typename T> inline
335
    T toNativeLocalRegion(const T &value, ...) { return value; }
336
337
    template <typename T> inline
338
    T fromNativeScreenGeometry(const T &value, ...) { return value; }
339
340
    template <typename T, typename U> inline
341
    T toNativePixels(const T &value, const U*) {return value;}
342
    template <typename T, typename U> inline
343
    T fromNativePixels(const T &value, const U*) {return value;}
344
}
345
#endif // QT_NO_HIGHDPISCALING
346
QT_END_NAMESPACE
347
348
#endif // QHIGHDPISCALING_P_H