Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhighdpiscaling_p.h
Go to the documentation of this file.
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
31
33
34class QScreen;
35class QPlatformScreen;
36typedef std::pair<qreal, qreal> QDpi;
37
38#ifndef QT_NO_HIGHDPISCALING
39class Q_GUI_EXPORT QHighDpiScaling {
40 Q_GADGET
41public:
42 enum class DpiAdjustmentPolicy {
43 Unset,
44 Enabled,
45 Disabled,
46 UpOnly
47 };
48 Q_ENUM(DpiAdjustmentPolicy)
49
50 QHighDpiScaling() = delete;
51 ~QHighDpiScaling() = delete;
52 QHighDpiScaling(const QHighDpiScaling &) = delete;
53 QHighDpiScaling &operator=(const QHighDpiScaling &) = delete;
54 QHighDpiScaling(QHighDpiScaling &&) = delete;
55 QHighDpiScaling &operator=(QHighDpiScaling &&) = delete;
56
57 static void initHighDpiScaling();
58 static void updateHighDpiScaling();
59 static void setGlobalFactor(qreal factor);
60 static void setScreenFactor(QScreen *screen, qreal factor);
61
62 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 static qreal factor(C *context) {
86 return scaleAndOrigin(context).factor;
87 }
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
94private:
95 struct ScreenFactor {
96 ScreenFactor(QString name, qreal factor)
97 :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
124namespace QHighDpi {
125
126inline qreal scale(qreal value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
127{
128 return value * scaleFactor;
129}
130
131inline QSize scale(const QSize &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
132{
133 return value * scaleFactor;
134}
135
136inline QSizeF scale(const QSizeF &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
137{
138 return value * scaleFactor;
139}
140
141inline QVector2D scale(const QVector2D &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
142{
143 return value * float(scaleFactor);
144}
145
146inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
147{
148 return (pos - origin) * scaleFactor + origin;
149}
150
151inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
152{
153 return (pos - origin) * scaleFactor + origin;
154}
155
156inline QRect scale(const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
157{
158 return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
159}
160
161inline QRectF scale(const QRectF &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
162{
163 return QRectF(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
164}
165
166inline QMargins scale(const QMargins &margins, qreal scaleFactor, QPoint origin = QPoint(0, 0))
167{
168 Q_UNUSED(origin);
169 return QMargins(qRound(qreal(margins.left()) * scaleFactor), qRound(qreal(margins.top()) * scaleFactor),
170 qRound(qreal(margins.right()) * scaleFactor), qRound(qreal(margins.bottom()) * scaleFactor));
171}
172
173template<typename T>
174QList<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
186inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = QPoint(0, 0))
187{
188 if (qFuzzyCompare(scaleFactor, qreal(1)))
189 return region;
190
191 QRegion scaled = region.translated(-origin);
192 scaled = QTransform::fromScale(scaleFactor, scaleFactor).map(scaled);
193 return scaled.translated(origin);
194}
195
196template <typename T>
198 return QHighDpiScaling::Point{ QHighDpiScaling::Point::Invalid, QPoint() };
199}
200inline QHighDpiScaling::Point position(QPoint point, QHighDpiScaling::Point::Kind kind) {
201 return QHighDpiScaling::Point{ kind, point };
202}
203inline QHighDpiScaling::Point position(QPointF point, QHighDpiScaling::Point::Kind kind) {
204 return QHighDpiScaling::Point{ kind, point.toPoint() };
205}
206inline QHighDpiScaling::Point position(QRect rect, QHighDpiScaling::Point::Kind kind) {
207 return QHighDpiScaling::Point{ kind, rect.topLeft() };
208}
209inline QHighDpiScaling::Point position(QRectF rect, QHighDpiScaling::Point::Kind kind) {
210 return QHighDpiScaling::Point{ kind, rect.topLeft().toPoint() };
211}
212
213template <typename T, typename C>
214T fromNativePixels(const T &value, const C *context)
215{
216 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
217 return scale(value, qreal(1) / so.factor, so.origin);
218}
219
220template <typename T, typename C>
221T toNativePixels(const T &value, const C *context)
222{
223 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
224 return scale(value, so.factor, so.origin);
225}
226
227template <typename T, typename C>
228T fromNativeLocalPosition(const T &value, const C *context)
229{
230 return scale(value, qreal(1) / QHighDpiScaling::factor(context));
231}
232
233template <typename T, typename C>
234T toNativeLocalPosition(const T &value, const C *context)
235{
236 return scale(value, QHighDpiScaling::factor(context));
237}
238
239template <typename T, typename C>
240T fromNativeGlobalPosition(const T &value, const C *context)
241{
242 QHighDpiScaling::ScaleAndOrigin so =
243 QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::Native));
244 return scale(value, qreal(1) / so.factor, so.origin);
245}
246
247template <typename T, typename C>
248T toNativeGlobalPosition(const T &value, const C *context)
249{
250 QHighDpiScaling::ScaleAndOrigin so =
251 QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::DeviceIndependent));
252 return scale(value, so.factor, so.origin);
253}
254
255template <typename T, typename C>
256T fromNativeWindowGeometry(const T &value, const C *context)
257{
258 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
259 QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
260 return scale(value, qreal(1) / so.factor, effectiveOrigin);
261}
262
263template <typename T, typename C>
264T toNativeWindowGeometry(const T &value, const C *context)
265{
266 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
267 QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
268 return scale(value, so.factor, effectiveOrigin);
269}
270
271template <typename T>
272inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
273{
274 return scale(value, qreal(1) / scaleFactor, origin);
275}
276
277template <typename T>
278inline T toNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
279{
280 return scale(value, scaleFactor, origin);
281}
282
283inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
284{
285 return scale(rect, qreal(1) / QHighDpiScaling::factor(screen), screenOrigin);
286}
287
288inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
289{
290 return QRect(nativeScreenGeometry.topLeft(),
291 scale(nativeScreenGeometry.size(), qreal(1) / QHighDpiScaling::factor(screen)));
292}
293
294inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
295{
296 return scale(pixelRegion, qreal(1) / QHighDpiScaling::factor(window));
297}
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.
301inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
302{
303 if (!QHighDpiScaling::isActive())
304 return pixelRegion;
305
306 const qreal scaleFactor = QHighDpiScaling::factor(window);
307 QRegion pointRegion;
308 for (const QRectF rect: pixelRegion)
309 pointRegion += QRectF(rect.topLeft() / scaleFactor, rect.size() / scaleFactor).toAlignedRect();
310
311 return pointRegion;
312}
313
314inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
315{
316 return scale(pointRegion, QHighDpiScaling::factor(window));
317}
318
319} // namespace QHighDpi
320#else // QT_NO_HIGHDPISCALING
321class Q_GUI_EXPORT QHighDpiScaling {
322public:
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
351namespace 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
389QT_END_NAMESPACE
390
391#endif // QHIGHDPISCALING_P_H
Collection of utility functions for UI scaling.
T toNativePixels(const T &value, const C *context)
QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind)
QList< T > scale(const QList< T > &list, qreal scaleFactor, QPoint origin=QPoint(0, 0))
T toNativeLocalPosition(const T &value, const C *context)
QSize scale(const QSize &value, qreal scaleFactor, QPointF=QPointF(0, 0))
T toNativeGlobalPosition(const T &value, const C *context)
T fromNativeLocalPosition(const T &value, const C *context)
T fromNativeGlobalPosition(const T &value, const C *context)
T toNative(const T &value, qreal scaleFactor, QPoint origin=QPoint(0, 0))
QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
qreal scale(qreal value, qreal scaleFactor, QPointF=QPointF(0, 0))
T fromNativePixels(const T &value, const C *context)
QHighDpiScaling::Point position(QPoint point, QHighDpiScaling::Point::Kind kind)
QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
T fromNative(const T &value, qreal scaleFactor, QPoint origin=QPoint(0, 0))
T toNativeWindowGeometry(const T &value, const C *context)
T fromNativeWindowGeometry(const T &value, const C *context)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
static const char screenFactorsEnvVar[]
static const char dpiAdjustmentPolicyEnvVar[]
static const ScaleFactorRoundingPolicyLookup scaleFactorRoundingPolicyLookup[]
static bool operator==(const EnumLookup< EnumType > &e1, const EnumLookup< EnumType > &e2)
static const char scaleFactorRoundingPolicyEnvVar[]
static std::optional< qreal > qEnvironmentVariableOptionalReal(const char *name)
static Qt::HighDpiScaleFactorRoundingPolicy lookupScaleFactorRoundingPolicy(const QByteArray &v)
static const char enableHighDpiScalingEnvVar[]
static const DpiAdjustmentPolicyLookup dpiAdjustmentPolicyLookup[]
static const char usePhysicalDpiEnvVar[]
static std::optional< QString > qEnvironmentVariableOptionalString(const char *name)
static std::optional< QByteArray > qEnvironmentVariableOptionalByteArray(const char *name)
static QByteArray joinEnumValues(const EnumLookup< EnumType > *i1, const EnumLookup< EnumType > *i2)
static const char scaleFactorEnvVar[]
static const char scaleFactorProperty[]
static QHighDpiScaling::DpiAdjustmentPolicy lookupDpiAdjustmentPolicy(const QByteArray &v)
std::pair< qreal, qreal > QDpi
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)
const char * name