8294427: Check boxes and radio buttons have rendering issues on Windows in High DPI env
Reviewed-by: aivanov, achung
This commit is contained in:
parent
3df36c4f10
commit
a63afa4aa6
src/java.desktop
share/classes/sun/swing
windows
classes
native/libawt/windows
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2023, 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
|
||||
@ -314,8 +314,9 @@ public abstract class CachedPainter {
|
||||
|
||||
@Override
|
||||
public Image getResolutionVariant(double destWidth, double destHeight) {
|
||||
int w = (int) Math.ceil(destWidth);
|
||||
int h = (int) Math.ceil(destHeight);
|
||||
int w = (int) Math.floor(destWidth + 0.5);
|
||||
int h = (int) Math.floor(destHeight + 0.5);
|
||||
|
||||
return getImage(PainterMultiResolutionCachedImage.class,
|
||||
c, baseWidth, baseHeight, w, h, args);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2023, 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
|
||||
@ -40,10 +40,13 @@
|
||||
|
||||
package com.sun.java.swing.plaf.windows;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.util.EnumMap;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import sun.awt.windows.ThemeReader;
|
||||
|
||||
@ -55,7 +58,7 @@ import sun.awt.windows.ThemeReader;
|
||||
*
|
||||
* @author Leif Samuelsson
|
||||
*/
|
||||
class TMSchema {
|
||||
public final class TMSchema {
|
||||
|
||||
/**
|
||||
* An enumeration of the various Windows controls (also known as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2023, 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
|
||||
@ -40,14 +40,41 @@
|
||||
|
||||
package com.sun.java.swing.plaf.windows;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.security.AccessController;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import sun.awt.image.SunWritableRaster;
|
||||
@ -55,8 +82,10 @@ import sun.awt.windows.ThemeReader;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.swing.CachedPainter;
|
||||
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.*;
|
||||
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.Part;
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.Prop;
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.State;
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.TypeEnum;
|
||||
|
||||
/**
|
||||
* Implements Windows XP Styles for the Windows Look and Feel.
|
||||
@ -675,6 +704,11 @@ class XPStyle {
|
||||
w = bi.getWidth();
|
||||
h = bi.getHeight();
|
||||
|
||||
// Get DPI to pass further to ThemeReader.paintBackground()
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
AffineTransform at = g2d.getTransform();
|
||||
int dpi = (int)(at.getScaleX() * 96);
|
||||
|
||||
WritableRaster raster = bi.getRaster();
|
||||
DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer();
|
||||
// Note that stealData() requires a markDirty() afterwards
|
||||
@ -682,7 +716,8 @@ class XPStyle {
|
||||
ThemeReader.paintBackground(SunWritableRaster.stealData(dbi, 0),
|
||||
part.getControlName(c), part.getValue(),
|
||||
State.getValue(part, state),
|
||||
0, 0, w, h, w);
|
||||
0, 0, w, h, w, dpi);
|
||||
|
||||
SunWritableRaster.markDirty(dbi);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2023, 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
|
||||
@ -30,11 +30,14 @@ import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.Part;
|
||||
|
||||
/**
|
||||
* Implements Theme Support for Windows XP.
|
||||
*
|
||||
@ -44,7 +47,24 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
*/
|
||||
public final class ThemeReader {
|
||||
|
||||
private static final Map<String, Long> widgetToTheme = new HashMap<>();
|
||||
private static final int defaultDPI = 96;
|
||||
|
||||
/**
|
||||
* List of widgets for which we need to get the part size for the current DPI.
|
||||
*/
|
||||
private static final List<String> partSizeWidgets =
|
||||
List.of("MENU", "BUTTON");
|
||||
|
||||
/**
|
||||
* List of widget parts for which we need to get the part size for the current DPI.
|
||||
*/
|
||||
private static final List<Integer> partSizeWidgetParts =
|
||||
List.of(Part.BP_RADIOBUTTON.getValue(),
|
||||
Part.BP_CHECKBOX.getValue(),
|
||||
Part.MP_POPUPCHECK.getValue());
|
||||
|
||||
private static final Map<Integer, Map<String, Long>> dpiAwareWidgetToTheme
|
||||
= new HashMap<>();
|
||||
|
||||
// lock for the cache
|
||||
// reading should be done with readLock
|
||||
@ -80,28 +100,30 @@ public final class ThemeReader {
|
||||
return xpStyleEnabled;
|
||||
}
|
||||
|
||||
private static Long openThemeImpl(String widget, int dpi) {
|
||||
Long theme;
|
||||
int i = widget.indexOf("::");
|
||||
if (i > 0) {
|
||||
// We're using the syntax "subAppName::controlName" here, as used by msstyles.
|
||||
// See documentation for SetWindowTheme on MSDN.
|
||||
setWindowTheme(widget.substring(0, i));
|
||||
theme = openTheme(widget.substring(i + 2), dpi);
|
||||
setWindowTheme(null);
|
||||
} else {
|
||||
theme = openTheme(widget, dpi);
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
|
||||
// this should be called only with writeLock held
|
||||
private static Long getThemeImpl(String widget) {
|
||||
Long theme = widgetToTheme.get(widget);
|
||||
if (theme == null) {
|
||||
int i = widget.indexOf("::");
|
||||
if (i > 0) {
|
||||
// We're using the syntax "subAppName::controlName" here, as used by msstyles.
|
||||
// See documentation for SetWindowTheme on MSDN.
|
||||
setWindowTheme(widget.substring(0, i));
|
||||
theme = openTheme(widget.substring(i+2));
|
||||
setWindowTheme(null);
|
||||
} else {
|
||||
theme = openTheme(widget);
|
||||
}
|
||||
widgetToTheme.put(widget, theme);
|
||||
}
|
||||
return theme;
|
||||
private static Long getThemeImpl(String widget, int dpi) {
|
||||
return dpiAwareWidgetToTheme.computeIfAbsent(dpi, key -> new HashMap<>())
|
||||
.computeIfAbsent(widget, w -> openThemeImpl(widget, dpi));
|
||||
}
|
||||
|
||||
// returns theme value
|
||||
// this method should be invoked with readLock locked
|
||||
private static Long getTheme(String widget) {
|
||||
private static Long getTheme(String widget, int dpi) {
|
||||
if (!isThemed) {
|
||||
throw new IllegalStateException("Themes are not loaded");
|
||||
}
|
||||
@ -111,10 +133,12 @@ public final class ThemeReader {
|
||||
try {
|
||||
if (!valid) {
|
||||
// Close old themes.
|
||||
for (Long value : widgetToTheme.values()) {
|
||||
closeTheme(value);
|
||||
for (Map<String, Long> dpiVal : dpiAwareWidgetToTheme.values()) {
|
||||
for (Long value : dpiVal.values()) {
|
||||
closeTheme(value);
|
||||
}
|
||||
}
|
||||
widgetToTheme.clear();
|
||||
dpiAwareWidgetToTheme.clear();
|
||||
valid = true;
|
||||
}
|
||||
} finally {
|
||||
@ -123,13 +147,20 @@ public final class ThemeReader {
|
||||
}
|
||||
}
|
||||
|
||||
Long theme = null;
|
||||
|
||||
Map<String, Long> widgetToTheme = dpiAwareWidgetToTheme.get(dpi);
|
||||
|
||||
if (widgetToTheme != null) {
|
||||
theme = widgetToTheme.get(widget);
|
||||
}
|
||||
|
||||
// mostly copied from the javadoc for ReentrantReadWriteLock
|
||||
Long theme = widgetToTheme.get(widget);
|
||||
if (theme == null) {
|
||||
readLock.unlock();
|
||||
writeLock.lock();
|
||||
try {
|
||||
theme = getThemeImpl(widget);
|
||||
theme = getThemeImpl(widget, dpi);
|
||||
} finally {
|
||||
readLock.lock();
|
||||
writeLock.unlock();// Unlock write, still hold read
|
||||
@ -139,14 +170,23 @@ public final class ThemeReader {
|
||||
}
|
||||
|
||||
private static native void paintBackground(int[] buffer, long theme,
|
||||
int part, int state, int x,
|
||||
int y, int w, int h, int stride);
|
||||
int part, int state,
|
||||
int rectRight, int rectBottom,
|
||||
int w, int h, int stride);
|
||||
|
||||
public static void paintBackground(int[] buffer, String widget,
|
||||
int part, int state, int x, int y, int w, int h, int stride) {
|
||||
int part, int state, int x, int y, int w, int h, int stride, int dpi) {
|
||||
readLock.lock();
|
||||
try {
|
||||
paintBackground(buffer, getTheme(widget), part, state, x, y, w, h, stride);
|
||||
/* For widgets and parts in the lists, we get the part size
|
||||
for the current screen DPI to scale them better. */
|
||||
Dimension d = (partSizeWidgets.contains(widget)
|
||||
&& partSizeWidgetParts.contains(Integer.valueOf(part)))
|
||||
? getPartSize(getTheme(widget, dpi), part, state)
|
||||
: new Dimension(w, h);
|
||||
|
||||
paintBackground(buffer, getTheme(widget, dpi), part, state,
|
||||
d.width, d.height, w, h, stride);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -158,7 +198,7 @@ public final class ThemeReader {
|
||||
public static Insets getThemeMargins(String widget, int part, int state, int marginType) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getThemeMargins(getTheme(widget), part, state, marginType);
|
||||
return getThemeMargins(getTheme(widget, defaultDPI), part, state, marginType);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -169,7 +209,7 @@ public final class ThemeReader {
|
||||
public static boolean isThemePartDefined(String widget, int part, int state) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return isThemePartDefined(getTheme(widget), part, state);
|
||||
return isThemePartDefined(getTheme(widget, defaultDPI), part, state);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -181,7 +221,7 @@ public final class ThemeReader {
|
||||
public static Color getColor(String widget, int part, int state, int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getColor(getTheme(widget), part, state, property);
|
||||
return getColor(getTheme(widget, defaultDPI), part, state, property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -193,7 +233,7 @@ public final class ThemeReader {
|
||||
public static int getInt(String widget, int part, int state, int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getInt(getTheme(widget), part, state, property);
|
||||
return getInt(getTheme(widget, defaultDPI), part, state, property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -205,7 +245,7 @@ public final class ThemeReader {
|
||||
public static int getEnum(String widget, int part, int state, int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getEnum(getTheme(widget), part, state, property);
|
||||
return getEnum(getTheme(widget, defaultDPI), part, state, property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -218,7 +258,7 @@ public final class ThemeReader {
|
||||
int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getBoolean(getTheme(widget), part, state, property);
|
||||
return getBoolean(getTheme(widget, defaultDPI), part, state, property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -229,7 +269,7 @@ public final class ThemeReader {
|
||||
public static boolean getSysBoolean(String widget, int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getSysBoolean(getTheme(widget), property);
|
||||
return getSysBoolean(getTheme(widget, defaultDPI), property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -241,7 +281,7 @@ public final class ThemeReader {
|
||||
public static Point getPoint(String widget, int part, int state, int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getPoint(getTheme(widget), part, state, property);
|
||||
return getPoint(getTheme(widget, defaultDPI), part, state, property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -254,7 +294,7 @@ public final class ThemeReader {
|
||||
int property) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getPosition(getTheme(widget), part,state,property);
|
||||
return getPosition(getTheme(widget, defaultDPI), part,state,property);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -266,13 +306,13 @@ public final class ThemeReader {
|
||||
public static Dimension getPartSize(String widget, int part, int state) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getPartSize(getTheme(widget), part, state);
|
||||
return getPartSize(getTheme(widget, defaultDPI), part, state);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static native long openTheme(String widget);
|
||||
private static native long openTheme(String widget, int dpi);
|
||||
|
||||
private static native void closeTheme(long theme);
|
||||
|
||||
@ -285,8 +325,9 @@ public final class ThemeReader {
|
||||
int stateFrom, int stateTo, int propId) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getThemeTransitionDuration(getTheme(widget),
|
||||
part, stateFrom, stateTo, propId);
|
||||
return getThemeTransitionDuration(getTheme(widget, defaultDPI),
|
||||
part, stateFrom, stateTo,
|
||||
propId);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
@ -299,8 +340,9 @@ public final class ThemeReader {
|
||||
int part, int state, int boundingWidth, int boundingHeight) {
|
||||
readLock.lock();
|
||||
try {
|
||||
return getThemeBackgroundContentMargins(getTheme(widget),
|
||||
part, state, boundingWidth, boundingHeight);
|
||||
return getThemeBackgroundContentMargins(getTheme(widget, defaultDPI),
|
||||
part, state,
|
||||
boundingWidth, boundingHeight);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
|
||||
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
|
||||
int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
|
||||
|
||||
typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
|
||||
typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
|
||||
|
||||
typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
|
||||
int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,
|
||||
@ -90,7 +90,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
|
||||
(HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
|
||||
int iPropId, DWORD *pdwDuration);
|
||||
|
||||
static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
|
||||
static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
|
||||
static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
|
||||
static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
|
||||
static PFNDRAWTHEMETEXT DrawThemeTextFunc = NULL;
|
||||
@ -116,8 +116,8 @@ BOOL InitThemes() {
|
||||
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
|
||||
if(hModThemes) {
|
||||
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
|
||||
OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
|
||||
"OpenThemeData");
|
||||
OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
|
||||
hModThemes, "OpenThemeDataForDpi");
|
||||
DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
|
||||
hModThemes, "DrawThemeBackground");
|
||||
CloseThemeDataFunc = (PFNCLOSETHEMEDATA)GetProcAddress(
|
||||
@ -152,7 +152,7 @@ BOOL InitThemes() {
|
||||
(PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
|
||||
"GetThemeTransitionDuration");
|
||||
|
||||
if(OpenThemeDataFunc
|
||||
if(OpenThemeDataForDpiFunc
|
||||
&& DrawThemeBackgroundFunc
|
||||
&& CloseThemeDataFunc
|
||||
&& DrawThemeTextFunc
|
||||
@ -171,9 +171,12 @@ BOOL InitThemes() {
|
||||
&& GetThemeTransitionDurationFunc
|
||||
) {
|
||||
DTRACE_PRINTLN("Loaded function pointers.\n");
|
||||
// We need to make sure we can load the Theme. This may not be
|
||||
// the case on a WinXP machine with classic mode enabled.
|
||||
HTHEME hTheme = OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), L"Button");
|
||||
// We need to make sure we can load the Theme.
|
||||
// Use the default DPI value of 96 on windows.
|
||||
constexpr unsigned int defaultDPI = 96;
|
||||
HTHEME hTheme = OpenThemeDataForDpiFunc (
|
||||
AwtToolkit::GetInstance().GetHWnd(),
|
||||
L"Button", defaultDPI);
|
||||
if(hTheme) {
|
||||
DTRACE_PRINTLN("Loaded Theme data.\n");
|
||||
CloseThemeDataFunc(hTheme);
|
||||
@ -236,7 +239,7 @@ static void assert_result(HRESULT hres, JNIEnv *env) {
|
||||
* Signature: (Ljava/lang/String;)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
|
||||
(JNIEnv *env, jclass klass, jstring widget) {
|
||||
(JNIEnv *env, jclass klass, jstring widget, jint dpi) {
|
||||
|
||||
LPCTSTR str = (LPCTSTR) JNU_GetStringPlatformChars(env, widget, NULL);
|
||||
if (str == NULL) {
|
||||
@ -245,7 +248,9 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
|
||||
}
|
||||
// We need to open the Theme on a Window that will stick around.
|
||||
// The best one for that purpose is the Toolkit window.
|
||||
HTHEME htheme = OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
|
||||
HTHEME htheme = OpenThemeDataForDpiFunc(
|
||||
AwtToolkit::GetInstance().GetHWnd(),
|
||||
str, dpi);
|
||||
JNU_ReleaseStringPlatformChars(env, widget, str);
|
||||
return (jlong) htheme;
|
||||
}
|
||||
@ -378,7 +383,7 @@ static void copyDIBToBufferedImage(int *pDstBits, int *pSrcBits,
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
|
||||
(JNIEnv *env, jclass klass, jintArray array, jlong theme, jint part, jint state,
|
||||
jint x, jint y, jint w, jint h, jint stride) {
|
||||
jint rectRight, jint rectBottom, jint w, jint h, jint stride) {
|
||||
|
||||
int *pDstBits=NULL;
|
||||
int *pSrcBits=NULL;
|
||||
@ -424,8 +429,8 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.bottom = h;
|
||||
rect.right = w;
|
||||
rect.bottom = rectBottom;
|
||||
rect.right = rectRight;
|
||||
|
||||
ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
|
||||
|
||||
@ -714,27 +719,6 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rescale(SIZE *size) {
|
||||
static int dpiX = -1;
|
||||
static int dpiY = -1;
|
||||
if (dpiX == -1 || dpiY == -1) {
|
||||
HWND hWnd = ::GetDesktopWindow();
|
||||
HDC hDC = ::GetDC(hWnd);
|
||||
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
::ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_ThemeReader
|
||||
* Method: getPartSize
|
||||
@ -761,7 +745,6 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
|
||||
CHECK_NULL_RETURN(dimMID, NULL);
|
||||
}
|
||||
|
||||
rescale(&size);
|
||||
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
env->ExceptionDescribe();
|
||||
|
Loading…
x
Reference in New Issue
Block a user