mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-1929 FractionalMetricsSupport
(cherry picked from commit bbdc159762)
This commit is contained in:
committed by
alexey.ushakov@jetbrains.com
parent
8d64b96363
commit
9c0de70fc6
@@ -427,6 +427,7 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
* AA text hints.
|
||||
*/
|
||||
private transient Object aaHint;
|
||||
private transient Object fmHint;
|
||||
private transient Object lcdRenderingHint;
|
||||
|
||||
static {
|
||||
@@ -732,6 +733,8 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
// aaText shouldn't persist between look and feels, reset it.
|
||||
aaHint = UIManager.getDefaults().get(
|
||||
RenderingHints.KEY_TEXT_ANTIALIASING);
|
||||
fmHint = UIManager.getDefaults().get(
|
||||
RenderingHints.KEY_FRACTIONALMETRICS);
|
||||
lcdRenderingHint = UIManager.getDefaults().get(
|
||||
RenderingHints.KEY_TEXT_LCD_CONTRAST);
|
||||
ComponentUI oldUI = ui;
|
||||
@@ -4110,6 +4113,8 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
public final Object getClientProperty(Object key) {
|
||||
if (key == RenderingHints.KEY_TEXT_ANTIALIASING) {
|
||||
return aaHint;
|
||||
} else if (key == RenderingHints.KEY_FRACTIONALMETRICS) {
|
||||
return fmHint;
|
||||
} else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) {
|
||||
return lcdRenderingHint;
|
||||
}
|
||||
@@ -4154,6 +4159,9 @@ public abstract class JComponent extends Container implements Serializable,
|
||||
if (key == RenderingHints.KEY_TEXT_ANTIALIASING) {
|
||||
aaHint = value;
|
||||
return;
|
||||
} else if (key == RenderingHints.KEY_FRACTIONALMETRICS) {
|
||||
fmHint = value;
|
||||
return;
|
||||
} else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) {
|
||||
lcdRenderingHint = value;
|
||||
return;
|
||||
|
||||
@@ -67,6 +67,7 @@ import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedString;
|
||||
import java.text.BreakIterator;
|
||||
import java.text.CharacterIterator;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -102,9 +103,11 @@ import sun.font.FontUtilities;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.print.ProxyPrintGraphics;
|
||||
|
||||
import static java.awt.RenderingHints.KEY_FRACTIONALMETRICS;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
|
||||
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
|
||||
import static java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT;
|
||||
import static java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
|
||||
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
|
||||
@@ -565,25 +568,9 @@ public class SwingUtilities2 {
|
||||
? null
|
||||
: c.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != null) {
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
|
||||
Object lcdContrastHint = c.getClientProperty(
|
||||
KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
lcdContrastHint);
|
||||
}
|
||||
}
|
||||
Object oldAAValue = configureHint(KEY_TEXT_ANTIALIASING, g2, aaHint);
|
||||
Object oldFMValue = configureHint(KEY_FRACTIONALMETRICS, g2, c);
|
||||
Object oldContrast = configureHint(KEY_TEXT_LCD_CONTRAST, g2, c);
|
||||
|
||||
if (needsTextLayout) {
|
||||
TextLayout layout = createTextLayout(c, text, g2.getFont(),
|
||||
@@ -593,12 +580,9 @@ public class SwingUtilities2 {
|
||||
g2.drawString(text, x, y);
|
||||
}
|
||||
|
||||
if (oldAAValue != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
|
||||
}
|
||||
if (oldContrast != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);
|
||||
}
|
||||
restoreHint(KEY_TEXT_ANTIALIASING, g2, oldAAValue);
|
||||
restoreHint(KEY_FRACTIONALMETRICS, g2, oldFMValue);
|
||||
restoreHint(KEY_TEXT_LCD_CONTRAST, g2, oldContrast);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -904,34 +888,15 @@ public class SwingUtilities2 {
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
if (aaHint != null) {
|
||||
|
||||
Object oldContrast = null;
|
||||
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
|
||||
if (aaHint != null && aaHint != oldAAValue) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, aaHint);
|
||||
} else {
|
||||
oldAAValue = null;
|
||||
}
|
||||
|
||||
Object lcdContrastHint = c.getClientProperty(KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint != null) {
|
||||
oldContrast = g2.getRenderingHint(KEY_TEXT_LCD_CONTRAST);
|
||||
if (lcdContrastHint.equals(oldContrast)) {
|
||||
oldContrast = null;
|
||||
} else {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
|
||||
lcdContrastHint);
|
||||
}
|
||||
}
|
||||
Object oldAAValue = configureHint(KEY_TEXT_ANTIALIASING, g2, aaHint);
|
||||
Object oldFMValue = configureHint(KEY_FRACTIONALMETRICS, g2, c);
|
||||
Object oldContrast = configureHint(KEY_TEXT_LCD_CONTRAST, g2, c);
|
||||
|
||||
g2.drawString(new String(data, offset, length), x, y);
|
||||
|
||||
if (oldAAValue != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
|
||||
}
|
||||
if (oldContrast != null) {
|
||||
g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, oldContrast);
|
||||
}
|
||||
restoreHint(KEY_TEXT_ANTIALIASING, g2, oldAAValue);
|
||||
restoreHint(KEY_FRACTIONALMETRICS, g2, oldFMValue);
|
||||
restoreHint(KEY_TEXT_LCD_CONTRAST, g2, oldContrast);
|
||||
}
|
||||
else {
|
||||
g2.drawString(new String(data, offset, length), x, y);
|
||||
@@ -1248,7 +1213,6 @@ public class SwingUtilities2 {
|
||||
*/
|
||||
private static FontRenderContext getFRCProperty(JComponent c) {
|
||||
if (c != null) {
|
||||
|
||||
GraphicsConfiguration gc = c.getGraphicsConfiguration();
|
||||
AffineTransform tx = (gc == null) ? null : gc.getDefaultTransform();
|
||||
// [tav] workaround deadlock on MacOSX until fixed, JRE-226
|
||||
@@ -1260,16 +1224,22 @@ public class SwingUtilities2 {
|
||||
.getDefaultTransform();
|
||||
}
|
||||
Object aaHint = c.getClientProperty(KEY_TEXT_ANTIALIASING);
|
||||
return getFRCFromCache(tx, aaHint);
|
||||
if (aaHint == null) aaHint = VALUE_TEXT_ANTIALIAS_DEFAULT;
|
||||
|
||||
Object fmHint = c.getClientProperty(KEY_FRACTIONALMETRICS);
|
||||
if (fmHint == null) fmHint = VALUE_FRACTIONALMETRICS_DEFAULT;
|
||||
|
||||
return getFRCFromCache(tx, aaHint, fmHint);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Object APP_CONTEXT_FRC_CACHE_KEY = new Object();
|
||||
|
||||
private static FontRenderContext getFRCFromCache(AffineTransform tx,
|
||||
Object aaHint) {
|
||||
if (tx == null && aaHint == null) {
|
||||
private static FontRenderContext getFRCFromCache(AffineTransform tx, Object aaHint, Object fmHint) {
|
||||
if ((tx == null || tx.isIdentity())
|
||||
&& (aaHint == VALUE_TEXT_ANTIALIAS_OFF || aaHint == VALUE_TEXT_ANTIALIAS_DEFAULT)
|
||||
&& (fmHint == VALUE_FRACTIONALMETRICS_OFF || fmHint == VALUE_FRACTIONALMETRICS_DEFAULT)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1283,41 +1253,31 @@ public class SwingUtilities2 {
|
||||
}
|
||||
|
||||
Object key = (tx == null)
|
||||
? aaHint
|
||||
: (aaHint == null ? tx : new KeyPair(tx, aaHint));
|
||||
? new KeyArray(aaHint, fmHint)
|
||||
: new KeyArray(tx, aaHint, fmHint);
|
||||
|
||||
FontRenderContext frc = cache.get(key);
|
||||
if (frc == null) {
|
||||
aaHint = (aaHint == null) ? VALUE_TEXT_ANTIALIAS_OFF : aaHint;
|
||||
frc = new FontRenderContext(tx, aaHint,
|
||||
VALUE_FRACTIONALMETRICS_DEFAULT);
|
||||
cache.put(key, frc);
|
||||
}
|
||||
return frc;
|
||||
return cache.computeIfAbsent(key, k -> new FontRenderContext(tx, aaHint, fmHint));
|
||||
}
|
||||
|
||||
private static class KeyPair {
|
||||
private static class KeyArray {
|
||||
private final Object[] array;
|
||||
|
||||
private final Object key1;
|
||||
private final Object key2;
|
||||
|
||||
public KeyPair(Object key1, Object key2) {
|
||||
this.key1 = key1;
|
||||
this.key2 = key2;
|
||||
KeyArray(Object... array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof KeyPair)) {
|
||||
public boolean equals(Object object) {
|
||||
if (!(object instanceof KeyArray)) {
|
||||
return false;
|
||||
}
|
||||
KeyPair that = (KeyPair) obj;
|
||||
return this.key1.equals(that.key1) && this.key2.equals(that.key2);
|
||||
KeyArray that = (KeyArray) object;
|
||||
return Arrays.equals(that.array, array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key1.hashCode() + 37 * key2.hashCode();
|
||||
return Arrays.hashCode(array);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2345,4 +2305,45 @@ public class SwingUtilities2 {
|
||||
var oldTx = oldGC != null ? oldGC.getDefaultTransform() : null;
|
||||
return !Objects.equals(newTx, oldTx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the key of the hint to be set
|
||||
* @param g the graphics to configure
|
||||
* @param c the component that provides a hint value
|
||||
* @return a value previously set in the given graphics,
|
||||
* or {@code null} if a hint value is not set
|
||||
*/
|
||||
private static Object configureHint(RenderingHints.Key key, Graphics2D g, JComponent c) {
|
||||
if (c == null) return null; // component is not specified
|
||||
|
||||
return configureHint(key, g, c.getClientProperty(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the key of the hint to be set
|
||||
* @param g the graphics to configure
|
||||
* @param newValue the new value to set
|
||||
* @return a value previously set in the given graphics,
|
||||
* or {@code null} if a hint value is not set
|
||||
*/
|
||||
private static Object configureHint(RenderingHints.Key key, Graphics2D g, Object newValue) {
|
||||
if (newValue == null) return null; // new value is not provided
|
||||
|
||||
Object oldValue = g.getRenderingHint(key);
|
||||
if (newValue.equals(oldValue)) return null; // value is not changed
|
||||
|
||||
g.setRenderingHint(key, newValue);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the key of the hint to be set
|
||||
* @param g the graphics to configure
|
||||
* @param oldValue the stored value to set
|
||||
*/
|
||||
private static void restoreHint(RenderingHints.Key key, Graphics2D g, Object oldValue) {
|
||||
if (oldValue == null) return; // nothing to restore
|
||||
|
||||
g.setRenderingHint(key, oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user