Native text rendering in Swing applications

November 21st, 2007

Yesterday i posted six screenshots divided in two groups and asked what is the difference. Most of the comments rightfully pointed out that the font rendering is different, and that the second group looks better in this area.

First, here is a screenshot that summarizes the difference in font rendering in those screenshots (the source code for this application is here, read the technical instructions below on how to run it):

The not-so-gentle hint in the frame title bears congratulations to Eugene Ryzhikov that said that the font rendering in the second group is “just like on Vista”. The first and third rows in the screenshot above are rendered by SWT (and hence by the OS), while the second and fourth rows are rendered byAWT / Java2D (applying the rendering hints as instructed by Chet Haase). The difference has been pointed out and discussed about eight months ago on this JavaLobby thread, but this specific screenshot doesn’t really do native rendering the justice it deserves.

First, note the stroke weights – SWT / native rendering is consistently heavier than in AWT / Java2D one. This puts less strain on the eyes in the long run. Second, pay close attention to the small letters ‘a’, ‘e’, ‘s’, pretty much all the digits and the symbol ‘@’. Java2D rendering is missing an entire pixel! And this specific screenshot is not even a good representation of a “real” UI, since it falsely skews the letter frequency and doesn’t show actual words.

Much can be said about statistics and how they can be bent both ways, but suffice it to say that, combined together, letters ‘a’, ‘e’ and ‘s’ account for more than 26% of an average English text. This means that on average, a Swing UI running on Vista and using the default Vista font (Segoe UI) has a lot of unnecessary inter-letter white space, which makes the texts less readable; the extra white space might cause the eye to perceive word boundaries where there are none. Combine that with lighter strokes and there – you have the reason why the WindowsLookAndFeel in Mustang under Vista still uses Tahoma for all the controls except menus. So much for the platform fidelity…

This issue has been on my mind ever since this comment by Karsten Lentzsch; i even had a chance to ask the Swing Java2D team about this during the Desktop Matters conference held on the next day of Karsten’s comment. Why not use SWT text rendering in Swing applications? Since the main strength of SWT is the native rendering (not only for texts), we will have the operating system rendering our strings, bringing the absolute fidelity in text rendering. And this is what is provided by the Bramble plugin for the latest 4.2dev drop of Substance look and feel (code-named Memphis).

Once you have the Bramble plugin in your classpath, along with the matching SWT jar and native library (see below for more technical details), Substance will automatically switch to native text rendering, turning this

into this

The actual implementation is a little bit more complicated than i originally thought. This is mainly due to the fact that in SWT you can’t paint anti-aliased text on a transparent background, like you can in Swing. See this discussion on the platform-swt-dev mailing list and this discussion on the eclipse.swt.forum for the reasons why. I’ll blog about this limitation and a few other differences between SWT and AWT text rendering later; in the meantime you can see the current implementation for more details.
Currently, the following components should have support for native text rendering:

  • JButton and JToggleButton
  • JRadioButton and JCheckBox
  • JLabel including the default cell renderers for JTree, JTable, JList and JComboBox
  • JTextField with simple view
  • JTabbedPane
  • Decorated title panes of JFrame and JDialog
  • JMenu and JMenuItem
  • JCheckBoxMenuItem and JRadioButtonMenuItem. Currently, the checkmarks are not shown (will be addressed)
  • Components from the Flamingo component suite such as JCommandButton, JToggleCommandButton and JRibbon.

The implementation requires JDK 5.0 to run, and has been successfully tested under Windows Vista (where it makes the biggest impact). In addition, it successfully runs under Windows 2003 and should also run under Windows XP. Since there are no Windows-specific classes used in the Bramble text painter, it should also run under other OSes, such as Mac OS X and Ubuntu (pretty much everywhere SWT is supported).

To give your application a ride, you need to do the following:

  • Download the substance-bramble.jar here and add it to the classpath of your application.
  • Add the org.eclipse.swt.win32 jar to the classpath of your application. Bramble distribution bundles this jar from Eclipse 3.2.1 in the ‘lib’ folder.
  • Extract the matching swt-win32.dll and add it to the java.library.path of your runtime configuration. Bramble distribution bundles this DLL from Eclipse 3.2.1 in the ‘lib’ folder.
  • Configure your application to run under the latest 4.2dev drop of Substance look and feel.

The next steps are:

  • Provide full support for all core Swing components, with possible exclusion of non-plain text components, such as HTML rendering
  • Provide full support for all SwingX components
  • Test and verify under Ubuntu 7.10
  • Extend the current Windows font policy to use Segoe UI font under JDK 5.0 running on Vista
  • Provide support for WebStart environment
  • Provide support for the NetBeans module

The native text rendering coupled with the automatic platform-specific font policy lookup should help Substance-powered Swing applications turn into the first-class citizens on the Vista desktop. Many thanks go to Karsten Lentzsch for his pioneering work in this field.

You’re more than welcome to leave comments with your thoughts, suggestions and bug reports (first consult the current list of supported components above). The plugin is distributed under the Eclipse Public License (EPL). Hope you like it, happy Thanksgiving and see you on the other side of our trip to Hawaii :)