Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

WPF (and Silverlight): Choose your Fonts and Text Rendering Options Wisely

Pete Brown - 06 June 2010

"He Chose Poorly" was the first thing I thought when I saw the font rendering in a metro-themed WPF4 application I looked at the other day. (Metro is the name of the Zune/Windows Phone 7 user experience style). The application was really sweet, but suffered from some crummy font rendering.

Ok, maybe not the first thought. My first thought was actually "This is WPF 4, there's no excuse for bad font rendering", and I was half right. Folks were looking at the application and blaming WPF for the text quality when it was really an combination of bad font selection and lack of appropriate text options.

WPF 4 has vastly improved font rendering over WPF 3.5. In fact, when you want it to be, it is completely indistinguishable from straight old native Windows GDI font rendering. Something else had to be going on here, so I pulled out Snoop and took a look at the fonts being used.

The font being used was Segoe WP, the Windows Phone 7 Segoe font. This is a font designed for 260+ DPI displays, like you might find on a handheld device, so there's no real hinting included with the font. The net result is horrible rendering on our 96 dpi displays. A font of pixel size 48 on a hand-held device appears at approximately the same physical size as a font of pixel size 18 on our desktop machines.

Here's Segoe WP in Microsoft Word at a number of different sizes. Notice how the characters are poorly formed.

image

You can see that the higher sizes, which would rely less on hinting, have better shape and clarity, while anything under about 36 is of questionable quality, and anything under 24 is pretty much unusable. That 36px font would be representative of the quality and clarity of regular text on the phone due to the DPI difference. Stuff like this is why I ranted that I wanted higher DPI displays for our own PCs. If the DPI gets high enough, you no longer need anti-aliasing of graphics or tricks like ClearType and grayscale smoothing of text. Anyway, I've beat that one to death.

Now, here's Segoe UI, a font specifically designed for 96dpi displays, at the same sizes:

image

You can see the results are quite different in the lower point sizes. The font itself is not identical to Segoe WP (in fact, Segoe was born from different roots than the Microsoft brand Segoe fonts) but it is a reasonable stand-in.

For grins, I even tried using Segoe WP in Notepad:

image

As you can see, it didn't go over well. There are a fair number of horizontal lines that are just missing.

Picking the right font makes all the difference for both WPF and Silverlight. Just because a font is available, doesn't mean it's a font that will render well in your specific scenario.

In addition to picking the right font, WPF has some text rendering tweaks you can make to help further clarify text on-screen.

What about WPF Text Options?

Ok, so what if you pick a good font, but still don't see great results? The next step is to try out some of the different text rendering options. In the examples below, I'm using Segoe UI, a font with decent, but not excellent, rendering at smaller point sizes.

TextOptions.TextFormattingMode

TextOptions.TextFormattingMode = Display

 

image

Here is a zoomed-in version (click for much larger version).

image

Note that when using Display, the verticals (most obvious in the word "all") are identical. This mode takes display resolution into account when laying out the type. The sacrifice made is font fidelity: if you want to see the font exactly as intended, with shapes exactly as designed, this mode is not for you. However, if clarity of smaller sizes is more important, the Display formatting mode will often get you there.

TextOptions.TextFormattingMode = Ideal

 

image

Here is a zoomed-in version (click for much larger version)

image

The Ideal mode, which is the default, works harder to preserve the shapes of the characters. For example, look at the 12pt "Q" in "Quick" here vs the Display mode. The Ideal mode preserves the rounder shape of the Q whereas the Display mode squishes it a little. The Display model also appears a little more aliased when compared to the ideal mode.

 

TextOptions.TextRenderingMode

Let's take a look at combining the formatting model with the various TextRenderingMode options. TextRenderingMode supports four different values:

  • Aliased - bilevel rendering, aliased
  • Auto - pick automatically based on layout mode
  • ClearType - pick appropriate ClearType algorithm based on layout mode
  • GrayScale - grayscale anti-aliasing

I decided to try out two of the TextRenderingMode settings: Aliased and ClearType. This is a really large image (a little larger than full-screen on my 30" display), but gives you an idea of what each of the combinations looks like.

image

NOTE:

ClearType settings on my PC are a little off. I didn't update them when I upgraded my display, so I get more color fringing than most folks.

Here are the four 100% sized captures:

Display, Aliased

image

 

Ideal, Aliased

image

 

Display, ClearType

image

 

Ideal, ClearType

image

 

Here's the XAML I used to test (I changed the properties in the two styles to create the different scenarios, used Snag-It for screen captures, then composited in PhotoShop. Yes, I could have done it all in WPF without anything else but a print screen <g>)

<Grid Margin="10">
    <StackPanel Orientation="Vertical">
        <StackPanel.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="FontFamily"
                        Value="Segoe UI" />
                <Setter Property="TextOptions.TextFormattingMode"
                        Value="Display" />
                <Setter Property="TextOptions.TextRenderingMode"
                        Value="ClearType" />
            </Style>
        </StackPanel.Resources>
        <StackPanel Orientation="Vertical" Margin="10">
            <TextBlock Text="10: The Quick Brown Fox and all that"
                        FontSize="10" />
            <TextBlock Text="12: The Quick Brown Fox and all that"
                        FontSize="12" />
            <TextBlock Text="14: The Quick Brown Fox and all that"
                        FontSize="14" />
            <TextBlock Text="18: The Quick Brown Fox and all that"
                        FontSize="18" />
            <TextBlock Text="24: The Quick Brown Fox and all that"
                        FontSize="24" />
            <TextBlock Text="36: The Quick Brown Fox and all that"
                        FontSize="36" />
        </StackPanel>
        <StackPanel Orientation="Vertical" Background="DarkBlue" Margin="10">
            <StackPanel.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="FontFamily"
                            Value="Segoe UI" />
                    <Setter Property="Foreground"
                            Value="Yellow" />
                    <Setter Property="TextOptions.TextFormattingMode"
                            Value="Display" />
                    <Setter Property="TextOptions.TextRenderingMode"
                            Value="ClearType" />
                </Style>
            </StackPanel.Resources>
            <TextBlock Text="10: The Quick Brown Fox and all that"
                        FontSize="10" />
            <TextBlock Text="12: The Quick Brown Fox and all that"
                        FontSize="12" />
            <TextBlock Text="14: The Quick Brown Fox and all that"
                        FontSize="14" />
            <TextBlock Text="18: The Quick Brown Fox and all that"
                        FontSize="18" />
            <TextBlock Text="24: The Quick Brown Fox and all that"
                        FontSize="24" />
            <TextBlock Text="36: The Quick Brown Fox and all that"
                        FontSize="36" />
        </StackPanel>
    </StackPanel>
</Grid>

How does it Compare to Windows Forms?

Windows Forms is the gold standard for font rendering in business applications. It's what WPF is compared to whenever someone mentions fuzzy or blurry text.

For grins, here's the same text using Windows Forms. The font sizes aren't exactly the same (off by a few thousandths), as different measurement units are used (pixels in WPF vs. Points in Windows Forms), but it's close enough to compare.

TIP

To convert WPF pixel font sizes to Windows Forms Point font sizes, divide the WPF font size by 1.3333 (or 96/72 : WPF Screen DPI / Point DPI).

image

Compare that to the Display, Cleartype WPF rendering above. They are almost identical. (the clipping of the Q is my fault: forgot that Windows Forms labels are opaque by default)The actual Windows Forms point sizes used were 7.5, 9, 10.5, 13.5, 18, 27.

How about seeing them side by side?

Windows Forms and WPF, Side by Side

WPF on the left, Windows Forms on the right. WPF is using the Display, ClearType settings.

image

Windows Forms

image

WPF (Display, ClearType)

image

You'd need to pull out specialized measuring instruments to tell if there were any differences here. To my eye, they are identical. You can tell they're not the same screen shot because the spacing between the lines is a little different.

Summary

WPF 4 has Great Font Rendering. So, what are you waiting for? There are so many great WPF applications out there that just need these simple text options changes (which can be put into global styles) in order to go from awesome to truly friggin awesome.

WPF has gotten a lot of abuse about its font rendering over the years. While I understand why the rendering was the way it was, I'm one of the people who complained about it. WPF 4 totally changes that. It has font rendering that is as good as any native Windows application, and better than most every other developer platform. Pick good fonts (a must in any case) and set the right options to take the fuzz out of your WPF applications.

     
posted by Pete Brown on Sunday, June 6, 2010
filed under:      

20 comments for “WPF (and Silverlight): Choose your Fonts and Text Rendering Options Wisely”

  1. Justin Jamessays:
    You've really made WPF look bad here. Sure, *with the right tweaks* it can look good. But guess what? I don't have to lift a finger to get the right results with WinForms. Do you really think that the typical developer needs this added to their plate? I don't!

    And you've forgotten something much more crucial... Silverlight is supposed to be giving up "write once, run everywhere", particularly with a transition across form factors. So picking a font and rendering options based on one display apparently makes things much uglier on another display. Or, to put it another way, what looks good on your PC will look awful on a Windows Phone 7 device, and vice versa.

    J.Ja
  2. Petesays:
    @Justin

    I completely disagree. WPF had issues with text clarity in the past, and I'm simply showing how to get past them in the current release.

    WPF has much better support for rendering fonts the way the font designers had intended them to look. However, that generally only looks good at larger font sizes or higher DPI displays. If you'd rather have a traditional GDI-style look to the font (which tends to look better at font sizes < 14 or so) you can put a couple lines in some global styles in your project and be done with it. It's actually not much to worry about at all.

    WPF provides you with options to control the font rendering for a variety of scenarios. As a designer, you have much more control over how the text appears.

    WPF (and Silverlight) use subpixel rendering, which provides much better scalability of UI than anything we've had before (including Windows Forms). A casualty of that was the font rendering, but that has now been addressed.

    Silverlight is not "write once, run everywhere" -- it never was. In reality, you're going to optimize the user interface for the form factor you're targeting. While you may reuse a ton of stuff, you're almost certainly not going to share the UI components between, say, a client (Win/Mac) app, a web page right-rail widget, and a Windows Phone 7 application. There's no "giving up" involved :)

    "What looks good on your PC will look awful on a Windows Phone 7 device". I think we learned that with Windows Phone 6 and below. Taking desktop UI and desktop metaphors and porting them to a device does not result in a very good user experience. This is as true for client applications as it is for web pages.

    So, if all you're interested in is quality text rendering on 96dpi Windows displays, sure Windows Forms is marginally easier. However, WPF and Silverlight provide much more capabilities both in the UI space and in core capabilities such as the rich binding support. Windows Forms is a good technology, and still has life left in it, but its time in the spotlight has passed.

    Pete
  3. Petesays:
    @Chris

    Why are you stuck on SP2? SP3 has been out for over two years and is highly recommended not only for stability but also for security reasons. SP2 also end-of-lifes this July meaning no more support.

    If you (or your company) won't upgrade to Windows 7, consider SP3 at least. Running with an unpatched OS that old just invites disaster.

    Pete
  4. Justin Jamessays:
    Pete -

    I appreciate where you are coming from, but it all honesty, the *device* should be making rendering deicisons, not the *developer*. For one thing, the developer cannot anticipate every device's hardware (and it is even worse on mobile devices than desktops). In addition, I would think that the team at Microsoft and/or the device maker is going to have a lot more expertise in picking the right rendering choices for their device. Finally, the user gets a say in the matter too; if the user wants to use ClearType, why should the application be overriding that with aliasing or something else entirely?

    Sometimes, choice is not good. And when you are forcing people who lack the experience and knowledge of things like rendering techniques (honestly, this really is a specialized field of knowledge) to make these kinds of choices, the results are often less than perfect. It's like how "developers" were forced to do "design" before CSS made it so easy to split the job roles, and you saw Web sites with green text on red backgrounds so much more often...

    I really think that if anything, this highlights some weaknesses in the font sub-system. With the shift to WPF, the font system should be updated as well so that a single font can package in the right versions for low and high DPI scenarios.

    By the by, many, many people are indeed treating Silverlight as a "write once, run everywhere" deal. I agree whole heartedly than a UI that works well on one form factor is not going to work well on all form factors, but at the same time, using Silverlight as a "widget" technology is still appealing, especially if you have an MSDN subscription and get Expression Studio for free, and don't feel like learning Flash.

    J.Ja
  5. Darrensays:
    This article caught my eye whilst catching up with my news feeds on the train. This is because I've been having trouble with fonts on an internal application that I wrote some time ago which has become quite popular and I now need to make some modifications. Since writing it, I've upgraded to VS 2010.

    The problem I'm having is with a silverlight navigation application. When I run the app, the navigation bar seems to display nicely, then resizes and goes fuzzy when the content loads.

    I haven't been able to test on another machine just yet, but I would have hoped that the built in templates would work fine so I'm suspecting this is probably a very basic issue that I'm missing. Even if I creates new project using "File -> New Project -> Silverlight Navigation Application" and hit f5 I get the same problem so I don't think it's anything I've added to the app -- either it's my local workstation, or there is a problem with the template?

    Any thoughts anyone has greatly appreciated. Sorry for the basic question.
  6. Bigsbysays:
    Jolly nice, Pete,

    I guess I understand what Justin is. One of the wonderful things about .Net is that you can choose the level of your coding and have .Net Framework handle a lot of the issues you don't care about technically speaking. Maybe, text rendering control should be default to a one-size-fits-all-although-heavier set.

    Liking to go through .Net Framework's code to get what is going on underneath and coding my own versions to really understand how things are done, I tend to rely on the code in .Net and it's updatable features.

    So, I understand the complaints about text rendering and/but I also understand the constraints of making it cross. Not an easy task. No, siree...
  7. Mattsays:
    I somewhat agree with Justin here too. While WPF has now given us all this extra power for different font rendering techniques it has also gone and complicated the whole idea of rendering fonts.

    Previously the developer did not need to be all that concerned about the appearance of fonts as it just worked. However I'm still glad MS decided to fix the awful issues with font rendering in WPF. It was so bad we had several prototypes rejected from customers due to the lack of clarity in previous version of WPF.


    With regards to Chris' response and WinXP SP2, I'd imagine he's referring to thin client machines. There's a lot of these out there in enterprise businesses that come with WinXP SP2 embedded with no way to upgrade them to SP3.

  8. Petesays:
    @Justin (and others)

    The font technology is actually fine. Font files are flexible enough to include appropriate hinting and information so they can be made to look good at most any DPI. However, that takes a fair bit of work from the font designer. In the case of Segoe WP, a font which was made specifically for high DPI displays, they decided not to bother with that. It's a special case, but definitely not the only one like that. Some self-categorized "headline" fonts are the same way: they look crappy under a certain size.

    To everyone's point: I agree, I think having the GDI-compatible text rendering as the default would have been a good choice. Unfortunately, it would have broken existing applications. I'll put together another post showing how you can set this pretty much globally in your own apps.

    That said, I'm a little torn on it. The Ideal mode looks good above certain sizes, and certainly is a better representation of what the font designer designed.

    Choice is good, but I see how in this instance, choice gets in the way of productivity.

    Pete
  9. Chipalo Streetsays:
    I am a program manager for text in WPF and Silverlight. I’d like to address a couple points brought up in the post and the comments which followed.

    Pete mentioned in his original blog post that WPF measures text in pixels. This is the default behavior; however WPF can also measure text in points. To do this just add ‘pt’ after the value for the FontSize property.

    <TextBlock Text="Text measured in pixels" FontSize="10" />
    <TextBlock Text="Text measured in points" FontSize="10pt" />

    This is not applicable in Silverlight. Currently Silverlight only measures text in pixels. If you would like text measured in points, you have to do the conversion that Pete mentioned in his original blog post. More information about text measurement is available at http://blogs.msdn.com/b/text/archive/2009/12/11/wpf-text-measurement-units.aspx.

    Justin noted that developers should not have to worry about many details of the font stack and the system which an app is running on. The WPF and Silverlight teams agree with this. Our frameworks try to pick the best default behavior for main line scenarios while providing APIs to control low level functionality for those who care.

    For example, WPF will automatically use ClearType and other information within a font to make the text as clear as possible. Without the developer doing anything, WPF honors system ClearType settings. If an individual user does not like ClearType, he can disable it on his machine and the WPF app will change its rendering accordingly.

    Well designed fonts take a lot of time and effort to create because font designers embed tons of detailed information in them (eg. Hinting, kerning, etc...). This data is specific to individual fonts and cannot be faked by a text stack. WPF will use this info when it is available, again without a developer doing any extra work.

    In some scenarios developers do care about text details. VS2010’s default font is Consolas. This font is designed to be used with ClearType enabled. Consolas will look worse than other fonts when ClearType is disabled. Due to this, the VS2010 team decided to use a low level WPF API (TextRenderingMode, more info at http://blogs.msdn.com/b/text/archive/2009/08/24/wpf-4-0-text-stack-improvements.aspx) to always force the use of ClearType, overriding user set system settings, when Consolas is used in the editor. This is only done for Consolas so VS2010 will respect ClearType system settings for all other fonts.

    While our frameworks try to make it as easy as possible to write once use everywhere; developer decisions can dramatically impact this. The issue which sparked Pete’s original blog post stemmed from a developer using a font designed specifically for high resolution displays. This font did not have the necessary information to make it look crisp at small sizes on traditional LCD monitors. There is nothing that any font stack (WPF, Silverlight, GDI, Mac, Linux) can do about this.

    For more detailed information on font related issues, check out the WPF Text Blog (soon to be WPF + SL text blog) at http://blogs.msdn.com/b/text/.

    Darren – send me an email at cstreet@microsoft.com and we can investigate your issue separately.

    - Chipalo
  10. Itaisays:
    Missing a “Windows Forms and Silverlight, Side by Side comparison”. Since the majority of new business applications are targeted for browser, this would really show the core problem. Furthermore, 96 dpi is the standard de-facto on practically all current desktop monitors in the world. I wouldn’t hold my breath waiting for a massive hardware upgrade just to accommodate an "enhanced programming model". If it looks great on standard HTML pages/Winform then most business decision makers will treat it as software engineering problem which won't justify replacing current hardware.
    I think the whole idea of sub-pixel rendering while interesting from an engineering perspective is way ahead of its time from business perspective. The real issue is not WPF but *Silverlight*. The pain is in developing *web applications* not desktop applications; sadly current Silverlight text rendering (with clear type enabled or any other tweak) does not meet business standards.
  11. Alexsays:
    The issue is clients don't accept crappy text in Silverlight (so they don't want SL as a technology for their solutions).

    After four (4!) versions of Silverlight Microsoft still doesn't render clear text like in web browsers we see (using Tahoma font after embedding it in SL app for instance).

    It shocks the clients that I present them such poorly and crappy looking text as one of the options for their product ;(
    Until next versions of SL (probably we have to wait for version 8 or 9 knowing speed of MS improvement in this area) it's technology for testing in labs only or showing photos/playing video.

    What's a pity...
  12. Beluga Babysays:
    @ Koistya `Navin

    Thanks so much! That's exactly what I've been looking for. Do you know if there's any way to get the Windows 7 GUI to use this as well? The WPF refuses to respect anti-aliasing choices in the control panel, taskbar, etc... It'd be great if you could disable antialliasing completely.
  13. silverlight downloadsays:
    That is amazing, I know fonts had some hinting stuff built into them but never thought they could depend on it that much. So, it's not always WPF's fault ;)

    (funny story - when I first started typing this, i thought the font looked a little weird on here... and it kinda is.. but I think it's just the color maybe.)
  14. Mark Robinsonsays:
    hings that WPF has that Silverlight doesn't: Full 3d engine based on DirectX, Windows integration such as Windows 7 taskbar thumbnails and system registry availability as well as access to the full .NET Framework including Oracle database support. Also, SL runs in a secure sandbox that prevents access to things such as the entire file system where WPF apps can run full trust with complete system access.

Comment on this Post

Remember me