/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QHIGHDPISCALING_P_H #define QHIGHDPISCALING_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcScaling); class QScreen; class QPlatformScreen; typedef QPair QDpi; #ifndef QT_NO_HIGHDPISCALING class Q_GUI_EXPORT QHighDpiScaling { public: static void initHighDpiScaling(); static void updateHighDpiScaling(); static void setGlobalFactor(qreal factor); static void setScreenFactor(QScreen *window, qreal factor); static bool isActive() { return m_active; } static qreal factor(const QWindow *window); static qreal factor(const QScreen *screen); static qreal factor(const QPlatformScreen *platformScreen); static QPoint origin(const QScreen *screen); static QPoint origin(const QPlatformScreen *platformScreen); static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QDpi logicalDpi(); private: static qreal screenSubfactor(const QPlatformScreen *screen); static qreal m_factor; static bool m_active; static bool m_usePixelDensity; static bool m_globalScalingActive; static bool m_pixelDensityScalingActive; static bool m_screenFactorSet; static QDpi m_logicalDpi; }; // Coordinate system conversion functions: // QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels // QHighDpi::toNativePixels : from logical to physical pixels namespace QHighDpi { inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { return (pos - origin) / scaleFactor + origin; } inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { return (pos - origin) * scaleFactor + origin; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { return (pos - origin) / scaleFactor + origin; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { return (pos - origin) * scaleFactor + origin; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor) { return pos / scaleFactor; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor) { return pos * scaleFactor; } inline QSize fromNative(const QSize &size, qreal scaleFactor) { return size / scaleFactor; // TODO: should we round up? } inline QSize toNative(const QSize &size, qreal scaleFactor) { return size * scaleFactor; } inline QSizeF fromNative(const QSizeF &size, qreal scaleFactor) { return size / scaleFactor; } inline QSizeF toNative(const QSizeF &size, qreal scaleFactor) { return size * scaleFactor; } inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) { return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor)); } inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) { return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor)); } inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) { return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin); } inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) { return QRect(nativeScreenGeometry.topLeft(), fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen))); } inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return pos / scaleFactor; } inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return pos * scaleFactor; } inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return pos / scaleFactor; } inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return pos * scaleFactor; } inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen) { const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); const QPoint origin = QHighDpiScaling::origin(platformScreen); return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), fromNative(pixelRect.size(), scaleFactor)); } inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen) { const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); const QPoint origin = QHighDpiScaling::origin(platformScreen); return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), toNative(pointRect.size(), scaleFactor)); } inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen) { const qreal scaleFactor = QHighDpiScaling::factor(screen); const QPoint origin = QHighDpiScaling::origin(screen); return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), fromNative(pixelRect.size(), scaleFactor)); } inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen) { const qreal scaleFactor = QHighDpiScaling::factor(screen); const QPoint origin = QHighDpiScaling::origin(screen); return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), toNative(pointRect.size(), scaleFactor)); } inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) { return fromNativePixels(pixelRect, window->screen()); } else { const qreal scaleFactor = QHighDpiScaling::factor(window); return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor)); } } inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen) { const qreal scaleFactor = QHighDpiScaling::factor(screen); const QPoint origin = QHighDpiScaling::origin(screen); return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin), toNative(pointRect.size(), scaleFactor)); } inline QRect toNativePixels(const QRect &pointRect, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) { return toNativePixels(pointRect, window->screen()); } else { const qreal scaleFactor = QHighDpiScaling::factor(window); return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor)); } } inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen) { const qreal scaleFactor = QHighDpiScaling::factor(screen); const QPoint origin = QHighDpiScaling::origin(screen); return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin), fromNative(pixelRect.size(), scaleFactor)); } inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) { return fromNativePixels(pixelRect, window->screen()); } else { const qreal scaleFactor = QHighDpiScaling::factor(window); return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor); } } inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) { return toNativePixels(pointRect, window->screen()); } else { const qreal scaleFactor = QHighDpiScaling::factor(window); return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor); } } inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window) { return pixelSize / QHighDpiScaling::factor(window); } inline QSize toNativePixels(const QSize &pointSize, const QWindow *window) { return pointSize * QHighDpiScaling::factor(window); } inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window) { return pixelSize / QHighDpiScaling::factor(window); } inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window) { return pointSize * QHighDpiScaling::factor(window); } inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen) { return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); } inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) return fromNativePixels(pixelPoint, window->screen()); else return pixelPoint / QHighDpiScaling::factor(window); } inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen) { return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); } inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) return toNativePixels(pointPoint, window->screen()); else return pointPoint * QHighDpiScaling::factor(window); } inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen) { return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); } inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) return fromNativePixels(pixelPoint, window->screen()); else return pixelPoint / QHighDpiScaling::factor(window); } inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen) { return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); } inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window) { if (window && window->isTopLevel() && window->screen()) return toNativePixels(pointPoint, window->screen()); else return pointPoint * QHighDpiScaling::factor(window); } inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor, pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor); } inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor, pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor); } inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelRegion; qreal scaleFactor = QHighDpiScaling::factor(window); QRegion pointRegion; const auto rects = pixelRegion.rects(); for (const QRect &rect : rects) { pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor), fromNative(rect.size(), scaleFactor)); } return pointRegion; } inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointRegion; qreal scaleFactor = QHighDpiScaling::factor(window); QRegion pixelRegon; const auto rects = pointRegion.rects(); for (const QRect &rect : rects) { pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor), toNative(rect.size(), scaleFactor)); } return pixelRegon; } // Any T that has operator/() template T fromNativePixels(const T &pixelValue, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelValue; return pixelValue / QHighDpiScaling::factor(window); } //##### ????? template T fromNativePixels(const T &pixelValue, const QScreen *screen) { if (!QHighDpiScaling::isActive()) return pixelValue; return pixelValue / QHighDpiScaling::factor(screen); } // Any T that has operator*() template T toNativePixels(const T &pointValue, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointValue; return pointValue * QHighDpiScaling::factor(window); } template T toNativePixels(const T &pointValue, const QScreen *screen) { if (!QHighDpiScaling::isActive()) return pointValue; return pointValue * QHighDpiScaling::factor(screen); } // Any QVector where T has operator/() template QVector fromNativePixels(const QVector &pixelValues, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelValues; QVector pointValues; for (const T &pixelValue : pixelValues) pointValues.append(pixelValue / QHighDpiScaling::factor(window)); return pointValues; } // Any QVector where T has operator*() template QVector toNativePixels(const QVector &pointValues, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointValues; QVector pixelValues; for (const T &pointValue : pointValues) pixelValues.append(pointValue * QHighDpiScaling::factor(window)); return pixelValues; } } // namespace QHighDpi #else // QT_NO_HIGHDPISCALING class Q_GUI_EXPORT QHighDpiScaling { public: static inline void initHighDpiScaling() {} static inline void updateHighDpiScaling() {} static inline void setGlobalFactor(qreal) {} static inline void setScreenFactor(QScreen *, qreal) {} static inline bool isActive() { return false; } static inline qreal factor(const QWindow *) { return 1.0; } static inline qreal factor(const QScreen *) { return 1.0; } static inline qreal factor(const QPlatformScreen *) { return 1.0; } static inline QPoint origin(const QScreen *) { return QPoint(); } static inline QPoint origin(const QPlatformScreen *) { return QPoint(); } static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; } static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; } static inline QDpi logicalDpi() { return QDpi(-1,-1); } }; namespace QHighDpi { template inline T toNative(const T &value, ...) { return value; } template inline T fromNative(const T &value, ...) { return value; } template inline T fromNativeLocalPosition(const T &value, ...) { return value; } template inline T toNativeLocalPosition(const T &value, ...) { return value; } template inline T fromNativeLocalRegion(const T &value, ...) { return value; } template inline T toNativeLocalRegion(const T &value, ...) { return value; } template inline T fromNativeScreenGeometry(const T &value, ...) { return value; } template inline T toNativePixels(const T &value, const U*) {return value;} template inline T fromNativePixels(const T &value, const U*) {return value;} } #endif // QT_NO_HIGHDPISCALING QT_END_NAMESPACE #endif // QHIGHDPISCALING_P_H