-
Bug
-
Resolution: Unresolved
-
P4
-
8, 11, 16
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Windows 10
JDK 1.8.0_292, JDK 11.0.11, JDK 15.0.2, JDK 16.0.1
Screen Resolution: 4K (250% & 150%), 2K (100%)
A DESCRIPTION OF THE PROBLEM :
A fade in and out animation of anti aliased text is ugly as the text is rendered incorrectly with alpha composite < 1.0
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run sample
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No observable difference when rendering anti aliased text with alpha = 1f and alpha = 0.99f
ACTUAL -
When running the sample you see a significant flickering that should not be observable as we only animate between alpha=1 and alpha = 0.99f.
---------- BEGIN SOURCE ----------
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
public final class AlphaSample {
private static final String TEXT = "abcdefghiklmnopqrwstuvwxyz ABCDEFGHIKLMNOPQRSTUVWXYZ";
public static void main(String[] args) {
JFrame frame = new JFrame("Alpha");
MyComponent component = new MyComponent();
frame.getContentPane().add(component);
frame.setBounds(100, 100, 600, 400);
frame.setVisible(true);
Timer timer = new Timer(100, event -> {
if (component.alpha == 1f) {
component.alpha = 0.99f;
}
else {
component.alpha = 1f;
}
component.repaint();
});
timer.setRepeats(true);
timer.start();
}
private static final class MyComponent extends JComponent {
private float alpha = 1f;
private int y;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle clip = g2.getClipBounds();
g2.setColor(Color.WHITE);
g2.fillRect(clip.x, clip.y, clip.width, clip.height);
y = 0;
draw(g2, new Font(Font.DIALOG, Font.PLAIN, 10));
draw(g2, new Font("Segoe UI", Font.PLAIN, 10));
draw(g2, new Font(Font.DIALOG, Font.PLAIN, 20));
draw(g2, new Font("Segoe UI", Font.PLAIN, 20));
}
private void draw(Graphics2D g2, Font font) {
drawString(g2, font, 1f, false);
drawString(g2, font, 0.99f, false);
drawString(g2, font, alpha, false);
y += 10;
drawString(g2, font, 1f, true);
drawString(g2, font, 0.99f, true);
drawString(g2, font, alpha, true);
y += 20;
}
private void drawString(Graphics2D g2, Font font, float alpha, boolean antiAlias) {
g2.setColor(Color.BLACK);
g2.setFont(font);
y += g2.getFontMetrics().getHeight();
if (antiAlias) {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
}
else {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2.setComposite(alphaComposite);
g2.drawString(TEXT + ", font=" + font.getName() + " " + font.getSize() + ", antiAlias=" + antiAlias + ", alpha=" + alpha, 10, y);
}
}
}
---------- END SOURCE ----------
FREQUENCY : always
Windows 10
JDK 1.8.0_292, JDK 11.0.11, JDK 15.0.2, JDK 16.0.1
Screen Resolution: 4K (250% & 150%), 2K (100%)
A DESCRIPTION OF THE PROBLEM :
A fade in and out animation of anti aliased text is ugly as the text is rendered incorrectly with alpha composite < 1.0
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run sample
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No observable difference when rendering anti aliased text with alpha = 1f and alpha = 0.99f
ACTUAL -
When running the sample you see a significant flickering that should not be observable as we only animate between alpha=1 and alpha = 0.99f.
---------- BEGIN SOURCE ----------
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
public final class AlphaSample {
private static final String TEXT = "abcdefghiklmnopqrwstuvwxyz ABCDEFGHIKLMNOPQRSTUVWXYZ";
public static void main(String[] args) {
JFrame frame = new JFrame("Alpha");
MyComponent component = new MyComponent();
frame.getContentPane().add(component);
frame.setBounds(100, 100, 600, 400);
frame.setVisible(true);
Timer timer = new Timer(100, event -> {
if (component.alpha == 1f) {
component.alpha = 0.99f;
}
else {
component.alpha = 1f;
}
component.repaint();
});
timer.setRepeats(true);
timer.start();
}
private static final class MyComponent extends JComponent {
private float alpha = 1f;
private int y;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle clip = g2.getClipBounds();
g2.setColor(Color.WHITE);
g2.fillRect(clip.x, clip.y, clip.width, clip.height);
y = 0;
draw(g2, new Font(Font.DIALOG, Font.PLAIN, 10));
draw(g2, new Font("Segoe UI", Font.PLAIN, 10));
draw(g2, new Font(Font.DIALOG, Font.PLAIN, 20));
draw(g2, new Font("Segoe UI", Font.PLAIN, 20));
}
private void draw(Graphics2D g2, Font font) {
drawString(g2, font, 1f, false);
drawString(g2, font, 0.99f, false);
drawString(g2, font, alpha, false);
y += 10;
drawString(g2, font, 1f, true);
drawString(g2, font, 0.99f, true);
drawString(g2, font, alpha, true);
y += 20;
}
private void drawString(Graphics2D g2, Font font, float alpha, boolean antiAlias) {
g2.setColor(Color.BLACK);
g2.setFont(font);
y += g2.getFontMetrics().getHeight();
if (antiAlias) {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
}
else {
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2.setComposite(alphaComposite);
g2.drawString(TEXT + ", font=" + font.getName() + " " + font.getSize() + ", antiAlias=" + antiAlias + ", alpha=" + alpha, 10, y);
}
}
}
---------- END SOURCE ----------
FREQUENCY : always