# HG changeset patch # User alexsch # Date 1458058616 25200 # Node ID 1d4e5373786931625cb1e4ac22f52e6c375f64a2 # Parent 0256b6d86efb48f76674216b06f4c42c1561d13e 8076545: Text size is twice bigger under Windows L&F on Win 8.1 with HiDPI display 8149453: [hidpi] JFileChooser does not scale properly on Windows with HiDPI display and Windows L&F 8149368: [hidpi] JLabel font is twice bigger than JTextArea font on Windows 7,HiDPI, Windows L&F Reviewed-by: flar, serb diff -r 0256b6d86efb -r 1d4e53737869 jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Tue Mar 15 09:22:48 2016 +0300 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Tue Mar 15 09:16:56 2016 -0700 @@ -31,6 +31,8 @@ #include "awt_Object.h" #include "awt_Component.h" +#include "math.h" + // Important note about VC6 and VC7 (or XP Platform SDK) ! // // These type definitions have been imported from UxTheme.h @@ -745,6 +747,23 @@ return NULL; } +void rescale(SIZE *size) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX); + int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY); + + if (dpiX !=0 && dpiX != 96) { + float invScaleX = 96.0f / dpiX; + size->cx = (int)round(size->cx * invScaleX); + } + if (dpiY != 0 && dpiY != 96) { + float invScaleY = 96.0f / dpiY; + size->cy = (int)round(size->cy * invScaleY); + } + ::ReleaseDC(hWnd, hDC); +} + /* * Class: sun_awt_windows_ThemeReader * Method: getPartSize @@ -770,6 +789,8 @@ dimMID = env->GetMethodID(dimClassID, "", "(II)V"); CHECK_NULL_RETURN(dimMID, NULL); } + + rescale(&size); jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); diff -r 0256b6d86efb -r 1d4e53737869 jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Tue Mar 15 09:22:48 2016 +0300 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Tue Mar 15 09:16:56 2016 -0700 @@ -35,6 +35,8 @@ #include #include +#include "math.h" + // WDesktopProperties fields jfieldID AwtDesktopProperties::pDataID = 0; jmethodID AwtDesktopProperties::setBooleanPropertyID = 0; @@ -79,18 +81,35 @@ } } +void getInvScale(float &invScaleX, float &invScaleY) { + HWND hWnd = ::GetDesktopWindow(); + HDC hDC = ::GetDC(hWnd); + int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX); + int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY); + ::ReleaseDC(hWnd, hDC); + invScaleX = (dpiX == 0.0f) ? 1.0f : 96.0f / dpiX; + invScaleY = (dpiY == 0.0f) ? 1.0f : 96.0f / dpiY; +} + +int rescale(int value, float invScale){ + return invScale == 1.0f ? value : (int)round(value * invScale); +} + void AwtDesktopProperties::GetSystemProperties() { HDC dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if (dc != NULL) { try { - SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font")); - SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font")); - SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font")); - SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font")); - SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font")); - SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font")); - SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font")); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font"), 1.0f); + SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font"), 1.0f); + SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font"), 1.0f); + SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font"), invScaleY); + SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font"), 1.0f); + SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font"), 1.0f); + SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font"), 1.0f); } catch (std::bad_alloc&) { DeleteDC(dc); @@ -266,31 +285,35 @@ } VERIFY( SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncmetrics.cbSize, &ncmetrics, FALSE) ); - SetFontProperty( TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont ); - SetIntegerProperty( TEXT("win.frame.captionHeight"), ncmetrics.iCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.captionButtonWidth"), ncmetrics.iCaptionWidth ); - SetIntegerProperty( TEXT("win.frame.captionButtonHeight"), ncmetrics.iCaptionHeight ); - SetFontProperty( TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont ); - SetIntegerProperty( TEXT("win.frame.smallCaptionHeight"), ncmetrics.iSmCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.smallCaptionButtonWidth"), ncmetrics.iSmCaptionWidth ); - SetIntegerProperty( TEXT("win.frame.smallCaptionButtonHeight"), ncmetrics.iSmCaptionHeight ); - SetIntegerProperty( TEXT("win.frame.sizingBorderWidth"), ncmetrics.iBorderWidth ); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + + SetFontProperty(TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont, invScaleY); + SetIntegerProperty(TEXT("win.frame.captionHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.captionButtonWidth"), rescale(ncmetrics.iCaptionWidth, invScaleX)); + SetIntegerProperty(TEXT("win.frame.captionButtonHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY)); + SetFontProperty(TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont, invScaleY); + SetIntegerProperty(TEXT("win.frame.smallCaptionHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.smallCaptionButtonWidth"), rescale(ncmetrics.iSmCaptionWidth, invScaleX)); + SetIntegerProperty(TEXT("win.frame.smallCaptionButtonHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY)); + SetIntegerProperty(TEXT("win.frame.sizingBorderWidth"), rescale(ncmetrics.iBorderWidth, invScaleX)); // menu properties - SetFontProperty( TEXT("win.menu.font"), ncmetrics.lfMenuFont ); - SetIntegerProperty( TEXT("win.menu.height"), ncmetrics.iMenuHeight ); - SetIntegerProperty( TEXT("win.menu.buttonWidth"), ncmetrics.iMenuWidth ); + SetFontProperty(TEXT("win.menu.font"), ncmetrics.lfMenuFont, invScaleY); + SetIntegerProperty(TEXT("win.menu.height"), rescale(ncmetrics.iMenuHeight, invScaleY)); + SetIntegerProperty(TEXT("win.menu.buttonWidth"), rescale(ncmetrics.iMenuWidth, invScaleX)); // scrollbar properties - SetIntegerProperty( TEXT("win.scrollbar.width"), ncmetrics.iScrollWidth ); - SetIntegerProperty( TEXT("win.scrollbar.height"), ncmetrics.iScrollHeight ); + SetIntegerProperty(TEXT("win.scrollbar.width"), rescale(ncmetrics.iScrollWidth, invScaleX)); + SetIntegerProperty(TEXT("win.scrollbar.height"), rescale(ncmetrics.iScrollHeight, invScaleY)); // status bar and tooltip properties - SetFontProperty( TEXT("win.status.font"), ncmetrics.lfStatusFont ); - SetFontProperty( TEXT("win.tooltip.font"), ncmetrics.lfStatusFont ); + SetFontProperty(TEXT("win.status.font"), ncmetrics.lfStatusFont, invScaleY); + SetFontProperty(TEXT("win.tooltip.font"), ncmetrics.lfStatusFont, invScaleY); // message box properties - SetFontProperty( TEXT("win.messagebox.font"), ncmetrics.lfMessageFont ); + SetFontProperty(TEXT("win.messagebox.font"), ncmetrics.lfMessageFont, invScaleY); } void AwtDesktopProperties::GetIconParameters() { @@ -302,10 +325,13 @@ iconmetrics.cbSize = sizeof(iconmetrics); VERIFY( SystemParametersInfo(SPI_GETICONMETRICS, iconmetrics.cbSize, &iconmetrics, FALSE) ); - SetIntegerProperty(TEXT("win.icon.hspacing"), iconmetrics.iHorzSpacing); - SetIntegerProperty(TEXT("win.icon.vspacing"), iconmetrics.iVertSpacing); + float invScaleX; + float invScaleY; + getInvScale(invScaleX, invScaleY); + SetIntegerProperty(TEXT("win.icon.hspacing"), rescale(iconmetrics.iHorzSpacing, invScaleX)); + SetIntegerProperty(TEXT("win.icon.vspacing"), rescale(iconmetrics.iVertSpacing, invScaleY)); SetBooleanProperty(TEXT("win.icon.titleWrappingOn"), iconmetrics.iTitleWrap != 0); - SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont); + SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont, invScaleY); } /* Windows settings for these are also in the registry @@ -718,6 +744,7 @@ } void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) { + jstring key = JNU_NewStringPlatform(GetEnv(), propName); if (key == NULL) { throw std::bad_alloc(); @@ -752,8 +779,8 @@ } void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, - LPCTSTR propName) { - HGDIOBJ font = GetStockObject(fontID); + LPCTSTR propName, float invScale) { + HGDIOBJ font = GetStockObject(fontID); if (font != NULL && SelectObject(dc, font) != NULL) { int length = GetTextFace(dc, 0, NULL); @@ -789,8 +816,8 @@ throw std::bad_alloc(); } - jint pointSize = metrics.tmHeight - - metrics.tmInternalLeading; + jint pointSize = rescale(metrics.tmHeight - + metrics.tmInternalLeading, invScale); jint style = java_awt_Font_PLAIN; if (metrics.tmWeight >= FW_BOLD) { @@ -818,7 +845,8 @@ } } -void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font) { +void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font, + float invScale) { jstring fontName; jint pointSize; jint style; @@ -836,7 +864,7 @@ ReleaseDC(NULL, hdc); #endif // Java uses point sizes, but assumes 1 pixel = 1 point - pointSize = -font.lfHeight; + pointSize = rescale(-font.lfHeight, invScale); // convert Windows font style to Java style style = java_awt_Font_PLAIN; diff -r 0256b6d86efb -r 1d4e53737869 jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h Tue Mar 15 09:22:48 2016 +0300 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h Tue Mar 15 09:16:56 2016 -0700 @@ -73,8 +73,8 @@ void SetIntegerProperty(LPCTSTR, int); void SetStringProperty(LPCTSTR, LPTSTR); void SetColorProperty(LPCTSTR, DWORD); - void SetFontProperty(HDC, int, LPCTSTR); - void SetFontProperty(LPCTSTR, const LOGFONT &); + void SetFontProperty(HDC, int, LPCTSTR, float invScale); + void SetFontProperty(LPCTSTR, const LOGFONT &, float invScale); void SetSoundProperty(LPCTSTR, LPCTSTR); JNIEnv * GetEnv() { diff -r 0256b6d86efb -r 1d4e53737869 jdk/test/java/awt/font/FontScaling/FontScalingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/font/FontScaling/FontScalingTest.java Tue Mar 15 09:16:56 2016 -0700 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.metal.MetalLookAndFeel; + +/* + * @test + * @bug 8076545 + * @summary Text size is twice bigger under Windows L&F on Win 8.1 with + * HiDPI display + */ +public class FontScalingTest { + + public static void main(String[] args) throws Exception { + int metalFontSize = getFontSize(MetalLookAndFeel.class.getName()); + int systemFontSize = getFontSize(UIManager.getSystemLookAndFeelClassName()); + + if (Math.abs(systemFontSize - metalFontSize) > 8) { + throw new RuntimeException("System L&F is too big!"); + } + } + + private static int getFontSize(String laf) throws Exception { + + UIManager.setLookAndFeel(laf); + final int[] sizes = new int[1]; + + SwingUtilities.invokeAndWait(() -> { + JButton button = new JButton("Test"); + sizes[0] = button.getFont().getSize(); + }); + + return sizes[0]; + } +} \ No newline at end of file