The Big FontManager Refactoring

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.
  • X11FontManager, 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 FontManagerForSGE now.
  • 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 and see what looks better 🙂


About Roman Kennke
JVM Hacker, Principal Software Engineer at Red Hat's OpenJDK team, Shenandoah GC project lead, Java Champion

2 Responses to The Big FontManager Refactoring

  1. Jonathan Gibbons says:

    When I’ve done similar big refactorings within JDK. I’ve found it helps to checkpoint the work and review each of the series of steps in turn, rather than review the complete “beginning to end”. The steps often break down into different types of cleanup, such as “move stuff around”, “retrofit interface”, “add new features”, and it is typically easier to review each such step sepaartely; otherwise it is easy to lose the small changes amongst the big moves.

  2. Clemens Eisserer says:

    Great work 🙂

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: