Plenty of people (myself included) have had some less than favorable things to say about text rendering in WPF and Silverlight. Well haters gonna h8, but we’ve come a long way! Here’s thet thing: text rendering is not only hard but it’s highly subject. That’s why a tool like photoshop makes you choose a rendering method (one of 5) for every text element on the canvas. There really isn’t a single rendering methodology that is going to look great for all fonts in all situations.
If you think about it, you’re dealing with the intersection of a lot of variables: the glyphs in the font itself (is it thin, thick, etc.), the features of the font (whether it supports hinting, etc.), the size of the font and the context in which it is used (the color of the text, the color of the background, etc.).
The fancypants engineering that turns all of that into pixels on a screen is not going to get it right all the time, especially for something like type where our eyes are highly trained and people (designers and non-designers alike) have strong opinions.
So, in that spirit, I thought I’d share some of my (highly subjective) opinions. Here are a couple of things that I do get better text rendering in Silverlight:
1. Choose Good Fonts at the Right Size
Some fonts just seem to be made for Silverlight and some feel like a fight. Unfortunately, there are no rules about this. It takes a little trial and error. And to make it even more complicated, the results are pretty dramatic depending on the size at which you’re rendering. The same font might look pretty good at 12px and crummy at 13px.
Segoe and Verdana both look okay at display sizes. I prefer Verdana at 11px or 12px. Segoe works great at 14px but kind of looks awful at 11px (especially bold).
Confusing? Unfortunately, it sort of is. The good news is that for display font sizes (10-14px or so), you’re generally better off sticking with what you know anyway. At that size, you shouldn’t be trying to be creative or really even establish a mood. You should probably be focused on conveying information. To that end, a common font is an asset because it lets the text itself have the voice instead of the font its written in.
For larger sizes, you may want to be a little more expressive and there you’ll have to do some digging. Keep that in mind as you design or work with your designers to that they understand: when it comes to production, you may have to tweak font sizes by a pixel or two here and there to find a match to the Silverlight text rendering engine.
Seems a little arbitrary, right? Why should the same font look so different (jaggy vs not, etc.) at two very similar sizes? It’s because of text hinting and that brings us to…
2. Understand Hinting (and turn it off some times)
Text hinting (or font hinting) is like pixel snapping for fonts. It’s a way for the font author to specify the “critical” lines in each of the glyphs, the ones that need to land on pixel boundaries. The result of well hinted text is that the stems in a letter like “M” fall on pixel boundaries and you get text that looks much crisper.
Microsoft tends to be pretty aggressive when it comes to text hinting and that typically accounts for the difference in font rendering between Windows and Mac. Strongly hinted text feels crisper but a little bit more jaggy. At large sizes, text hinting doesn’t matter and in WPF and Silverlight, you can usually find the “magic” size where the rendering algorithm stops paying attention to hints. For Segoe UI (in WPF) this happens somewhere between 20 and 21px. You can see the difference below:
This is how text hinting accounts for the big differences between seemingly small sizes. It’s not just because hinting switches off at certain sizes, it’s also the fact that as you move from size to size, you’re doing a bunch of rounding. You’re literally changing the underlying glyphs that make up the characters in the font so that they align to pixel boundaries.
This also explains why you get a lot of artifacts in the “medium” sized display sizes (13px through 20px or so): at smaller sizes, hinting does less because many of the glyphs end up being a single pixel wide (think of the letter I at 10, 11 or 12px—there’s a good chance that it will only be a single pixel wide at any of those sizes). When you move up just a little, you still have hinting in the math, but now the difference is more noticable and as you move from, say a 17px font to an 18px font you may actually see a significant change in the shape of a glyph. This effect sets in even earlier for bold text.
You can probably already feel my bias here. At small sizes, I really like hinted text but for medium sizes, I think it distorts the glyphs and generally looks too crisp. In my opinion, this is why people complain about Silverlight and WPF text rendering. It’s too aggressive in it’s approach to hinting. I won’t pretend to be an expert, but I’ve heard that this has something to do with something called a gamma table. I mention that only because it sounds awesome.
Earlier I said that Photoshop lets us choose between 5 different mathemagical formulas to get pretty precise control of text appearance. Well, Silverlight isn’t quite that generous, but there’s one huge switch that we can throw: TextHintingMode. Hooray!
When you set TextOptions.TextHintingMode=”Animated” you are essentially telling the rendering engine to ignore hinting. Thanks! I think it’s called “Animated” because if you’re text is animated, you presumably don’t care about how it lines up against pixel boundaries anymore.
Basically, when you set TextHintingMode=”Animated, you tell Silverlight to render your text using the same algorithm it uses at larger sizes, the one that ignores hinting. The result can be that the text feels a little fuzzy at smaller sizes, but I think it often looks much better. Here are a couple of examples:
You might prefer the hinted text (Fixed above). From a technical perspective, you could probably make an argument that it’s more “correct.” It’s definitely brighter and I think that some people would argue that’s more readable because of that.
On the other hand, I think anyone would agree that the “shape” of the letters in the “Fixed” text is a little distorted compared to the “Animated” text. Look at the top sample. That’s Verdana. Checkout the top of the “6” in 16 for the bold version of that font. It’s been reduced to a single horizontal line. The same goes for the top and bottom lines in th
e little “z” in size. If you compare those to the non-hinted version, it’s clear that those lines should all have a little more weight to them.
The result of all of this is that I use TextHintingMode=”Animated” a lot. A whole lot. In fact, this property inherits and I usually just set at the top of the app and then “opt out” instead of opting in. If that makes things look fuzzy, um, sorry. I like it.