I'm thinking on doing some more work on the FreeType font hinting code sometime soon, so I've spent some time the last few weekends building a program to view hinted outlines. The way that hinting fonts for the screen works is that the outline is modified to better fit the grid of pixels, then the modified outline is scan-converted. My program allows looking at a magnified version of the modified outline and comparing it to the resulting pixels.
As you might guess from the spiffy, antialiased, alpha-blended graphics, I'm using Cairo to do the main drawing. It's been a lot of fun to write a very small, limited purpose application and really nail the details. To list a few:
- The toplevel window automatically resizes as you zoom in or out and change the text. But it respects the workarea of your desktop and scrollbars appear when the contents get bigger than that.
- The 1:1 image in the upper left is actually on overlay that doesn't scroll with the contents. It can be dragged around and if you drag it to an edge, it sticks to the edge as the window resizes.
- The entire state of the application is saved to GConf, so the next time you start it, it remembers your last selected font, all the hinting and display options, the text being used and so forth.
- The dropdown on the combo contains a history of the 10 last strings you've used, plus a set of fixed strings in different scripts.
- You can save the output to a PNG image, and the output is annotated with the selected font, the hinting style, and the 1:1 image that normally appears in the overlay.
I was suprised by how well saving the entire application state to GConf worked. There is no separation between preferences and transient state. You can just exit the viewer at any time and bring it up and it remembers where you were. This clearly isn't the right model for most applications, but I wonder if there are places in the GNOME desktop where idea could be effectively applied; perhaps desk accessories like gcalctool, gconf-editor, and gucharmap should work like that. For the viewer, the code flow for interacting with GConf is a little unusual; instead of monitoring GConf actively as the "model" of the application, the viewer simply initializes from GConf on startup and saves changes to GConf as they happen. This allows having multiple viewers usefully running at once.