/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 ®ion, 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 |