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
This commit is contained in:
parent
1948e2f95f
commit
b6e44767c0
@ -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 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition
|
||||
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 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
|
||||
dimMID = env->GetMethodID(dimClassID, "<init>", "(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();
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "math.h"
|
||||
|
||||
// WDesktopProperties fields
|
||||
jfieldID AwtDesktopProperties::pDataID = 0;
|
||||
jmethodID AwtDesktopProperties::setBooleanPropertyID = 0;
|
||||
@ -79,18 +81,35 @@ void AwtDesktopProperties::GetWindowsParameters() {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void AwtDesktopProperties::GetNonClientParameters() {
|
||||
}
|
||||
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 @@ void AwtDesktopProperties::GetIconParameters() {
|
||||
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::SetStringProperty(LPCTSTR propName, LPTSTR value) {
|
||||
}
|
||||
|
||||
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::SetColorProperty(LPCTSTR propName, DWORD value) {
|
||||
}
|
||||
|
||||
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 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
|
||||
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(HDC dc, int fontID,
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
|
||||
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;
|
||||
|
@ -73,8 +73,8 @@ class AwtDesktopProperties {
|
||||
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() {
|
||||
|
58
jdk/test/java/awt/font/FontScaling/FontScalingTest.java
Normal file
58
jdk/test/java/awt/font/FontScaling/FontScalingTest.java
Normal file
@ -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];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user