4#ifndef QHIGHDPISCALING_P_H
5#define QHIGHDPISCALING_P_H
18#include <QtGui/private/qtguiglobal_p.h>
19#include <QtCore/qlist.h>
20#include <QtCore/qloggingcategory.h>
21#include <QtCore/qmargins.h>
22#include <QtCore/qmath.h>
23#include <QtCore/qrect.h>
24#include <QtGui/qregion.h>
25#include <QtGui/qscreen.h>
26#include <QtGui/qvector2d.h>
27#include <QtGui/qwindow.h>
37#ifndef QT_NO_HIGHDPISCALING
41 enum class DpiAdjustmentPolicy {
47 Q_ENUM(DpiAdjustmentPolicy)
49 QHighDpiScaling() =
delete;
50 ~QHighDpiScaling() =
delete;
51 QHighDpiScaling(
const QHighDpiScaling &) =
delete;
52 QHighDpiScaling &operator=(
const QHighDpiScaling &) =
delete;
53 QHighDpiScaling(QHighDpiScaling &&) =
delete;
54 QHighDpiScaling &operator=(QHighDpiScaling &&) =
delete;
56 static void initHighDpiScaling();
57 static void updateHighDpiScaling();
58 static void setGlobalFactor(qreal factor);
59 static void setScreenFactor(QScreen *screen, qreal factor);
61 static bool isActive() {
return m_active; }
79 static ScaleAndOrigin scaleAndOrigin(
const QPlatformScreen *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
80 static ScaleAndOrigin scaleAndOrigin(
const QScreen *screen, Point position = Point{ Point::Invalid, QPoint() });
81 static ScaleAndOrigin scaleAndOrigin(
const QWindow *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
84 static qreal factor(C *context) {
85 return scaleAndOrigin(context).factor;
88 static QPoint mapPositionFromNative(
const QPoint &pos,
const QPlatformScreen *platformScreen);
89 static QPoint mapPositionToNative(
const QPoint &pos,
const QPlatformScreen *platformScreen);
90 static QDpi logicalDpi(
const QScreen *screen);
91 static qreal roundScaleFactor(qreal rawFactor);
95 ScreenFactor(QString name, qreal factor)
96 :name(name), factor(factor) { }
101 static qreal rawScaleFactor(
const QPlatformScreen *screen);
102 static QDpi effectiveLogicalDpi(
const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
103 static qreal screenSubfactor(
const QPlatformScreen *screen);
104 static QScreen *screenForPosition(Point position, QScreen *guess);
105 static QList<QHighDpiScaling::ScreenFactor> parseScreenScaleFactorsSpec(QStringView screenScaleFactors);
107 static qreal m_factor;
108 static bool m_active;
109 static bool m_usePlatformPluginDpi;
110 static bool m_platformPluginDpiScalingActive;
111 static bool m_globalScalingActive;
112 static bool m_screenFactorSet;
113 static bool m_usePhysicalDpi;
114 static QVector<ScreenFactor> m_screenFactors;
115 static DpiAdjustmentPolicy m_dpiAdjustmentPolicy;
116 static QHash<QString, qreal> m_namedScreenScaleFactors;
118#ifndef QT_NO_DEBUG_STREAM
119 friend Q_GUI_EXPORT QDebug operator<<(QDebug,
const ScreenFactor &);
125inline qreal scale(qreal value, qreal scaleFactor, QPointF = QPointF(0, 0))
127 return value * scaleFactor;
130inline QSize scale(
const QSize &value, qreal scaleFactor, QPointF = QPointF(0, 0))
132 return value * scaleFactor;
135inline QSizeF scale(
const QSizeF &value, qreal scaleFactor, QPointF = QPointF(0, 0))
137 return value * scaleFactor;
140inline QVector2D scale(
const QVector2D &value, qreal scaleFactor, QPointF = QPointF(0, 0))
142 return value *
float(scaleFactor);
145inline QPointF scale(
const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
147 return (pos - origin) * scaleFactor + origin;
150inline QPoint scale(
const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
152 return (pos - origin) * scaleFactor + origin;
155inline QRect scale(
const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
157 return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
160inline QRectF scale(
const QRectF &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
162 return QRectF(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
165inline QMargins scale(
const QMargins &margins, qreal scaleFactor, QPoint origin = QPoint(0, 0))
168 return QMargins(qRound(qreal(margins.left()) * scaleFactor), qRound(qreal(margins.top()) * scaleFactor),
169 qRound(qreal(margins.right()) * scaleFactor), qRound(qreal(margins.bottom()) * scaleFactor));
173QList<
T>
scale(
const QList<T> &list, qreal scaleFactor, QPoint origin = QPoint(0, 0))
175 if (qFuzzyCompare(scaleFactor, qreal(1)))
179 scaled.reserve(list.size());
180 for (
const T &item : list)
181 scaled.append(scale(item, scaleFactor, origin));
185inline QRegion scale(
const QRegion ®ion, qreal scaleFactor, QPoint origin = QPoint(0, 0))
187 if (qFuzzyCompare(scaleFactor, qreal(1)))
190 QRegion scaled = region.translated(-origin);
191 scaled = QTransform::fromScale(scaleFactor, scaleFactor).map(scaled);
192 return scaled.translated(origin);
197 return QHighDpiScaling::Point{ QHighDpiScaling::Point::Invalid, QPoint() };
200 return QHighDpiScaling::Point{ kind, point };
203 return QHighDpiScaling::Point{ kind, point.toPoint() };
206 return QHighDpiScaling::Point{ kind, rect.topLeft() };
209 return QHighDpiScaling::Point{ kind, rect.topLeft().toPoint() };
212template <
typename T,
typename C>
215 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
216 return scale(value, qreal(1) / so.factor, so.origin);
219template <
typename T,
typename C>
222 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
223 return scale(value, so.factor, so.origin);
226template <
typename T,
typename C>
229 return scale(value, qreal(1) / QHighDpiScaling::factor(context));
232template <
typename T,
typename C>
235 return scale(value, QHighDpiScaling::factor(context));
238template <
typename T,
typename C>
241 QHighDpiScaling::ScaleAndOrigin so =
242 QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::Native));
243 return scale(value, qreal(1) / so.factor, so.origin);
246template <
typename T,
typename C>
249 QHighDpiScaling::ScaleAndOrigin so =
250 QHighDpiScaling::scaleAndOrigin(context, position(value, QHighDpiScaling::Point::DeviceIndependent));
251 return scale(value, so.factor, so.origin);
254template <
typename T,
typename C>
257 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
258 QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
259 return scale(value, qreal(1) / so.factor, effectiveOrigin);
262template <
typename T,
typename C>
265 QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
266 QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
267 return scale(value, so.factor, effectiveOrigin);
271inline T
fromNative(
const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
273 return scale(value, qreal(1) / scaleFactor, origin);
277inline T
toNative(
const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
279 return scale(value, scaleFactor, origin);
282inline QRect fromNative(
const QRect &rect,
const QScreen *screen,
const QPoint &screenOrigin)
284 return scale(rect, qreal(1) / QHighDpiScaling::factor(screen), screenOrigin);
289 return QRect(nativeScreenGeometry.topLeft(),
290 scale(nativeScreenGeometry.size(), qreal(1) / QHighDpiScaling::factor(screen)));
295 return scale(pixelRegion, qreal(1) / QHighDpiScaling::factor(window));
302 if (!QHighDpiScaling::isActive())
305 const qreal scaleFactor = QHighDpiScaling::factor(window);
307 for (
const QRectF rect: pixelRegion)
308 pointRegion += QRectF(rect.topLeft() / scaleFactor, rect.size() / scaleFactor).toAlignedRect();
315 return scale(pointRegion, QHighDpiScaling::factor(window));
320class Q_GUI_EXPORT QHighDpiScaling {
322 static inline void initHighDpiScaling() {}
323 static inline void updateHighDpiScaling() {}
324 static inline void setGlobalFactor(qreal) {}
325 static inline void setScreenFactor(QScreen *, qreal) {}
327 struct ScaleAndOrigin
332 static ScaleAndOrigin scaleAndOrigin(
const QPlatformScreen *platformScreen, QPoint *nativePosition =
nullptr);
333 static ScaleAndOrigin scaleAndOrigin(
const QScreen *screen, QPoint *nativePosition =
nullptr);
334 static ScaleAndOrigin scaleAndOrigin(
const QWindow *platformScreen, QPoint *nativePosition =
nullptr);
336 static inline bool isActive() {
return false; }
337 static inline qreal factor(
const QWindow *) {
return 1.0; }
338 static inline qreal factor(
const QScreen *) {
return 1.0; }
339 static inline qreal factor(
const QPlatformScreen *) {
return 1.0; }
340 static inline QPoint origin(
const QScreen *) {
return QPoint(); }
341 static inline QPoint origin(
const QPlatformScreen *) {
return QPoint(); }
342 static inline QPoint mapPositionFromNative(
const QPoint &pos,
const QPlatformScreen *) {
return pos; }
343 static inline QPoint mapPositionToNative(
const QPoint &pos,
const QPlatformScreen *) {
return pos; }
344 static inline QPointF mapPositionToGlobal(
const QPointF &pos,
const QPoint &,
const QWindow *) {
return pos; }
345 static inline QPointF mapPositionFromGlobal(
const QPointF &pos,
const QPoint &,
const QWindow *) {
return pos; }
346 static inline QDpi logicalDpi(
const QScreen *) {
return QDpi(-1,-1); }
347 static inline qreal roundScaleFactor(qreal) {
return 1.0; }
351 template <
typename T>
inline
352 T scale(
const T &value, ...) {
return value; }
354 template <
typename T>
inline
355 T toNative(
const T &value, ...) {
return value; }
356 template <
typename T>
inline
357 T fromNative(
const T &value, ...) {
return value; }
359 template <
typename T>
inline
360 T fromNativeLocalPosition(
const T &value, ...) {
return value; }
361 template <
typename T>
inline
362 T toNativeLocalPosition(
const T &value, ...) {
return value; }
363 template <
typename T,
typename C>
inline
364 T fromNativeGlobalPosition(
const T &value,
const C *) {
return value; }
365 template <
typename T,
typename C>
inline
366 T toNativeGlobalPosition(
const T &value,
const C *) {
return value; }
367 template <
typename T,
typename C>
inline
368 T fromNativeWindowGeometry(
const T &value,
const C *) {
return value; }
369 template <
typename T,
typename C>
inline
370 T toNativeWindowGeometry(
const T &value,
const C *) {
return value; }
372 template <
typename T>
inline
373 T fromNativeLocalRegion(
const T &value, ...) {
return value; }
374 template <
typename T>
inline
375 T fromNativeLocalExposedRegion(
const T &value, ...) {
return value; }
376 template <
typename T>
inline
377 T toNativeLocalRegion(
const T &value, ...) {
return value; }
379 template <
typename T>
inline
380 T fromNativeScreenGeometry(
const T &value, ...) {
return value; }
382 template <
typename T,
typename U>
inline
383 T toNativePixels(
const T &value,
const U*) {
return value;}
384 template <
typename T,
typename U>
inline
385 T fromNativePixels(
const T &value,
const U*) {
return value;}
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")
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher)
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