We’re not living in an ideal world where everything just works and if not it can be fixed in no time. Not at all. Some time ago I wrote an article about problems with Dzongkha (Bhutanese) texts in Swing environment. At that time I thought it was fixed for good but nothing was further from the truth.
While rendered texts looks all right on first sight we later found out that some of the characters were not rendered properly. Sometimes. I did more research and came to conclusion that characters composed from more “strokes” seem to be put together in a wrong way. But – properly rendered combinations do exist in fonts as one character too – so you could’ve two similar characters, one apparently correct and the other one fault, written next to each other in the same editor.
As OS/fonts are usually the usual suspect in those cases, I started investigation there – but it was a dead end. Even notepad/kate rendered composed characters properly. I went more low-level and tried to render it using WinAPI calls – again flawless. At this moment I was thinking about writing a native library for font rendering, but I’d need to have three of them (Windows, MacOSX, Linux) and it’s not exactly piece of cake. As a last experiment I tried to render it in SWT – it worked. Well then, I thought, this is going to be PITA as well, but still better than native library.
I spent two days analysing SWT and Swing sources, looking for differences, trying to find real issue behind Swing’s unability to render texts properly. And guess what – I was successful.
For tests I’ve selected character composed from four parts – 0x0f62, 0x0f92, 0x0fb1 and 0x0f74 (ICU browser), if you have Tibetan script support you should be able to see it directly as རྒྱུ. If not see screenshots in next paragraph.
Following image illustrates the issue – on the left there’s a properly rendered character, on the right bad one. Unfortunately the bad variant is what you get if you just put it into JTextPane.
On top of that I found out that none of Jomolhari fonts works in Java properly. The only font able to render my test character properly was Tibetan Machine Uni.
So how do you get properly rendered Tibetan script in Java? There are more steps required:
- download and install Tibetan Machine Uni
- edit
fontconfig.properties
as described in first article about Dzongkha How to render Dzongkha (Bhutan) texts in Swing properly usingTibetan Machine Uni
instead ofJomolhari
- add property “i18n” with value of
true
to every JTextComponent’sDocument
you want to display Tibetan script properly
To give you some basic idea here is the code used to produce image above:
package dzongkhatest; import java.awt.Dimension; import java.awt.Font; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JTextPane; public class DzongkhaTest { static class Frame extends JFrame { public Frame() { setTitle("Dzongkha rendering test"); getRootPane().setLayout(new BoxLayout(getRootPane(), BoxLayout.X_AXIS)); JTextPane pane1 = new JTextPane(); pane1.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 100)); pane1.getDocument().putProperty("i18n", true); pane1.setText("\u0f62\u0f92\u0fb1\u0f74"); getRootPane().add(pane1); JTextPane pane2 = new JTextPane(); pane2.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 100)); pane2.setText("\u0f62\u0f92\u0fb1\u0f74"); getRootPane().add(pane2); setSize(new Dimension(200, 200)); setDefaultCloseOperation(EXIT_ON_CLOSE); } } public static void main(String[] args) { new Frame().setVisible(true); } }
This solution seems to work fine on Windows and Linux. Nothing is perfect, however – it fails miserably on MacOSX – every composed character is shown as it’s parts one next to each other;(