Coverage Report

Created: 2026-06-07 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qhighdpiscaling_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#ifndef QHIGHDPISCALING_P_H
6
#define QHIGHDPISCALING_P_H
7
8
//
9
//  W A R N I N G
10
//  -------------
11
//
12
// This file is not part of the Qt API.  It exists purely as an
13
// implementation detail.  This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#include <QtGui/private/qtguiglobal_p.h>
20
#include <QtCore/qlist.h>
21
#include <QtCore/qloggingcategory.h>
22
#include <QtCore/qmargins.h>
23
#include <QtCore/qmath.h>
24
#include <QtCore/qrect.h>
25
#include <QtGui/qregion.h>
26
#include <QtGui/qscreen.h>
27
#include <QtGui/qvector2d.h>
28
#include <QtGui/qwindow.h>
29
30
QT_BEGIN_NAMESPACE
31
32
Q_DECLARE_LOGGING_CATEGORY(lcHighDpi);
33
34
class QScreen;
35
class QPlatformScreen;
36
typedef std::pair<qreal, qreal> QDpi;
37
38
#ifndef QT_NO_HIGHDPISCALING
39
class Q_GUI_EXPORT QHighDpiScaling {
40
    Q_GADGET
41
public:
42
    enum class DpiAdjustmentPolicy {
43
        Unset,
44
        Enabled,
45
        Disabled,
46
        UpOnly
47
    };
48
0
    Q_ENUM(DpiAdjustmentPolicy)
Unexecuted instantiation: qt_getEnumMetaObject(QHighDpiScaling::DpiAdjustmentPolicy)
Unexecuted instantiation: qt_getEnumName(QHighDpiScaling::DpiAdjustmentPolicy)
49
0
50
0
    QHighDpiScaling() = delete;
51
0
    ~QHighDpiScaling() = delete;
52
0
    QHighDpiScaling(const QHighDpiScaling &) = delete;
53
0
    QHighDpiScaling &operator=(const QHighDpiScaling &) = delete;
54
0
    QHighDpiScaling(QHighDpiScaling &&) = delete;
55
0
    QHighDpiScaling &operator=(QHighDpiScaling &&) = delete;
56
0
57
0
    static void initHighDpiScaling();
58
0
    static void updateHighDpiScaling();
59
0
    static void setGlobalFactor(qreal factor);
60
0
    static void setScreenFactor(QScreen *screen, qreal factor);
61
0
62
0
    static bool isActive() { return m_active; }
63
64
    struct Point {
65
        enum Kind {
66
            Invalid,
67
            DeviceIndependent,
68
            Native
69
        };
70
        Kind kind;
71
        QPoint point;
72
    };
73
74
    struct ScaleAndOrigin
75
    {
76
        qreal factor;
77
        QPoint origin;
78
    };
79
80
    static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
81
    static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, Point position = Point{ Point::Invalid, QPoint() });
82
    static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
83
84
    template<typename C>
85
0
    static qreal factor(C *context) {
86
0
        return scaleAndOrigin(context).factor;
87
0
    }
Unexecuted instantiation: double QHighDpiScaling::factor<QScreen const>(QScreen const*)
Unexecuted instantiation: double QHighDpiScaling::factor<QWindow const>(QWindow const*)
Unexecuted instantiation: double QHighDpiScaling::factor<QPlatformScreen const>(QPlatformScreen const*)
Unexecuted instantiation: double QHighDpiScaling::factor<QPlatformScreen>(QPlatformScreen*)
Unexecuted instantiation: double QHighDpiScaling::factor<QScreen>(QScreen*)
Unexecuted instantiation: double QHighDpiScaling::factor<QWindow>(QWindow*)
88
89
    static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
90
    static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
91
    static QDpi logicalDpi(const QScreen *screen);
92
    static qreal roundScaleFactor(qreal rawFactor);
93
94
private:
95
    struct ScreenFactor {
96
        ScreenFactor(QString name, qreal factor)
97
0
            :name(name), factor(factor) { }
98
        QString name;
99
        qreal factor;
100
    };
101
102
    static qreal rawScaleFactor(const QPlatformScreen *screen);
103
    static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
104
    static qreal screenSubfactor(const QPlatformScreen *screen);
105
    static QScreen *screenForPosition(Point position, QScreen *guess);
106
    static QList<QHighDpiScaling::ScreenFactor> parseScreenScaleFactorsSpec(QStringView screenScaleFactors);
107
108
    static qreal m_factor;
109
    static bool m_active;
110
    static bool m_usePlatformPluginDpi;
111
    static bool m_platformPluginDpiScalingActive;
112
    static bool m_globalScalingActive;
113
    static bool m_screenFactorSet;
114
    static bool m_usePhysicalDpi;
115
    static QVector<ScreenFactor> m_screenFactors;
116
    static DpiAdjustmentPolicy m_dpiAdjustmentPolicy;
117
    static QHash<QString, qreal> m_namedScreenScaleFactors;
118
119
#ifndef QT_NO_DEBUG_STREAM
120
    friend Q_GUI_EXPORT QDebug operator<<(QDebug, const ScreenFactor &);
121
#endif
122
};
123
124
namespace QHighDpi {
125
126
inline qreal scale(qreal value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
127
0
{
128
0
    return value * scaleFactor;
129
0
}
130
131
inline QSize scale(const QSize &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
132
0
{
133
0
    return value * scaleFactor;
134
0
}
135
136
inline QSizeF scale(const QSizeF &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
137
0
{
138
0
    return value * scaleFactor;
139
0
}
140
141
inline QVector2D scale(const QVector2D &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
142
0
{
143
0
    return value * float(scaleFactor);
144
0
}
145
146
inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
147
0
{
148
0
     return (pos - origin) * scaleFactor + origin;
149
0
}
150
151
inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
152
0
{
153
0
     return (pos - origin) * scaleFactor + origin;
154
0
}
155
156
inline QRect scale(const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
157
0
{
158
0
    return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
159
0
}
160
161
inline QRectF scale(const QRectF &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
162
0
{
163
0
    return QRectF(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
164
0
}
165
166
inline QMargins scale(const QMargins &margins, qreal scaleFactor, QPoint origin = QPoint(0, 0))
167
0
{
168
0
    Q_UNUSED(origin);
169
0
    return QMargins(qRound(qreal(margins.left()) * scaleFactor), qRound(qreal(margins.top()) * scaleFactor),
170
0
                    qRound(qreal(margins.right()) * scaleFactor), qRound(qreal(margins.bottom()) * scaleFactor));
171
0
}
172
173
template<typename T>
174
QList<T> scale(const QList<T> &list, qreal scaleFactor, QPoint origin = QPoint(0, 0))
175
{
176
    if (qFuzzyCompare(scaleFactor, qreal(1)))
177
        return list;
178
179
    QList<T> scaled;
180
    scaled.reserve(list.size());
181
    for (const T &item : list)
182
        scaled.append(scale(item, scaleFactor, origin));
183
    return scaled;
184
}
185
186
inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = QPoint(0, 0))
187
0
{
188
0
    if (qFuzzyCompare(scaleFactor, qreal(1)))
189
0
        return region;
190
191
0
    QRegion scaled = region.translated(-origin);
192
0
    scaled = QTransform::fromScale(scaleFactor, scaleFactor).map(scaled);
193
0
    return scaled.translated(origin);
194
0
}
195
196
template <typename T>
197
inline QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind) {
198
    return QHighDpiScaling::Point{ QHighDpiScaling::Point::Invalid, QPoint() };
199
}
200
0
inline QHighDpiScaling::Point position(QPoint point, QHighDpiScaling::Point::Kind kind) {
201
0
    return QHighDpiScaling::Point{ kind, point };
202
0
}
203
0
inline QHighDpiScaling::Point position(QPointF point, QHighDpiScaling::Point::Kind kind) {
204
0
    return QHighDpiScaling::Point{ kind, point.toPoint() };
205
0
}
206
0
inline QHighDpiScaling::Point position(QRect rect, QHighDpiScaling::Point::Kind kind) {
207
0
    return QHighDpiScaling::Point{ kind, rect.topLeft() };
208
0
}
209
0
inline QHighDpiScaling::Point position(QRectF rect, QHighDpiScaling::Point::Kind kind) {
210
0
    return QHighDpiScaling::Point{ kind, rect.topLeft().toPoint() };
211
0
}
212
213
template <typename T, typename C>
214
T fromNativePixels(const T &value, const C *context)
215
0
{
216
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
217
0
    return scale(value, qreal(1) / so.factor, so.origin);
218
0
}
Unexecuted instantiation: QPointF QHighDpi::fromNativePixels<QPointF, QWindow>(QPointF const&, QWindow const*)
Unexecuted instantiation: QRect QHighDpi::fromNativePixels<QRect, QWindow>(QRect const&, QWindow const*)
Unexecuted instantiation: QMargins QHighDpi::fromNativePixels<QMargins, QWindow>(QMargins const&, QWindow const*)
Unexecuted instantiation: QSizeF QHighDpi::fromNativePixels<QSizeF, QWindow>(QSizeF const&, QWindow const*)
Unexecuted instantiation: QVector2D QHighDpi::fromNativePixels<QVector2D, QWindow>(QVector2D const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativePixels<QPoint, QScreen>(QPoint const&, QScreen const*)
219
220
template <typename T, typename C>
221
T toNativePixels(const T &value, const C *context)
222
0
{
223
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
224
0
    return scale(value, so.factor, so.origin);
225
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: QRectF QHighDpi::toNativePixels<QRectF, QWindow>(QRectF const&, QWindow const*)
Unexecuted instantiation: QRect QHighDpi::toNativePixels<QRect, QWindow>(QRect const&, QWindow const*)
Unexecuted instantiation: QVector2D QHighDpi::toNativePixels<QVector2D, QWindow>(QVector2D const&, QWindow const*)
Unexecuted instantiation: QRect QHighDpi::toNativePixels<QRect, QScreen>(QRect const&, QScreen const*)
Unexecuted instantiation: QSize QHighDpi::toNativePixels<QSize, QWindow>(QSize const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::toNativePixels<QPoint, QWindow>(QPoint const&, QWindow const*)
226
227
template <typename T, typename C>
228
T fromNativeLocalPosition(const T &value, const C *context)
229
0
{
230
0
    return scale(value, qreal(1) / QHighDpiScaling::factor(context));
231
0
}
Unexecuted instantiation: QPointF QHighDpi::fromNativeLocalPosition<QPointF, QWindow>(QPointF const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativeLocalPosition<QPoint, QWindow>(QPoint const&, QWindow const*)
232
233
template <typename T, typename C>
234
T toNativeLocalPosition(const T &value, const C *context)
235
0
{
236
0
    return scale(value, QHighDpiScaling::factor(context));
237
0
}
238
239
template <typename T, typename C>
240
T fromNativeGlobalPosition(const T &value, const C *context)
241
0
{
242
0
    QHighDpiScaling::ScaleAndOrigin so =
243
0
        QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::Native));
244
0
    return scale(value, qreal(1) / so.factor, so.origin);
245
0
}
246
247
template <typename T, typename C>
248
T toNativeGlobalPosition(const T &value, const C *context)
249
0
{
250
0
    QHighDpiScaling::ScaleAndOrigin so =
251
0
        QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::DeviceIndependent));
252
0
    return scale(value, so.factor, so.origin);
253
0
}
254
255
template <typename T>
256
T fromNativeWindowGeometry(const T &value, const QWindow *context)
257
0
{
258
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
259
0
    QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
260
0
    return scale(value, qreal(1) / so.factor, effectiveOrigin);
261
0
}
Unexecuted instantiation: QRect QHighDpi::fromNativeWindowGeometry<QRect>(QRect const&, QWindow const*)
Unexecuted instantiation: QPoint QHighDpi::fromNativeWindowGeometry<QPoint>(QPoint const&, QWindow const*)
Unexecuted instantiation: QRectF QHighDpi::fromNativeWindowGeometry<QRectF>(QRectF const&, QWindow const*)
262
263
template <typename T>
264
T toNativeWindowGeometry(const T &value, const QWindow *context)
265
0
{
266
0
    QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
267
0
    QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
268
0
    return scale(value, so.factor, effectiveOrigin);
269
0
}
Unexecuted instantiation: QRect QHighDpi::toNativeWindowGeometry<QRect>(QRect const&, QWindow const*)
Unexecuted instantiation: QRectF QHighDpi::toNativeWindowGeometry<QRectF>(QRectF const&, QWindow const*)
270
271
template <typename T>
272
inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
273
0
{
274
0
    return scale(value, qreal(1) / scaleFactor, origin);
275
0
}
276
277
template <typename T>
278
inline T toNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
279
0
{
280
0
    return scale(value, scaleFactor, origin);
281
0
}
Unexecuted instantiation: QPoint QHighDpi::toNative<QPoint>(QPoint const&, double, QPoint)
Unexecuted instantiation: QSize QHighDpi::toNative<QSize>(QSize const&, double, QPoint)
282
283
inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
284
0
{
285
0
    return scale(rect, qreal(1) / QHighDpiScaling::factor(screen), screenOrigin);
286
0
}
287
288
inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
289
0
{
290
0
    return QRect(nativeScreenGeometry.topLeft(),
291
0
                 scale(nativeScreenGeometry.size(), qreal(1) / QHighDpiScaling::factor(screen)));
292
0
}
293
294
inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
295
0
{
296
0
    return scale(pixelRegion, qreal(1) / QHighDpiScaling::factor(window));
297
0
}
298
299
// When mapping expose events to Qt rects: round top/left towards the origin and
300
// bottom/right away from the origin, making sure that we cover the whole window.
301
inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
302
0
{
303
0
    if (!QHighDpiScaling::isActive())
304
0
        return pixelRegion;
305
306
0
    const qreal scaleFactor = QHighDpiScaling::factor(window);
307
0
    QRegion pointRegion;
308
0
    for (const QRectF rect: pixelRegion)
309
0
        pointRegion += QRectF(rect.topLeft() / scaleFactor, rect.size() / scaleFactor).toAlignedRect();
310
311
0
    return pointRegion;
312
0
}
313
314
inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
315
0
{
316
0
    return scale(pointRegion, QHighDpiScaling::factor(window));
317
0
}
318
319
} // namespace QHighDpi
320
#else // QT_NO_HIGHDPISCALING
321
class Q_GUI_EXPORT QHighDpiScaling {
322
public:
323
    static inline void initHighDpiScaling() {}
324
    static inline void updateHighDpiScaling() {}
325
    static inline void setGlobalFactor(qreal) {}
326
    static inline void setScreenFactor(QScreen *, qreal) {}
327
328
    struct ScaleAndOrigin
329
    {
330
        qreal factor;
331
        QPoint origin;
332
    };
333
    static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr);
334
    static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr);
335
    static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr);
336
337
    static inline bool isActive() { return false; }
338
    static inline qreal factor(const QWindow *) { return 1.0; }
339
    static inline qreal factor(const QScreen *) { return 1.0; }
340
    static inline qreal factor(const QPlatformScreen *) { return 1.0; }
341
    static inline QPoint origin(const QScreen *) { return QPoint(); }
342
    static inline QPoint origin(const QPlatformScreen *) { return QPoint(); }
343
    static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
344
    static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; }
345
    static inline QPointF mapPositionToGlobal(const QPointF &pos, const QPoint &, const QWindow *) { return pos; }
346
    static inline QPointF mapPositionFromGlobal(const QPointF &pos, const QPoint &, const QWindow *) { return pos; }
347
    static inline QDpi logicalDpi(const QScreen *) { return QDpi(-1,-1); }
348
    static inline qreal roundScaleFactor(qreal) { return 1.0; }
349
};
350
351
namespace QHighDpi {
352
    template <typename T> inline
353
    T scale(const T &value, ...) { return value; }
354
355
    template <typename T> inline
356
    T toNative(const T &value, ...) { return value; }
357
    template <typename T> inline
358
    T fromNative(const T &value, ...) { return value; }
359
360
    template <typename T> inline
361
    T fromNativeLocalPosition(const T &value, ...) { return value; }
362
    template <typename T> inline
363
    T toNativeLocalPosition(const T &value, ...) { return value; }
364
    template <typename T, typename C> inline
365
    T fromNativeGlobalPosition(const T &value, const C *) { return value; }
366
    template <typename T, typename C> inline
367
    T toNativeGlobalPosition(const T &value, const C *) { return value; }
368
    template <typename T, typename C> inline
369
    T fromNativeWindowGeometry(const T &value, const C *) { return value; }
370
    template <typename T, typename C> inline
371
    T toNativeWindowGeometry(const T &value, const C *) { return value; }
372
373
    template <typename T> inline
374
    T fromNativeLocalRegion(const T &value, ...) { return value; }
375
    template <typename T> inline
376
    T fromNativeLocalExposedRegion(const T &value, ...) { return value; }
377
    template <typename T> inline
378
    T toNativeLocalRegion(const T &value, ...) { return value; }
379
380
    template <typename T> inline
381
    T fromNativeScreenGeometry(const T &value, ...) { return value; }
382
383
    template <typename T, typename U> inline
384
    T toNativePixels(const T &value, const U*) {return value;}
385
    template <typename T, typename U> inline
386
    T fromNativePixels(const T &value, const U*) {return value;}
387
}
388
#endif // QT_NO_HIGHDPISCALING
389
QT_END_NAMESPACE
390
391
#endif // QHIGHDPISCALING_P_H