4

I’ve been asked to look up the knobs in Swing to make text as legible as possible for reading. Is there any way to enable subpixel text antialiasing in a Swing application on Java 1.7+ on OS X? Are there any other settings in Java for making text readable?

Observations:

  • On Java 1.7 on OS X, no matter what I do, all text is gray.
  • Even when subpixel rendering doesn’t work, RenderingHints.VALUE_TEXT_ANTIALIAS_ON is darker than RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB. Why?
  • By default, a JComponent on the Mac is rendered with RenderingHints.VALUE_TEXT_ANTIALIAS_ON (dark gray antialiasing).
  • On Java 1.6, -Dapple.awt.graphics.UseQuartz=true does enable LCD antialiasing, but that setting has no effect on Oracle Java 1.7.
  • On Linux, all subpixel antialias hints work properly, and a JComponent uses HRGB antialiasing by default.

Antialiasing Same screenshot at 300%

Here’s the code I used:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;

import sun.swing.SwingUtilities2;


public class TextAntialiasDemo {
    public static JLabel createJlabel(String name, final Object textAntialiasing) {
        JLabel label = new JLabel("ABCDEabcde text_antialiasing=" + name) {
            private static final long serialVersionUID = 1L;
            @Override public void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D)g.create();
                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialiasing);
                super.paintComponent(g2);
            }
        };

        // Tell the JComponent to use the Graphics2d's text rendering hint
        // instead of the Toolkit default.
        label.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, null);
        // To make all new JComponents use Graphics2d's rendering hint, do this:
        // UIManager.getDefaults().remove(SwingUtilities2.AA_TEXT_PROPERTY_KEY);

        return label;
    }
    public static void main(String[] argv) {
        System.out.format("Look and feel: %s%n", UIManager.getLookAndFeel());
        JFrame jframe = new JFrame();
        if (argv.length > 0)
            jframe.setTitle(argv[0]);
        jframe.getContentPane().setLayout(new BoxLayout(jframe.getContentPane(), BoxLayout.PAGE_AXIS));
        jframe.add(new JLabel("ABCDEabcde"));
        jframe.add(createJlabel("default", RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT));
        jframe.add(createJlabel("off", RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
        jframe.add(createJlabel("on", RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
        jframe.add(createJlabel("LCD_VRGB", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB));
        jframe.add(createJlabel("LCD_VBGR", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR));
        jframe.add(createJlabel("LCD_HBGR", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR));
        jframe.add(createJlabel("LCD_HRGB", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB));
        jframe.pack();
        jframe.setVisible(true);
    }
}
yonran
  • 18,156
  • 8
  • 72
  • 97
  • 1
    Have you tried `RenderingHints.KEY_FRACTIONALMETRICS`? – Shrike Jun 19 '13 at 17:39
  • You’re right @Shrike, when I set fractionalmetrics=on and set text antialiasing=HRGB, it does render with LCD antialiasing. It seems to put a dot under some letters randomly though [Screenshot](http://i.stack.imgur.com/oCGe7.png). – yonran Jun 19 '13 at 18:04
  • Those dots seem to be a symptom of using the wrong sub-pixel model. Unfortunately, a lot of things with regard to painting and drawing vary in subtle and undocumented ways between implementations of the JVM on multiple platforms, and so you'll rarely get things to look *exactly* the same across operating systems. – Shrike Jun 19 '13 at 18:31
  • Another interesting note: In all other text on OS X, the left side of a glyph stem is dark red while the right side is dark blue. But with fractionalmetrics on, it uses bright red/cyan and bright yellow/blue which is more noticeable. – yonran Jun 19 '13 at 20:00

1 Answers1

1

Proper subpixel AA font rendering is now available for OSX in OpenJDK 9 b70: https://jdk9.java.net/download/. It's not available if your surfaces are translucent though. I've written up on how to enable that, eg. for use with netbeans on my blog; http://www.nothome.com/2015/07/subpixel-font-rendering-with-netbeans.html or simply build and patch using:

hg clone http://hg.openjdk.java.net/jdk9/jdk9 jdk9
cd ./jdk9
bash ./get_source.sh 
cd jdk
curl http://cr.openjdk.java.net/~bae/8087201/9/webrev.00/jdk.patch | patch --dry-run -p1
curl https://gist.githubusercontent.com/iampivot/5677ccc024afe115d4bc/raw/f7b9acb1c6f356efa26f5772075a32dc899cd8ab/gistfile1.txt | patch -p0 
cd ..
sh ./configure --disable-warnings-as-errors
make all
Thor
  • 737
  • 7
  • 15