From bcfad66e893fe35dde4c480ebbd52a23be2deae4 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 13 Aug 2010 21:57:55 +1200 Subject: [PATCH] Bug 537890. Part 2: Get DPI values for Mac, Windows, and X. r=jmathies,josh,karlt --- widget/src/cocoa/nsChildView.h | 1 + widget/src/cocoa/nsChildView.mm | 22 ++++++++++++++++++++++ widget/src/gtk2/nsWindow.cpp | 13 +++++++++++++ widget/src/gtk2/nsWindow.h | 1 + widget/src/qt/nsWindow.cpp | 13 +++++++++++++ widget/src/qt/nsWindow.h | 1 + widget/src/windows/nsWindow.cpp | 16 ++++++++++++++++ widget/src/windows/nsWindow.h | 1 + 8 files changed, 68 insertions(+) diff --git a/widget/src/cocoa/nsChildView.h b/widget/src/cocoa/nsChildView.h index 1ac3e04d02a..235920801d1 100644 --- a/widget/src/cocoa/nsChildView.h +++ b/widget/src/cocoa/nsChildView.h @@ -297,6 +297,7 @@ public: NS_IMETHOD SetParent(nsIWidget* aNewParent); virtual nsIWidget* GetParent(void); + virtual float GetDPI(); LayerManager* GetLayerManager(); diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 5e3eff00505..68aa9101243 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -965,6 +965,28 @@ nsChildView::GetParent() return mParentWidget; } +float +nsChildView::GetDPI() +{ + NSWindow* window = [mView window]; + NSScreen* screen = [window screen]; + if (!screen) + return 96.0f; + + CGDirectDisplayID displayID = + [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; + CGFloat heightMM = CGDisplayScreenSize(displayID).height; + size_t heightPx = CGDisplayPixelsHigh(displayID); + CGFloat scaleFactor = [window userSpaceScaleFactor]; + + // Currently we don't do our own scaling to take account + // of userSpaceScaleFactor, so every "pixel" we draw is actually + // userSpaceScaleFactor screen pixels. So divide the screen height + // by userSpaceScaleFactor to get the number of "device pixels" + // available. + return (heightPx / scaleFactor) / (heightMM / 25.4f); +} + LayerManager* nsChildView::GetLayerManager() { diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index d94bc12519a..958b69a1ef0 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -821,6 +821,19 @@ nsWindow::GetParent(void) return mParent; } +float +nsWindow::GetDPI() +{ + Display *dpy = GDK_DISPLAY(); + int defaultScreen = DefaultScreen(dpy); + double heightInches = DisplayHeightMM(dpy, defaultScreen)/25.4; + if (heightInches < 0.25) { + // Something's broken, but we'd better not crash. + return 96.0f; + } + return float(DisplayHeight(dpy, defaultScreen)/heightInches); +} + NS_IMETHODIMP nsWindow::SetParent(nsIWidget *aNewParent) { diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h index 20cfca19efe..e5689aa7970 100644 --- a/widget/src/gtk2/nsWindow.h +++ b/widget/src/gtk2/nsWindow.h @@ -136,6 +136,7 @@ public: nsWidgetInitData *aInitData); NS_IMETHOD Destroy(void); virtual nsIWidget *GetParent(); + virtual float GetDPI(); virtual nsresult SetParent(nsIWidget* aNewParent); NS_IMETHOD SetModal(PRBool aModal); NS_IMETHOD IsVisible(PRBool & aState); diff --git a/widget/src/qt/nsWindow.cpp b/widget/src/qt/nsWindow.cpp index b587a366ecc..e68f4d3c5e9 100644 --- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -2189,6 +2189,19 @@ nsWindow::GetParent(void) return mParent; } +float +nsWindow::GetDPI() +{ + QDesktopWidget* rootWindow = QApplication::desktop(); + double heightInches = rootWindow->heightMM()/25.4; + if (heightInches < 0.25) { + // Something's broken, but we'd better not crash. + return 96.0f; + } + + return float(rootWindow->height()/heightInches); +} + void nsWindow::DispatchActivateEvent(void) { diff --git a/widget/src/qt/nsWindow.h b/widget/src/qt/nsWindow.h index 2eeab48ff7c..19a84a1bc6f 100644 --- a/widget/src/qt/nsWindow.h +++ b/widget/src/qt/nsWindow.h @@ -133,6 +133,7 @@ public: NS_IMETHOD Destroy(void); NS_IMETHOD SetParent(nsIWidget* aNewParent); virtual nsIWidget *GetParent(void); + virtual float GetDPI(); NS_IMETHOD Show(PRBool aState); NS_IMETHOD SetModal(PRBool aModal); NS_IMETHOD IsVisible(PRBool & aState); diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 1353c6d1002..d86778bdf9e 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -1066,6 +1066,22 @@ nsIWidget* nsWindow::GetParent(void) return GetParentWindow(PR_FALSE); } +float nsWindow::GetDPI() +{ + HDC dc = ::GetDC(mWnd); + if (!dc) + return 96.0f; + + double heightInches = ::GetDeviceCaps(dc, VERTSIZE)/25.4; + int heightPx = ::GetDeviceCaps(dc, VERTRES); + ::ReleaseDC(mWnd, dc); + if (heightInches < 0.25) { + // Something's broken + return 96.0f; + } + return float(heightPx/heightInches); +} + nsWindow* nsWindow::GetParentWindow(PRBool aIncludeOwner) { if (mIsTopWidgetWindow) { diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 871a45eadd6..7a252b2b9bf 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -123,6 +123,7 @@ public: NS_IMETHOD Destroy(); NS_IMETHOD SetParent(nsIWidget *aNewParent); virtual nsIWidget* GetParent(void); + virtual float GetDPI(); NS_IMETHOD Show(PRBool bState); NS_IMETHOD IsVisible(PRBool & aState); NS_IMETHOD ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY);