mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-28 19:20:33 +00:00
6302464: Allow programmatic enabling of subpixel anti-aliasing in Swing on ANY platform
Reviewed-by: serb, azvegint
This commit is contained in:
parent
49091ccf1d
commit
d14c028db9
@ -991,9 +991,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
|
||||
"Tree.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[]{"ESCAPE", "cancel"}),};
|
||||
|
||||
table.putDefaults(defaults);
|
||||
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(true);
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(true, table);
|
||||
}
|
||||
|
||||
protected void initSystemColorDefaults(final UIDefaults table) {
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
package com.sun.java.swing.plaf.gtk;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.io.File;
|
||||
import java.lang.ref.*;
|
||||
@ -41,6 +40,8 @@ import javax.swing.text.DefaultEditorKit;
|
||||
|
||||
import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
|
||||
import com.sun.java.swing.plaf.gtk.GTKConstants.StateType;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.UNIXToolkit;
|
||||
import sun.awt.OSInfo;
|
||||
@ -61,7 +62,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
|
||||
* We should assume ON - or some variation of ON as no GTK desktop
|
||||
* ships with it OFF.
|
||||
*/
|
||||
static Object aaTextInfo;
|
||||
static Map<Object, Object> aaTextInfo;
|
||||
|
||||
/**
|
||||
* Solaris, or Linux with Sun JDS in a CJK Locale.
|
||||
@ -1337,7 +1338,9 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
|
||||
if (fallbackFont != null) {
|
||||
table.put("TitledBorder.font", fallbackFont);
|
||||
}
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
if (aaTextInfo != null) {
|
||||
table.putAll(aaTextInfo);
|
||||
}
|
||||
}
|
||||
|
||||
protected void initSystemColorDefaults(UIDefaults table) {
|
||||
@ -1477,7 +1480,8 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
|
||||
* XRender.
|
||||
*/
|
||||
gtkAAFontSettingsCond = !isSunCJK && SwingUtilities2.isLocalDisplay();
|
||||
aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(gtkAAFontSettingsCond);
|
||||
aaTextInfo = new HashMap<>(2);
|
||||
SwingUtilities2.putAATextInfo(gtkAAFontSettingsCond, aaTextInfo);
|
||||
}
|
||||
|
||||
static ReferenceQueue<GTKLookAndFeel> queue = new ReferenceQueue<GTKLookAndFeel>();
|
||||
|
||||
@ -39,6 +39,8 @@ import sun.swing.SwingUtilities2;
|
||||
import sun.swing.plaf.synth.SynthIcon;
|
||||
|
||||
import com.sun.java.swing.plaf.gtk.GTKEngine.WidgetType;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -115,10 +117,12 @@ class GTKStyle extends SynthStyle implements GTKConstants {
|
||||
@Override
|
||||
public void installDefaults(SynthContext context) {
|
||||
super.installDefaults(context);
|
||||
if (!context.getRegion().isSubregion()) {
|
||||
context.getComponent().putClientProperty(
|
||||
SwingUtilities2.AA_TEXT_PROPERTY_KEY,
|
||||
GTKLookAndFeel.aaTextInfo);
|
||||
Map<Object, Object> aaTextInfo = GTKLookAndFeel.aaTextInfo;
|
||||
if (aaTextInfo != null && !context.getRegion().isSubregion()) {
|
||||
context.getComponent().putClientProperty(KEY_TEXT_ANTIALIASING,
|
||||
aaTextInfo.get(KEY_TEXT_ANTIALIASING));
|
||||
context.getComponent().putClientProperty(KEY_TEXT_LCD_CONTRAST,
|
||||
aaTextInfo.get(KEY_TEXT_LCD_CONTRAST));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -556,8 +556,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
|
||||
* for both client property and UIDefaults.
|
||||
* Also need to set up listeners for changes in these settings.
|
||||
*/
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(true);
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(true, table);
|
||||
this.aaSettings =
|
||||
new FontDesktopProperty(SunToolkit.DESKTOPFONTHINTS);
|
||||
}
|
||||
@ -2402,9 +2401,8 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
|
||||
}
|
||||
|
||||
protected void updateUI() {
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(true);
|
||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||
defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(true, defaults);
|
||||
super.updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,7 +377,8 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
/**
|
||||
* AA text hints.
|
||||
*/
|
||||
transient private Object aaTextInfo;
|
||||
transient private Object aaHint;
|
||||
transient private Object lcdRenderingHint;
|
||||
|
||||
static Graphics safelyGetGraphics(Component c) {
|
||||
return safelyGetGraphics(c, SwingUtilities.getRoot(c));
|
||||
@ -655,8 +656,10 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
uninstallUIAndProperties();
|
||||
|
||||
// aaText shouldn't persist between look and feels, reset it.
|
||||
aaTextInfo =
|
||||
UIManager.getDefaults().get(SwingUtilities2.AA_TEXT_PROPERTY_KEY);
|
||||
aaHint = UIManager.getDefaults().get(
|
||||
RenderingHints.KEY_TEXT_ANTIALIASING);
|
||||
lcdRenderingHint = UIManager.getDefaults().get(
|
||||
RenderingHints.KEY_TEXT_LCD_CONTRAST);
|
||||
ComponentUI oldUI = ui;
|
||||
ui = newUI;
|
||||
if (ui != null) {
|
||||
@ -4048,8 +4051,10 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
* @see #putClientProperty
|
||||
*/
|
||||
public final Object getClientProperty(Object key) {
|
||||
if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
|
||||
return aaTextInfo;
|
||||
if (key == RenderingHints.KEY_TEXT_ANTIALIASING) {
|
||||
return aaHint;
|
||||
} else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) {
|
||||
return lcdRenderingHint;
|
||||
} else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
|
||||
return ui;
|
||||
}
|
||||
@ -4091,8 +4096,11 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
* @see #addPropertyChangeListener
|
||||
*/
|
||||
public final void putClientProperty(Object key, Object value) {
|
||||
if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
|
||||
aaTextInfo = value;
|
||||
if (key == RenderingHints.KEY_TEXT_ANTIALIASING) {
|
||||
aaHint = value;
|
||||
return;
|
||||
} else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) {
|
||||
lcdRenderingHint = value;
|
||||
return;
|
||||
}
|
||||
if (value == null && clientProperties == null) {
|
||||
|
||||
@ -35,11 +35,11 @@ import javax.swing.event.InternalFrameEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
|
||||
|
||||
import sun.swing.DefaultLookup;
|
||||
|
||||
import static sun.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY;
|
||||
|
||||
/**
|
||||
* The class that manages a basic title bar
|
||||
* <p>
|
||||
@ -217,8 +217,10 @@ public class BasicInternalFrameTitlePane extends JComponent
|
||||
}
|
||||
|
||||
private void updateProperties() {
|
||||
final Object aaTextInfo = frame.getClientProperty(AA_TEXT_PROPERTY_KEY);
|
||||
putClientProperty(AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
putClientProperty(KEY_TEXT_ANTIALIASING,
|
||||
frame.getClientProperty(KEY_TEXT_ANTIALIASING));
|
||||
putClientProperty(KEY_TEXT_LCD_CONTRAST,
|
||||
frame.getClientProperty(KEY_TEXT_LCD_CONTRAST));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1514,8 +1514,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
|
||||
flushUnreferenced(); // Remove old listeners
|
||||
|
||||
boolean lafCond = SwingUtilities2.isLocalDisplay();
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(lafCond);
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(lafCond, table);
|
||||
new AATextListener(this);
|
||||
}
|
||||
|
||||
@ -2204,9 +2203,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
|
||||
}
|
||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||
boolean lafCond = SwingUtilities2.isLocalDisplay();
|
||||
Object aaTextInfo =
|
||||
SwingUtilities2.AATextInfo.getAATextInfo(lafCond);
|
||||
defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(lafCond, defaults);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
|
||||
@ -688,8 +688,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel {
|
||||
|
||||
// enabled antialiasing depending on desktop settings
|
||||
flushUnreferenced();
|
||||
Object aaTextInfo = getAATextInfo();
|
||||
table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(useLAFConditions(), table);
|
||||
new AATextListener(this);
|
||||
|
||||
if (defaultsMap != null) {
|
||||
@ -794,7 +793,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel {
|
||||
*
|
||||
* @return the text antialiasing information associated to the desktop
|
||||
*/
|
||||
private static Object getAATextInfo() {
|
||||
private static boolean useLAFConditions() {
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
String desktop =
|
||||
AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
|
||||
@ -805,10 +804,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel {
|
||||
boolean isGnome = "gnome".equals(desktop);
|
||||
boolean isLocal = SwingUtilities2.isLocalDisplay();
|
||||
|
||||
boolean setAA = isLocal && (!isGnome || !isCjkLocale);
|
||||
|
||||
Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(setAA);
|
||||
return aaTextInfo;
|
||||
return isLocal && (!isGnome || !isCjkLocale);
|
||||
}
|
||||
|
||||
private static ReferenceQueue<LookAndFeel> queue = new ReferenceQueue<LookAndFeel>();
|
||||
@ -844,8 +840,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel {
|
||||
return;
|
||||
}
|
||||
|
||||
Object aaTextInfo = getAATextInfo();
|
||||
defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
|
||||
SwingUtilities2.putAATextInfo(useLAFConditions(), defaults);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
@ -102,14 +102,6 @@ public class SwingUtilities2 {
|
||||
public static final FontRenderContext DEFAULT_FRC =
|
||||
new FontRenderContext(null, false, false);
|
||||
|
||||
/**
|
||||
* A JComponent client property is used to determine text aa settings.
|
||||
* To avoid having this property persist between look and feels changes
|
||||
* the value of the property is set to null in JComponent.setUI
|
||||
*/
|
||||
public static final Object AA_TEXT_PROPERTY_KEY =
|
||||
new StringBuffer("AATextInfoPropertyKey");
|
||||
|
||||
/**
|
||||
* Attribute key for the content elements. If it is set on an element, the
|
||||
* element is considered to be a line break.
|
||||
@ -123,58 +115,23 @@ public class SwingUtilities2 {
|
||||
private static final StringBuilder SKIP_CLICK_COUNT =
|
||||
new StringBuilder("skipClickCount");
|
||||
|
||||
/* Presently this class assumes default fractional metrics.
|
||||
* This may need to change to emulate future platform L&Fs.
|
||||
*/
|
||||
public static class AATextInfo {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void putAATextInfo(boolean lafCondition,
|
||||
Map<Object, Object> map) {
|
||||
SunToolkit.setAAFontSettingsCondition(lafCondition);
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
Object desktopHints = tk.getDesktopProperty(SunToolkit.DESKTOPFONTHINTS);
|
||||
|
||||
private static AATextInfo getAATextInfoFromMap(Map<java.awt.RenderingHints.Key, Object> hints) {
|
||||
|
||||
Object aaHint = hints.get(KEY_TEXT_ANTIALIASING);
|
||||
Object contHint = hints.get(KEY_TEXT_LCD_CONTRAST);
|
||||
|
||||
if (aaHint == null ||
|
||||
aaHint == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aaHint == VALUE_TEXT_ANTIALIAS_DEFAULT) {
|
||||
return null;
|
||||
} else {
|
||||
return new AATextInfo(aaHint, (Integer)contHint);
|
||||
if (desktopHints instanceof Map) {
|
||||
Map<Object, Object> hints = (Map<Object, Object>) desktopHints;
|
||||
Object aaHint = hints.get(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint == null
|
||||
|| aaHint == VALUE_TEXT_ANTIALIAS_OFF
|
||||
|| aaHint == VALUE_TEXT_ANTIALIAS_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static AATextInfo getAATextInfo(boolean lafCondition) {
|
||||
SunToolkit.setAAFontSettingsCondition(lafCondition);
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
Object map = tk.getDesktopProperty(SunToolkit.DESKTOPFONTHINTS);
|
||||
if (map instanceof Map) {
|
||||
return getAATextInfoFromMap((Map<java.awt.RenderingHints.Key, Object>)map);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Object aaHint;
|
||||
Integer lcdContrastHint;
|
||||
FontRenderContext frc;
|
||||
|
||||
/* These are rarely constructed objects, and only when a complete
|
||||
* UI is being updated, so the cost of the tests here is minimal
|
||||
* and saves tests elsewhere.
|
||||
* We test that the values are ones we support/expect.
|
||||
*/
|
||||
public AATextInfo(Object aaHint, Integer lcdContrastHint) {
|
||||
if (aaHint == null) {
|
||||
throw new InternalError("null not allowed here");
|
||||
}
|
||||
if (aaHint == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aaHint == VALUE_TEXT_ANTIALIAS_DEFAULT) {
|
||||
throw new InternalError("AA must be on");
|
||||
}
|
||||
this.aaHint = aaHint;
|
||||
this.lcdContrastHint = lcdContrastHint;
|
||||
this.frc = new FontRenderContext(null, aaHint,
|
||||
VALUE_FRACTIONALMETRICS_DEFAULT);
|
||||
map.put(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
map.put(KEY_TEXT_LCD_CONTRAST, hints.get(KEY_TEXT_LCD_CONTRAST));
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,22 +197,6 @@ public class SwingUtilities2 {
|
||||
// need to gracefully handle null.
|
||||
//
|
||||
|
||||
/**
|
||||
* Returns whether or not text should be drawn antialiased.
|
||||
*
|
||||
* @param c JComponent to test.
|
||||
* @return Whether or not text should be drawn antialiased for the
|
||||
* specified component.
|
||||
*/
|
||||
public static AATextInfo drawTextAntialiased(JComponent c) {
|
||||
if (c != null) {
|
||||
/* a non-null property implies some form of AA requested */
|
||||
return (AATextInfo)c.getClientProperty(AA_TEXT_PROPERTY_KEY);
|
||||
}
|
||||
// No component, assume aa is off
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left side bearing of the first character of string. The
|
||||
* left side bearing is calculated from the passed in
|
||||
@ -530,7 +471,6 @@ public class SwingUtilities2 {
|
||||
|
||||
// If we get here we're not printing
|
||||
if (g instanceof Graphics2D) {
|
||||
AATextInfo info = drawTextAntialiased(c);
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
|
||||
boolean needsTextLayout = ((c != null) &&
|
||||
@ -543,21 +483,25 @@ public class SwingUtilities2 {
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null) {
|
||||
Object aaHint = c.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != null) {
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (info.aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);
|
||||
if (aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
if (info.lcdContrastHint != null) {
|
||||
|
||||
Object lcdContrastHint = c.getClientProperty(
|
||||
KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (info.lcdContrastHint.equals(oldContrast)) {
|
||||
if (lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
info.lcdContrastHint);
|
||||
lcdContrastHint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,24 +765,26 @@ public class SwingUtilities2 {
|
||||
}
|
||||
// Assume we're not printing if we get here, or that we are invoked
|
||||
// via Swing text printing which is laid out for the printer.
|
||||
AATextInfo info = drawTextAntialiased(c);
|
||||
if (info != null && (g instanceof Graphics2D)) {
|
||||
Object aaHint = c.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != null && (g instanceof Graphics2D)) {
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (info.aaHint != null && info.aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, info.aaHint);
|
||||
if (aaHint != null && aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
if (info.lcdContrastHint != null) {
|
||||
|
||||
Object lcdContrastHint = c.getClientProperty(KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (info.lcdContrastHint.equals(oldContrast)) {
|
||||
if (lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
info.lcdContrastHint);
|
||||
lcdContrastHint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1117,15 +1063,35 @@ public class SwingUtilities2 {
|
||||
*/
|
||||
private static FontRenderContext getFRCProperty(JComponent c) {
|
||||
if (c != null) {
|
||||
AATextInfo info =
|
||||
(AATextInfo)c.getClientProperty(AA_TEXT_PROPERTY_KEY);
|
||||
if (info != null) {
|
||||
return info.frc;
|
||||
Object aaHint = c.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != null) {
|
||||
return getFRCFromCache(aaHint);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Object APP_CONTEXT_FRC_CACHE_KEY = new Object();
|
||||
|
||||
private static FontRenderContext getFRCFromCache(Object aaHint) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Object, FontRenderContext> cache = (Map<Object, FontRenderContext>)
|
||||
AppContext.getAppContext().get(APP_CONTEXT_FRC_CACHE_KEY);
|
||||
|
||||
if (cache == null) {
|
||||
cache = new HashMap<>();
|
||||
AppContext.getAppContext().put(APP_CONTEXT_FRC_CACHE_KEY, cache);
|
||||
}
|
||||
|
||||
FontRenderContext frc = cache.get(aaHint);
|
||||
if (frc == null) {
|
||||
frc = new FontRenderContext(null, aaHint,
|
||||
VALUE_FRACTIONALMETRICS_DEFAULT);
|
||||
cache.put(aaHint, frc);
|
||||
}
|
||||
return frc;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if the Graphics is print Graphics
|
||||
* false otherwise
|
||||
|
||||
283
jdk/test/javax/swing/UIDefaults/6302464/bug6302464.java
Normal file
283
jdk/test/javax/swing/UIDefaults/6302464/bug6302464.java
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 java.util.Map;
|
||||
import java.util.HashSet;
|
||||
import java.awt.Color;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_GASP;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6302464
|
||||
* @author Alexandr Scherbatiy
|
||||
* @summary Allow programmatic enabling of subpixel anti-aliasing in Swing
|
||||
*/
|
||||
public class bug6302464 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SwingUtilities.invokeAndWait(bug6302464::testAntialiasingProperties);
|
||||
}
|
||||
|
||||
private static void testAntialiasingProperties() {
|
||||
testCustomLAF();
|
||||
testFontRenderingContext();
|
||||
testAntialiasingHints();
|
||||
testLAFAAHints();
|
||||
}
|
||||
|
||||
private static void testCustomLAF() {
|
||||
try {
|
||||
testCustomLAF(false);
|
||||
testCustomLAF(true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCustomLAF(boolean useAAHints) throws Exception {
|
||||
CustomLookAndFeel customLAF = new CustomLookAndFeel(useAAHints);
|
||||
UIManager.setLookAndFeel(customLAF);
|
||||
|
||||
JLabel label = new JLabel();
|
||||
Object aaHint = label.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
Object lcdContrastHint = label.getClientProperty(KEY_TEXT_LCD_CONTRAST);
|
||||
|
||||
if (aaHint != customLAF.getAAHint()) {
|
||||
throw new RuntimeException("AA hint from custom L&F is not set");
|
||||
}
|
||||
|
||||
if (lcdContrastHint != customLAF.getLCDContarstHint()) {
|
||||
throw new RuntimeException("AA hint from custom L&F is not set");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Object[] ANTIALIASING_HINTS = {
|
||||
VALUE_TEXT_ANTIALIAS_GASP,
|
||||
VALUE_TEXT_ANTIALIAS_LCD_HRGB,
|
||||
VALUE_TEXT_ANTIALIAS_LCD_HBGR,
|
||||
VALUE_TEXT_ANTIALIAS_LCD_VRGB,
|
||||
VALUE_TEXT_ANTIALIAS_LCD_VBGR
|
||||
};
|
||||
|
||||
private static void testFontRenderingContext() {
|
||||
for (Object aaHint : ANTIALIASING_HINTS) {
|
||||
testFontRenderingContext(aaHint);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testFontRenderingContext(Object aaHint) {
|
||||
|
||||
JLabel label = new JLabel("Test");
|
||||
label.putClientProperty(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
FontRenderContext frc = label.getFontMetrics(
|
||||
label.getFont()).getFontRenderContext();
|
||||
|
||||
if (!aaHint.equals(frc.getAntiAliasingHint())) {
|
||||
throw new RuntimeException("Wrong aa hint in FontRenderContext");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAntialiasingHints() {
|
||||
setMetalLookAndFeel();
|
||||
|
||||
HashSet colorsAAOff = getAntialiasedColors(VALUE_TEXT_ANTIALIAS_OFF, 100);
|
||||
|
||||
if (colorsAAOff.size() > 2) {
|
||||
throw new RuntimeException("Wrong number of antialiased colors.");
|
||||
}
|
||||
|
||||
HashSet colorsAAOnLCD100 = getAntialiasedColors(
|
||||
VALUE_TEXT_ANTIALIAS_LCD_HRGB, 100);
|
||||
|
||||
if (colorsAAOnLCD100.size() <= 2) {
|
||||
throw new RuntimeException("Wrong number of antialiased colors.");
|
||||
}
|
||||
|
||||
HashSet colorsAAOnLCD250 = getAntialiasedColors(
|
||||
VALUE_TEXT_ANTIALIAS_LCD_HRGB, 250);
|
||||
|
||||
if (colorsAAOnLCD250.size() <= 2) {
|
||||
throw new RuntimeException("Wrong number of antialiased colors.");
|
||||
}
|
||||
|
||||
if (colorsAAOnLCD100.equals(colorsAAOnLCD250)) {
|
||||
throw new RuntimeException("LCD contarst is not used.");
|
||||
}
|
||||
}
|
||||
|
||||
private static HashSet getAntialiasedColors(Object aaHint, int lcdContrast) {
|
||||
|
||||
JLabel label = new JLabel("ABCD");
|
||||
label.setSize(label.getPreferredSize());
|
||||
label.putClientProperty(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
label.putClientProperty(KEY_TEXT_LCD_CONTRAST, lcdContrast);
|
||||
|
||||
int w = label.getWidth();
|
||||
int h = label.getHeight();
|
||||
|
||||
BufferedImage buffImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = buffImage.createGraphics();
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, w, h);
|
||||
label.paint(g);
|
||||
g.dispose();
|
||||
|
||||
HashSet<Color> colors = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < w; i++) {
|
||||
for (int j = 0; j < h; j++) {
|
||||
Color color = new Color(buffImage.getRGB(i, j));
|
||||
colors.add(color);
|
||||
}
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
private static void setMetalLookAndFeel() {
|
||||
setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
|
||||
}
|
||||
|
||||
private static void setLookAndFeel(String lafClass) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(lafClass);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testLAFAAHints() {
|
||||
|
||||
for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
|
||||
testLAFAAHints(lafInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] EXCLUDED_LAFS = {"CDE/Motif"};
|
||||
|
||||
private static boolean isExcludedLAF(LookAndFeelInfo lafInfo) {
|
||||
for (String excludedLaf : EXCLUDED_LAFS) {
|
||||
if (lafInfo.getName().equals(excludedLaf)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void testLAFAAHints(LookAndFeelInfo lafInfo) {
|
||||
setLookAndFeel(lafInfo.getClassName());
|
||||
|
||||
Object uiAAHint = UIManager.getDefaults().get(KEY_TEXT_ANTIALIASING);
|
||||
Object uiLCDContrastHint = UIManager.getDefaults().get(
|
||||
KEY_TEXT_LCD_CONTRAST);
|
||||
|
||||
Object aaHints = Toolkit.getDefaultToolkit().
|
||||
getDesktopProperty("awt.font.desktophints");
|
||||
|
||||
if (isExcludedLAF(lafInfo)) {
|
||||
if (uiAAHint != null || uiLCDContrastHint != null) {
|
||||
throw new RuntimeException("Rendering hints set for excluded L&F");
|
||||
}
|
||||
} else if (aaHints instanceof Map) {
|
||||
Map map = (Map) aaHints;
|
||||
|
||||
if (uiAAHint != map.get(KEY_TEXT_ANTIALIASING)) {
|
||||
throw new RuntimeException("UI defaults contains wrong aa hint");
|
||||
}
|
||||
|
||||
if (uiLCDContrastHint != map.get(KEY_TEXT_LCD_CONTRAST)) {
|
||||
throw new RuntimeException("UI defaults contains wrong"
|
||||
+ "lcd contrast hint");
|
||||
}
|
||||
} else if (uiAAHint != null || uiLCDContrastHint != null) {
|
||||
throw new RuntimeException("Rendering hints set for empty desktop"
|
||||
+ "properties");
|
||||
}
|
||||
}
|
||||
|
||||
private static class CustomLookAndFeel extends BasicLookAndFeel {
|
||||
|
||||
private final boolean useAAHints;
|
||||
|
||||
public CustomLookAndFeel(boolean useAAHints) {
|
||||
this.useAAHints = useAAHints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Custom L&F";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativeLookAndFeel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLookAndFeel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initClassDefaults(UIDefaults table) {
|
||||
super.initClassDefaults(table);
|
||||
table.put(KEY_TEXT_ANTIALIASING, getAAHint());
|
||||
table.put(KEY_TEXT_LCD_CONTRAST, getLCDContarstHint());
|
||||
}
|
||||
|
||||
private Object getAAHint() {
|
||||
return useAAHints ? VALUE_TEXT_ANTIALIAS_GASP : null;
|
||||
}
|
||||
|
||||
private Object getLCDContarstHint() {
|
||||
return useAAHints ? 115 : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user