Friday, September 04, 2009
(Blogger scaled the image down slightly so click to enlarge)
Recently I discovered that Sean Barrett has put up on his website a nice little True Type font rasterizer. The keyword here being "little", compared to FreeType its microscopic with less than 1600 lines of source code in a single file. FreeType on the other hand is about 6.5MB of just source code... I have worked on games with less source code! So the possibility of tossing out that much bloat is really appealing to me.
Anyways upon finding this I quickly tossed it into my hobby project game engine to compare performance/memory/quality to FreeType with the assumption that it is probably faster, probably thrashes memory less and quality is probably roughly the same. Here are my discoveries:
This was a big shocker to me... FreeType was a good 3 times faster than stb_truetype at rasterizing a font of about 350 characters at height=14 pixels 8ms vs 26ms... thats almost double a single frame's budget! Granted usually you rasterize fonts once during loading and if you only have 1 or 2 fonts this is probably a non-issue, but if you have lots of fonts and supporting asian localizations this could potentially add seconds to your load time and that might be a deal breaker if you are already barely squeezing into TRC load time requirements. If you are dynamically caching fonts (like because you support rich text or something) this could be make it quite difficult to keep performance up. Luckily in my situation though I am pre-baking my fonts in my tools chain not at load time so performance isn't quite a deal breaker but I would prefer not pre-bake if performance was good enough. One thing to note is that in stb_truetype I was able to set it up to rasterize directly into locked texture memory whereas FreeType has no such API so I have to rasterize and then blit into texture memory so in a way FreeType was given a small handicap already.
Because I rasterize glyphs one by one the peak memory consumption for both FreeType and stb_truetype is quite low (just a few KB). But the number of allocator calls for both is quite high. Oddly enough again stb_truetype hammers on the allocator more making ~8,000 allocations versus FreeType's ~3,000 for the same font. Neither particularly makes me happy as a runtime solution. But the good news here is that while I would not want to touch FreeType's source code with a 10 foot pole, looking around in stb_truetype's source I believe I could stick in a relatively small fixed size pool and make stb_truetype run without any allocations of its own. So there is actually quite a bit of hope here.
Quality of stb_truetype isn't terrible but its not great either. FreeType comes off much cleaner and more closely matches the way Windows rasterize the same font. stb_truetype always comes off a bit bolder than it should be, a bit blurrier and a few artifacts like some characters being 50% transparent. Overall I think quality is probably acceptable for games and tools, but I wouldn't be shocked to have a few artists complain about it looking different than it does in Windows.
Mikko Mononen brought up www.codinghorror.com/blog/archives/000884.html. I am not so sure yet if the differences are within the same threshold or not, but I suppose its possible the quality is no more different than OSX vs Windows (which, btw I think fonts look better in OSX).
I am not quite ready to toss out FreeType yet, but I am awfully tempted. I think all the issues with stb_truetype can be resolved without too much effort so I fully expect to be giving FreeType the boot eventually.
So I decided I might try this blogging thing that all the cool kids are doing again, but this time instead of trying to ramble on about my day to day life which is not particularly interesting I figured I would use this as an outlet for my ramblings on technology, algorithms and random bits of code.