When trying to draw a string with alpha composite mode "clear", nothing is drawn (or rather removed), when RenderingHints.KEY_TEXT_ANTIALIASING, is set to RenderingHints.VALUE_TEXT_ANTIALIAS_ON.
Demo code
=========
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class CompositeDemo {
public static void main(final String[] args) {
final ImageIcon imageIconWithAntiAliasing = createIcon(true);
final ImageIcon imageIconWithoutAntiAliasing = createIcon(false);
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(imageIconWithAntiAliasing));
frame.getContentPane().add(new JLabel(imageIconWithoutAntiAliasing));
SwingUtilities.invokeLater(() -> {
frame.setSize(250, 100);
frame.setVisible(true);
});
}
private static ImageIcon createIcon(final boolean textAntiAlias) {
final BufferedImage image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = (Graphics2D)image.getGraphics();
if (textAntiAlias) {
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g.setColor(Color.BLACK);
g.drawRect(0, 0, 99, 49);
g.setColor(Color.RED);
g.fillRect(0, 0, 50, 50);
g.setComposite(AlphaComposite.Clear);
g.setColor(Color.BLUE);
g.drawString("sdfegergerwgrtwgtrw", 0, 25);
return new ImageIcon(image);
}
}
A screenshot is attached. The text should be visible in both labels, but is only visible in the one without text anti-aliasing.
Workaround:
Change the AlphaComposite rule to AlphaComposite.DstOut.
Demo code
=========
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class CompositeDemo {
public static void main(final String[] args) {
final ImageIcon imageIconWithAntiAliasing = createIcon(true);
final ImageIcon imageIconWithoutAntiAliasing = createIcon(false);
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(imageIconWithAntiAliasing));
frame.getContentPane().add(new JLabel(imageIconWithoutAntiAliasing));
SwingUtilities.invokeLater(() -> {
frame.setSize(250, 100);
frame.setVisible(true);
});
}
private static ImageIcon createIcon(final boolean textAntiAlias) {
final BufferedImage image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = (Graphics2D)image.getGraphics();
if (textAntiAlias) {
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g.setColor(Color.BLACK);
g.drawRect(0, 0, 99, 49);
g.setColor(Color.RED);
g.fillRect(0, 0, 50, 50);
g.setComposite(AlphaComposite.Clear);
g.setColor(Color.BLUE);
g.drawString("sdfegergerwgrtwgtrw", 0, 25);
return new ImageIcon(image);
}
}
A screenshot is attached. The text should be visible in both labels, but is only visible in the one without text anti-aliasing.
Workaround:
Change the AlphaComposite rule to AlphaComposite.DstOut.