From 7d2cfbe5aa1e67d12010a66481625c9d40f0c174 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Samuel=20R=C3=B8dal?= Date: Fri, 30 Sep 2011 14:25:43 +0200 Subject: [PATCH] Improved logical and physical DPI APIs. Made physicalSize() return QSizeF instead, to prevent rounding errors. Added logicalSize() as the base to compute font pixel sizes instead, and added convenience functions in QScreen to access the logical and physical sizes and DPI metrics. Task-number: QTBUG-21736 Task-number: QTBUG-21737 Change-Id: Ic705dc98eb3632617659e65a0c9a552673dc0c65 Reviewed-on: http://codereview.qt-project.org/5888 Reviewed-by: Qt Sanity Bot Reviewed-by: Friedemann Kleint --- src/gui/kernel/qplatformscreen_qpa.cpp | 33 +++++++++-- src/gui/kernel/qplatformscreen_qpa.h | 6 +- src/gui/kernel/qscreen.cpp | 69 ++++++++++++++++++++++ src/gui/kernel/qscreen.h | 12 +++- src/gui/text/qfont.cpp | 8 +-- src/plugins/platforms/cocoa/qcocoaintegration.h | 4 +- src/plugins/platforms/cocoa/qcocoaintegration.mm | 2 +- .../platforms/directfb/qdirectfbintegration.cpp | 2 +- .../platforms/directfb/qdirectfbintegration.h | 4 +- src/plugins/platforms/kms/qkmsscreen.cpp | 4 +- src/plugins/platforms/kms/qkmsscreen.h | 4 +- src/plugins/platforms/openwfd/qopenwfdscreen.cpp | 4 +- src/plugins/platforms/openwfd/qopenwfdscreen.h | 2 +- src/plugins/platforms/qvfb/qvfbintegration.cpp | 4 +- src/plugins/platforms/qvfb/qvfbintegration.h | 2 +- src/plugins/platforms/uikit/quikitscreen.h | 4 +- src/plugins/platforms/uikit/quikitscreen.mm | 2 +- src/plugins/platforms/windows/qwindowsscreen.cpp | 16 +++-- src/plugins/platforms/windows/qwindowsscreen.h | 7 ++- src/plugins/platforms/xcb/qxcbscreen.cpp | 4 +- src/plugins/platforms/xcb/qxcbscreen.h | 2 +- src/plugins/platforms/xlib/qxlibscreen.cpp | 2 +- src/plugins/platforms/xlib/qxlibscreen.h | 4 +- src/widgets/kernel/qwidget_qpa.cpp | 23 +++++--- 24 files changed, 165 insertions(+), 59 deletions(-) diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp index 1a8e6d8..86dc0bd 100644 --- a/src/gui/kernel/qplatformscreen_qpa.cpp +++ b/src/gui/kernel/qplatformscreen_qpa.cpp @@ -127,20 +127,41 @@ QScreen *QPlatformScreen::screen() const /*! Reimplement this function in subclass to return the physical size of the - screen. This function is used by QFont to convert point sizes to pixel - sizes. + screen. The physical size represents the actual physical dimensions of + the display. The default implementation takes the pixel size of the screen, considers a resolution of 100 dots per inch, and returns the calculated physical size. A device with a screen that has different resolutions will need to be supported by a suitable reimplementation of this function. + + \sa logcalDpi */ -QSize QPlatformScreen::physicalSize() const +QSizeF QPlatformScreen::physicalSize() const { static const int dpi = 100; - int width = geometry().width() / dpi * qreal(25.4) ; - int height = geometry().height() / dpi * qreal(25.4) ; - return QSize(width,height); + return QSizeF(geometry().size()) / dpi * qreal(25.4); +} + +/*! + Reimplement this function in subclass to return the logical horizontal + and vertical dots per inch metrics of the screen. + + The logical dots per inch metrics are used by QFont to convert point sizes + to pixel sizes. + + The default implementation uses the screen pixel size and physical size to + compute the metrics. + + \sa physicalSize +*/ +QDpi QPlatformScreen::logicalDpi() const +{ + QSizeF ps = physicalSize(); + QSize s = geometry().size(); + + return QDpi(25.4 * s.width() / ps.width(), + 25.4 * s.height() / ps.height()); } QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window) diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h index 7c20fba..6917d5e 100644 --- a/src/gui/kernel/qplatformscreen_qpa.h +++ b/src/gui/kernel/qplatformscreen_qpa.h @@ -67,6 +67,8 @@ class QPlatformWindow; class QScreen; class QSurfaceFormat; +typedef QPair QDpi; + class Q_GUI_EXPORT QPlatformScreenPageFlipper : public QObject { Q_OBJECT @@ -93,7 +95,9 @@ public: virtual int depth() const = 0; virtual QImage::Format format() const = 0; - virtual QSize physicalSize() const; + + virtual QSizeF physicalSize() const; + virtual QDpi logicalDpi() const; virtual QWindow *topLevelAt(const QPoint &point) const; virtual QList virtualSiblings() const; diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 96ed2bd..c2049af 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -102,6 +102,75 @@ QSize QScreen::size() const } /*! + Gets the number of physical dots or pixels per inch in the horizontal direction. + + This value represents the actual horizontal pixel density on the screen's display. + Depending on what information the underlying system provides the value might not be + entirely accurate. + + \sa physicalDotsPerInchY() +*/ +qreal QScreen::physicalDotsPerInchX() const +{ + return size().width() / physicalSize().width() * 25.4; +} + +/*! + Gets the number of physical dots or pixels per inch in the vertical direction. + + This value represents the actual vertical pixel density on the screen's display. + Depending on what information the underlying system provides the value might not be + entirely accurate. + + \sa physicalDotsPerInchX() +*/ +qreal QScreen::physicalDotsPerInchY() const +{ + return size().height() / physicalSize().height() * 25.4; +} + +/*! + Gets the number of logical dots or pixels per inch in the horizontal direction. + + This value is used to convert font point sizes to pixel sizes. + + \sa logicalDotsPerInchY() +*/ +qreal QScreen::logicalDotsPerInchX() const +{ + Q_D(const QScreen); + return d->platformScreen->logicalDpi().first; +} + +/*! + Gets the number of logical dots or pixels per inch in the vertical direction. + + This value is used to convert font point sizes to pixel sizes. + + \sa logicalDotsPerInchX() +*/ +qreal QScreen::logicalDotsPerInchY() const +{ + Q_D(const QScreen); + return d->platformScreen->logicalDpi().second; +} + +/*! + Get the screen's physical size (in millimeters). + + The physical size represents the actual physical dimensions of the + screen's display. + + Depending on what information the underlying system provides the value + might not be entirely accurate. +*/ +QSizeF QScreen::physicalSize() const +{ + Q_D(const QScreen); + return d->platformScreen->physicalSize(); +} + +/*! Get the screen's available size. The available size is the size excluding window manager reserved areas diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index ea068cd..72681eb 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -44,6 +44,9 @@ #include #include +#include +#include +#include QT_BEGIN_HEADER @@ -54,7 +57,6 @@ QT_MODULE(Gui) class QPlatformScreen; class QScreenPrivate; class QWindow; -class QSize; class QRect; class Q_GUI_EXPORT QScreen : public QObject @@ -72,6 +74,14 @@ public: QSize size() const; QRect geometry() const; + QSizeF physicalSize() const; + + qreal physicalDotsPerInchX() const; + qreal physicalDotsPerInchY() const; + + qreal logicalDotsPerInchX() const; + qreal logicalDotsPerInchY() const; + QSize availableSize() const; QRect availableGeometry() const; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index e8308db..3d2dfb9 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -170,9 +170,7 @@ Q_GUI_EXPORT int qt_defaultDpiX() #elif defined(Q_WS_QPA) QScreen *screen = QGuiApplication::primaryScreen(); if (screen) { - const QSize screenSize = screen->geometry().size(); - const QSize physicalSize = screen->handle()->physicalSize(); - dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4))); + dpi = qRound(screen->logicalDotsPerInchX()); } else { //PI has not been initialised, or it is being initialised. Give a default dpi dpi = 100; @@ -200,9 +198,7 @@ Q_GUI_EXPORT int qt_defaultDpiY() #elif defined(Q_WS_QPA) QScreen *screen = QGuiApplication::primaryScreen(); if (screen) { - const QSize screenSize = screen->geometry().size(); - const QSize physicalSize = screen->handle()->physicalSize(); - dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4))); + dpi = qRound(screen->logicalDotsPerInchY()); } else { //PI has not been initialised, or it is being initialised. Give a default dpi dpi = 100; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index a253a6b..6e845de 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -59,14 +59,14 @@ public: QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } - QSize physicalSize() const { return m_physicalSize; } + QSizeF physicalSize() const { return m_physicalSize; } public: NSScreen *m_screen; QRect m_geometry; int m_depth; QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; }; class QCocoaIntegration : public QPlatformIntegration diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 6399314..68567a3 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -70,7 +70,7 @@ QCocoaScreen::QCocoaScreen(int screenIndex) const int dpi = 72; const qreal inch = 25.4; - m_physicalSize = QSize(qRound(m_geometry.width() * inch / dpi), qRound(m_geometry.height() *inch / dpi)); + m_physicalSize = QSizeF(m_geometry.size()) * inch / dpi; } QCocoaScreen::~QCocoaScreen() diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp index 7bf26b4..803d2f5 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp +++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp @@ -73,7 +73,7 @@ QDirectFbScreen::QDirectFbScreen(int display) const int dpi = 72; const qreal inch = 25.4; m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat); - m_physicalSize = QSize(qRound(config.width * inch / dpi), qRound(config.height *inch / dpi)); + m_physicalSize = QSizeF(config.width, config.height) * inch / dpi; m_cursor = new QDirectFBCursor(this); } diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h index 64f3b60..cba3249 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.h +++ b/src/plugins/platforms/directfb/qdirectfbintegration.h @@ -63,13 +63,13 @@ public: QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } - QSize physicalSize() const { return m_physicalSize; } + QSizeF physicalSize() const { return m_physicalSize; } public: QRect m_geometry; int m_depth; QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; IDirectFBDisplayLayer *m_layer; diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp index 0cd1530..9ea20ae 100644 --- a/src/plugins/platforms/kms/qkmsscreen.cpp +++ b/src/plugins/platforms/kms/qkmsscreen.cpp @@ -91,7 +91,7 @@ QImage::Format QKmsScreen::format() const return m_format; } -QSize QKmsScreen::physicalSize() const +QSizeF QKmsScreen::physicalSize() const { return m_physicalSize; } @@ -132,7 +132,7 @@ void QKmsScreen::initializeScreenMode() m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay); m_depth = 32; m_format = QImage::Format_RGB32; - m_physicalSize = QSize(connector->mmWidth, connector->mmHeight); + m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight); //Setup three buffers for current mode m_bufferManager.setupBuffersForMode(m_mode, 3); diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h index 5c8b5ca..5807366 100644 --- a/src/plugins/platforms/kms/qkmsscreen.h +++ b/src/plugins/platforms/kms/qkmsscreen.h @@ -60,7 +60,7 @@ public: QRect geometry() const; int depth() const; QImage::Format format() const; - QSize physicalSize() const; + QSizeF physicalSize() const; GLuint framebufferObject() const; quint32 crtcId() const { return m_crtcId; } @@ -83,7 +83,7 @@ private: quint32 m_crtcId; drmModeModeInfo m_mode; QRect m_geometry; - QSize m_physicalSize; + QSizeF m_physicalSize; int m_depth; QImage::Format m_format; diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.cpp b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp index 785bee9..0d33618 100644 --- a/src/plugins/platforms/openwfd/qopenwfdscreen.cpp +++ b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp @@ -112,9 +112,9 @@ QImage::Format QOpenWFDScreen::format() const return QImage::Format_RGB32; } -QSize QOpenWFDScreen::physicalSize() const +QSizeF QOpenWFDScreen::physicalSize() const { - return mPort->physicalSize().toSize(); + return mPort->physicalSize(); } QOpenWFDPort * QOpenWFDScreen::port() const diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.h b/src/plugins/platforms/openwfd/qopenwfdscreen.h index bb23744..fc65e50 100644 --- a/src/plugins/platforms/openwfd/qopenwfdscreen.h +++ b/src/plugins/platforms/openwfd/qopenwfdscreen.h @@ -64,7 +64,7 @@ public: QRect geometry() const; int depth() const; QImage::Format format() const; - QSize physicalSize() const; + QSizeF physicalSize() const; QOpenWFDPort *port() const; diff --git a/src/plugins/platforms/qvfb/qvfbintegration.cpp b/src/plugins/platforms/qvfb/qvfbintegration.cpp index d4d8183..1ddf934 100644 --- a/src/plugins/platforms/qvfb/qvfbintegration.cpp +++ b/src/plugins/platforms/qvfb/qvfbintegration.cpp @@ -392,8 +392,8 @@ QImage::Format QVFbScreen::format() const return d_ptr->format(); } -QSize QVFbScreen::physicalSize() const { - return (d_ptr->screenSize()*254)/720; +QSizeF QVFbScreen::physicalSize() const { + return (QSizeF(d_ptr->screenSize())*254)/720.; } #if 0 diff --git a/src/plugins/platforms/qvfb/qvfbintegration.h b/src/plugins/platforms/qvfb/qvfbintegration.h index 1c736c2..c6bfcc5 100644 --- a/src/plugins/platforms/qvfb/qvfbintegration.h +++ b/src/plugins/platforms/qvfb/qvfbintegration.h @@ -60,7 +60,7 @@ public: QRect geometry() const; int depth() const; QImage::Format format() const; - QSize physicalSize() const; + QSizeF physicalSize() const; QImage *screenImage(); diff --git a/src/plugins/platforms/uikit/quikitscreen.h b/src/plugins/platforms/uikit/quikitscreen.h index 23e95f6..bde4f89 100644 --- a/src/plugins/platforms/uikit/quikitscreen.h +++ b/src/plugins/platforms/uikit/quikitscreen.h @@ -57,7 +57,7 @@ public: QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } - QSize physicalSize() const { return m_physicalSize; } + QSizeF physicalSize() const { return m_physicalSize; } UIScreen *uiScreen() const; @@ -65,7 +65,7 @@ private: QRect m_geometry; int m_depth; QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; int m_index; }; diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index 0a5b027..b938542 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -67,7 +67,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) dpi = 132.; dragDistance = 10; } - m_physicalSize = QSize(qRound(bounds.size.width * inch / dpi), qRound(bounds.size.height * inch / dpi)); + m_physicalSize = QSizeF(bounds.size.width, bounds.size.height) * inch / dpi; qApp->setStartDragDistance(dragDistance); [pool release]; } diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cde9dec..c6784e5 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -55,8 +55,6 @@ QT_BEGIN_NAMESPACE -typedef QPair DPI; - QWindowsScreenData::QWindowsScreenData() : dpi(96, 96), depth(32), @@ -64,25 +62,25 @@ QWindowsScreenData::QWindowsScreenData() : { } -static inline DPI deviceDPI(HDC hdc) +static inline QDpi deviceDPI(HDC hdc) { - return DPI(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY)); + return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY)); } -static inline QSize deviceSizeMM(const QSize &pixels, const DPI &dpi) +static inline QSizeF deviceSizeMM(const QSize &pixels, const QDpi &dpi) { const qreal inchToMM = 25.4; const qreal h = qreal(pixels.width()) / qreal(dpi.first) * inchToMM; const qreal v = qreal(pixels.height()) / qreal(dpi.second) * inchToMM; - return QSize(qRound(h), qRound(v)); + return QSizeF(h, v); } -static inline DPI deviceDPI(const QSize &pixels, const QSize &physicalSizeMM) +static inline QDpi deviceDPI(const QSize &pixels, const QSizeF &physicalSizeMM) { const qreal inchToMM = 25.4; const qreal h = qreal(pixels.width()) / (qreal(physicalSizeMM.width()) / inchToMM); const qreal v = qreal(pixels.height()) / (qreal(physicalSizeMM.height()) / inchToMM); - return DPI(qRound(v), qRound(h)); + return QDpi(h, v); } typedef QList WindowsScreenDataList; @@ -101,13 +99,13 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); if (HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL)) { data.dpi = deviceDPI(hdc); + data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE)); DeleteDC(hdc); } else { qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %d DPI.", __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)), data.dpi.first); } - data.physicalSizeMM = deviceSizeMM(data.geometry.size(), data.dpi); data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1)); data.primary = (info.dwFlags & MONITORINFOF_PRIMARY) != 0; diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 65ee865..b424375 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -56,8 +56,8 @@ struct QWindowsScreenData QRect geometry; QRect availableGeometry; - QPair dpi; - QSize physicalSizeMM; + QDpi dpi; + QSizeF physicalSizeMM; int depth; QImage::Format format; bool primary; @@ -74,7 +74,8 @@ public: virtual QRect availableGeometry() const { return m_data.availableGeometry; } virtual int depth() const { return m_data.depth; } virtual QImage::Format format() const { return m_data.format; } - virtual QSize physicalSize() const { return m_data.physicalSizeMM; } + virtual QSizeF physicalSize() const { return m_data.physicalSizeMM; } + virtual QDpi logicalDpi() const { return m_data.dpi; } virtual QWindow *topLevelAt(const QPoint &point) const { return QWindowsScreen::findTopLevelAt(point, CWP_SKIPINVISIBLE); } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index d958316..386dbdc 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -222,9 +222,9 @@ QImage::Format QXcbScreen::format() const return QImage::Format_RGB32; } -QSize QXcbScreen::physicalSize() const +QSizeF QXcbScreen::physicalSize() const { - return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); + return QSizeF(m_screen->width_in_millimeters, m_screen->height_in_millimeters); } int QXcbScreen::screenNumber() const diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 3c9bf05..76cc0fa 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -67,7 +67,7 @@ public: QRect geometry() const; int depth() const; QImage::Format format() const; - QSize physicalSize() const; + QSizeF physicalSize() const; int screenNumber() const; diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp index e6263c0..314a3e4 100644 --- a/src/plugins/platforms/xlib/qxlibscreen.cpp +++ b/src/plugins/platforms/xlib/qxlibscreen.cpp @@ -218,7 +218,7 @@ QXlibScreen::QXlibScreen() int physicalWidth = DisplayWidthMM(mDisplay->nativeDisplay(), mScreen); int physicalHeight = DisplayHeightMM(mDisplay->nativeDisplay(), mScreen); - mPhysicalSize = QSize(physicalWidth,physicalHeight); + mPhysicalSize = QSizeF(physicalWidth, physicalHeight); int xSocketNumber = XConnectionNumber(mDisplay->nativeDisplay()); diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h index 6e1a3e4..13fc03e 100644 --- a/src/plugins/platforms/xlib/qxlibscreen.h +++ b/src/plugins/platforms/xlib/qxlibscreen.h @@ -62,7 +62,7 @@ public: QRect geometry() const { return mGeometry; } int depth() const { return mDepth; } QImage::Format format() const { return mFormat; } - QSize physicalSize() const { return mPhysicalSize; } + QSizeF physicalSize() const { return mPhysicalSize; } Window rootWindow(); unsigned long blackPixel(); @@ -94,7 +94,7 @@ private: void handleSelectionRequest(XEvent *event); QRect mGeometry; - QSize mPhysicalSize; + QSizeF mPhysicalSize; int mDepth; QImage::Format mFormat; QXlibCursor *mCursor; diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 65ba0fc..f1e0835 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -739,12 +739,15 @@ int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); - QPlatformScreen *screen = 0; + QScreen *screen = 0; if (QWidget *topLevel = window()) - if (QWindow *topLevelWindow = topLevel->windowHandle()) - screen = QPlatformScreen::platformScreenForWindow(topLevelWindow); + if (QWindow *topLevelWindow = topLevel->windowHandle()) { + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); + if (platformScreen) + screen = platformScreen->screen(); + } if (!screen && QGuiApplication::primaryScreen()) - screen = QGuiApplication::primaryScreen()->handle(); + screen = QGuiApplication::primaryScreen(); if (!screen) { if (m == PdmDpiX || m == PdmDpiY) @@ -762,18 +765,22 @@ int QWidget::metric(PaintDeviceMetric m) const val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height(); } else if (m == PdmDepth) { return screen->depth(); - } else if (m == PdmDpiX || m == PdmPhysicalDpiX) { + } else if (m == PdmDpiX) { if (d->extra && d->extra->customDpiX) return d->extra->customDpiX; else if (d->parent) return static_cast(d->parent)->metric(m); - return qRound(screen->geometry().width() / double(screen->physicalSize().width() / 25.4)); - } else if (m == PdmDpiY || m == PdmPhysicalDpiY) { + return qRound(screen->logicalDotsPerInchX()); + } else if (m == PdmDpiY) { if (d->extra && d->extra->customDpiY) return d->extra->customDpiY; else if (d->parent) return static_cast(d->parent)->metric(m); - return qRound(screen->geometry().height() / double(screen->physicalSize().height() / 25.4)); + return qRound(screen->logicalDotsPerInchY()); + } else if (m == PdmPhysicalDpiX) { + return qRound(screen->physicalDotsPerInchX()); + } else if (m == PdmPhysicalDpiY) { + return qRound(screen->physicalDotsPerInchY()); } else { val = QPaintDevice::metric(m);// XXX } -- 2.7.4