Quicklinks

Sponsor

Font antialiasing in Oracle Forms

Posted by Tobias on October 2nd 2011

Updated on November 4th 2011

Whenever I need to work in Forms my eyes hurt from reading text rendered by the Forms application. Almost all modern GUI frameworks today apply some sort of text antialiasing to make text more readable. You may think it’s an easy task; the Forms GUI is implemented in Java so we only need to set our preferred antialiasing method when the JVM starts up. Right!? Unfortunately Oracle has made things a bit more difficult for us. The only question is: Are you brave enough to continue reading?

Disclaimer

Before we continue I want to put a small disclaimer here. I do not know whether the methods used in this article are legal or not. I am a code monkey, not a lawyer.

Getting started

I guess you are brave enough, good for you! So how do we attack this problem? We know that forcing text antialiasing by giving the JVM the correct startup parameters doesn’t work so how do we find out what’s wrong? Maybe seasoned Java developers already hears a bell ringing somewhere in the distance. When drawing text using Java we use a method called drawString() usually in the paintComponent() method of our component. The drawString() method is located in the Graphics class and an instance of Graphics is provided for us in the paintComponent() method. Now, in order to get font antialiasing we must cast Graphics to Graphics2D before drawing the text. Hmm, maybe Oracle isn’t doing that…

But why on earth would Oracle paint their own strings you say? Well, we know Oracle has implemented their awkward looking GUI themes somehow and I’m guessing they are overriding painting of each individual component and implementing their own themes. It’s not very hard to come to this conclusion, just open the file named ‘frmall.jar’ in any zip application and look into the oracle.ewt.laf package. Any bells ringing now? There are three packages listed: basic, generic and oracle. But aren’t those names exactly like the names of the different look and feels you can set for your Forms application? Yes they are! Also, the class names in those packages may look familiar to Java GUI nerds; they are basically the implementation of a Java look and feel.

Testing the theory

Ok, so now we have a theory, let’s put it to the test. How can we be sure that Oracle is using drawString() to draw strings in a Forms application? Forms itself isn’t open source so we can’t start digging around in code. Java however is open source. First we need to find out what the Graphics class really is. Download the source code for Java from www.oracle.com (or just keep reading this article), and extract the package somewhere. Then browse to ‘\j2se\src\share \classes\java\awt’ and open the ‘Graphics.java’ file. You’ll notice that it’s an abstract class so the implementation is elsewhere. I’ll save you some time and tell you what the implementing class is named: sun.java2d.SunGraphics2D. Now open this and read through it… Naw, just kidding… The class is huge and we are only interested in the drawString() method so go ahead and find it. In order to test our theory we will now do the following: add a call to setRenderingHint() in the drawstring() method, compile our own JVM and run Forms on it. Or don’t… I have already done it so you don’t have to. Anyway, Forms will now have fully antialiased fonts and angels will stop crying. So yay! Success!

There you have it, now go and make you users happy. What’s that? You don’t want to run Forms on a home cooked JVM? Well that’s not my problem! Go tell Oracle what’s wrong and ask them to fix it! I did… Oracle did nothing… Update: Oracle fixed this in 11gR2 but this article is still relevant for users of previous versions. Ok, so I’ll let you in on a little secret. We can fix this without rolling our own JVM. This is where we get into a legal grey area. As I mentioned earlier, I do not know if the following methods are legally safe so if Oracle comes bashing down your door, you’re on your own.

So far we have figured out what’s wrong and we also came up with a solution, the solution however wasn’t very good so we need another.

Implementation

Some smart people have come up with a framework for Java called AspectJ. It’s mostly used for debugging, logging and unit testing but it will also help us solve our problem. I will not go into any more details about this framework, if you are curious about it go to their website at http://www.eclipse.org/aspectj/.

AspectJ enables us to hook our own code into the code written by Oracle without having access to any source code. It does this by injecting byte code into the classes developed by Oracle. So what we have to do is write a class which does what we want (enable text antialiasing) and decorate our class and methods according to the AspectJ framework syntax. Then we will use an ANT task to “weave” our own code into Oracle’s code. Finally we will replace the original ‘frmall.jar’ file with our own. There is only one problem; we don’t know where to inject our code. The only thing we know so far is that Oracle uses the abstract Graphics class to draw strings and we want to cast the Graphics class into Graphics2D and enable antialiasing. Remember when we rolled our own JVM and enabled antialiasing? Well, we can use the same method to find out who calls drawString() by adding the following code:

System.out.println(String.format("Caller: class ‘%s’ method ‘%s’", new Throwable().fillInStackTrace().getStackTrace()[1].getClassName(),new Throwable ().fillInStackTrace().getStackTrace()[1].getMethodName()));

So now I only had to run my Forms application for a while and I had a log of caller classes and methods which are our entry points. And there you have it! Download the code, test it, run it and modify it to your liking. Just don’t blame me if Oracle doesn’t like it!

Result

Fig. 1
Figure 1. Compare font antialiasing on and off
Fig. 2
Figure 2. Look closer

Download

Subversion repository at code.google.com



Post a comment




Comments
Posted by WkauwDlQr on December 23rd 2011 09:25
If only there were more clveer people like you!