One of the biggest tasks in the Caciocavallo project is the refactoring of the FontManager class. In the current OpenJDK code, this class is huge kitchen sink for all kinds of things that have no other place (or so it seems): it’s a final class with all static methods, with platform independent font code, utility functions, platform dependend code (windows and solaris mixed), fontconfig code, all nicely packaged in one big class. To make it even worse, there’s a bunch of similar font related methods in SunGraphicsEnvironment. My favorite comment in FontManager that says it all is this:
/* This is implemented only on windows and is called from code that
* executes only on windows. This isn't pretty but its not a precedent
* in this file. This very probably should be cleaned up at some point.
Ok, the latter is what we did in the end 🙂
The process of refactoring was a very interesting one, I won’t go into the details. We went to several iterations (I think around 7 by now), and after each one we had a quite large change already. During all the iterations, we kept moving code around, and for the first couple of iterations the mess didn’t seem to get better. But what we have now almost makes me proud. What we have now is this:
FontManager: Is an interface now. It ended up surprisingly small. This is the main interface to which the API classes talk to (java.awt.Font for example).
FontManagerForSGE: A subinterface of FontManager. It adds a couple of methods that are used by SunGraphicsEnvironment. Graphics backends that are based on SGE need to implement this for fonts, other backends (based on plain GraphicsEnvironment) only need the plain FontManager.
SunFontManager: An abstract base implementation of FontManagerForSGE. (Right now this class is called
FontManagerBase, but I’d like to rename it before pushing to OpenJDK.) It has all the platform independent code that serve as a basis for the platform specific implementations.
Win32FontManager: Subclasses of
SunFontManager for the respective platforms.
FontManagerFactory: A factory to create a fontmanager that is suitable for the target platform.
FontConfigManager: The fontconfig related code of the original
FontManager went there.
SunGraphicsEnvironment: has no font related code anymore. Everything is delegated to
FontUtilities: A couple of utility methods went here.
The scope of this change is quite huge, I don’t envy the guy who eventually will have to review it OTOH, I really would like to get this into OpenJDK as soon as possible, because maintaining this big change and keeping in sync with upstream is a nightmare. When everything goes as planned, it should be possible to implement a completely different font backend (i.e. based on GNU Classpath’s 100% Java fonts) based on this internal API. Yay!
For now, you could compare the old and new version of FontManager.java and see what looks better 🙂