Enabling ClearType for Ribbon Applications
The Ribbon RTM release was built against .NET 3.5, but our October 2010 release of Ribbon includes both .NET 3.5 and .NET 4.0 Ribbon DLLs. With the v4.0 Ribbon, we have enabled ClearType on all of the Ribbon controls using RenderOptions.ClearTypeHint. WPF applications using RibbonWindow must also opt-in to enable ClearType for all content below the Ribbon.
This article describes ClearType technology and requirements and then specifies how a WPF Ribbon application enables ClearType. We refer to RibbonWindow and Ribbon applications specifically, but similar steps to enable ClearType apply for any WPF app that uses WindowChrome.
- I. What is ClearType and where is it available?
- II. Why is it necessary to opt in to ClearType when using RibbonWindow in Aero theme?
- III. How WPF Ribbon achieves ClearType
- IV. Example: Enable ClearType for body text of RibbonWindow
- V. IRTs and ClearTypeHint
- VI. Determining if text is rendering as ClearType
- VII. Conditional Compilation of ClearType for .NET 4.0
- VIII. Sample Code & Related Links
ClearType is a subpixel anti-aliasing technique for improving text smoothness. Wikipedia has a nice overview of the technology here. WPF supports ClearType and extends ClearType in .NET 4 by allowing app developers to electively use ClearType on surfaces that are otherwise considered transparent and hence inappropriate for ClearType. Read more about WPF support for ClearType here.
ClearType support in WPF has a couple requirements:
- Opaquesurface
- ClearType is incompatible with alpha blending, so text cannot render as ClearType on top of a transparent background. In .NET 4.0, ClearTypeHint allows developers to enable ClearType where it is otherwise disabled, though this could make text worse or cause rendering issues when used over a non-opaque background.
- OS support
- ClearType is available on all Windows OS’s where WPF runs, starting with Windows XP. However, ClearType is only enabled by default on Vista & later. So, Windows XP users must go through Control Panel to enable ClearType. More information is available in this white paper on WPF text clarity.
Here is some text rendering as ClearType (shown at 800% magnification):
Notice the red and the blue hues. These indicate the text is rendering on subpixel boundaries. Rendering this text on subpixel boundaries gives 3x higher horizontal resolution than rendering on pixel boundaries, although there is a chromatic cost – some color is introduced to create the smoothing effect. This snapshot was taken at 800% magnification, and when I zoom out to normal resolution the red and blue hues are unnoticeable and you see smooth text.
Normal WPF 4.0 Window will support ClearType by default, so you get it for free. However, if you are using RibbonWindow, you need to opt in using the RenderOptions.ClearTypeHint attached property (System.Windows.Media namespace, PresentationCore.dll). This is necessary because RibbonWindow extends glass into the client area using DwmExtendFrameIntoClientArea. (RibbonWindow claims the entire native window as client area so that it can draw the Quick Access Toolbar in what is normally non-client area. Therefore, RibbonWindow must extend glass into the client area to attain the appearance of a normal Aero window.)
It is only necessary for RibbonWindow apps to set RenderOptions.ClearTypeHint for their Aero themes, but setting ClearTypeHint.Enabled for all themes shouldn’t hurt.
All of the WPF Ribbon controls render as ClearType as long as they are rendering against solid backgrounds (most controls are). Examine this screenshot:
Notice how the “Home” RibbonTab is rendering as ClearType with warm and cold hues, while the RibbonTitlePanel’s text is using grayscale anti-aliasing. This screenshot was taken on Win7 Aero, and the RibbonTitlePanel renders directly on glass, so it doesn’t support ClearType. The grayscale text is choppier, while ClearType offers a general improvement in text clarity. The text sharpening provided by ClearType is a cumulative effect, so the improvement in clarity becomes more evident at the document/app level.
The “Home” tab has ClearType “because the v4.0 Template for RibbonTabHeader sets RenderOptions.ClearTypeHint=“Enabled” on its “InnerBorder” element. Other Ribbon controls set ClearTypeHint in their templates also, and the Ribbon sample apps (e.g. RibbonWindowSample.exe) set ClearTypeHint similarly in their XAML.
IV. Example: Enable ClearType for body text of RibbonWindow
While Ribbon is fully ClearType-enabled, an app using Ribbon must opt-in to ClearType for the Aero theme. To achieve this, we simply make sure RenderOptions.ClearTypeHint=“Enabled” is set wherever text is hosted. Examine the following XAML:
<ribbon:RibbonWindow ...>
<Grid x:Name="LayoutRoot" ...>
<ribbon:Ribbon x:Name="Ribbon" ... />
<Border Grid.Row="1">
<StackPanel>
<TextBlock Text="ClearType ENABLED." RenderOptions.ClearTypeHint ="Enabled" />
<TextBlock Text="ClearType OFF."/>
</StackPanel>
</Border>
</Grid>
</ribbon:RibbonWindow>
Running this on Win7 Aero produces the following text rendering:
Notice ClearType rendering in the top TextBlock, which opts in to ClearType. Besides the chromatic differences, from this screenshot it’s not immediately obvious what improvements ClearType brings to the table. Bear in mind that ClearType rendering creates an accumulative effect to improve general text crispness.
Generally one should set RenderOptions.ClearTypeHint=“Enabled” at some root element, since the setting propagates down the visual tree unless another IRT (Intermediate Render Target, see next section) gets in the way. For example:
<ribbon:RibbonWindow ...>
<Grid ...>
<ribbon:Ribbon .../>
<Border Grid.Row="1" RenderOptions.ClearTypeHint ="Enabled" >
<StackPanel>
<TextBlock>My app</TextBlock>
<Button Width="Auto" HorizontalAlignment="Left">body has</Button>
<Label>ClearType!</Label>
</StackPanel>
</Border>
</Grid>
</ribbon:RibbonWindow>
Notice that we set ClearTypeHint=“Enabled” on the Border element below the Ribbon rather than on the parent Grid that contains everything. This was deliberate – the Ribbon’s quick access toolbar and title draw over the transparent glass at the top of the window, and setting ClearTypeHint=“Enabled” for text over transparent backgrounds may cause rendering issues.
IRT stands for Intermediate Render Target. An IRT is a common WPF graphics term used to refer to a surface that a tree of WPF visuals render to. Every separate visual tree (e.g. contents of a Popup in WPF) renders to a separate IRT. In addition, applying a Clip/Opacity to a Visual causes a new IRT to be generated.
ClearTypeHint, when set, propagates to the subtree under that Visual that renders to the same IRT. If a descendant node in this subtree has a Clip applied to it or causes a new IRT to be created for another reason, it no longer honors the ClearTypeHint settings. These settings will need to be redefined on a Visual within the scope of this new IRT. A common instance where this behavior manifests is in the case of a ScrollContentPresenter of a ScrollViewer. A ScrollContentPresenter inherently clips the contents that are beyond the viewport. By doing so, it causes its contents to be rendered to a separate IRT.
Now consider a RichTextBox hosted in the content pane of a RibbonWindow. A RichTextBox’s built-in template uses a ScrollViewer that contains a ScrollContentPresenter. Thus to turn on ClearType for text rendered within this ScrollContentPresenter, we must do two things:
- Render an opaque Background within this ScrollContentPresenter.
- Set ClearTypeHint=“Enabled” within the scope of this ScrollContentPresenter.
The attached sample code demonstrates such usage. Similar techniques have been implemented in the RibbonControlsLibrary to enable ClearType for the various subcomponents within the Ribbon. For further reference, Lester Lobo’s blog discusses IRTs and when to use ClearTypeHint in WPF.
As seen in this article’s screenshots, text rendering as ClearType has red and blue hues since glyphs cut across subpixel boundaries. It can be difficult to verify ClearType rendering at normal resolution, so we use a magnification technique to zoom in. Windows ships with a magnifier accessibility tool we can launch from the Start Menu:
When you magnify 800%-1000%, you can readily see the ClearType effect. The magnifier’s Full screen mode works great on Aero but isn’t available on other themes, so I often use MSPaint to magnify screenshots on non-Aero themes.
ClearType is only available in .NET 4.0, but some WPF apps and custom controls may want to support both .NET 3.5 and 4.0, lighting up with ClearType on .NET 4.0. To support both platforms from a single codebase, some conditional compilation is required.
Ribbon itself requires conditional compilation. The Microsoft Ribbon for WPF Source and Samples MSI includes a perl script that pushes XAML files for the Ribbon sample apps through the C preprocessor to create separate 3.5 and 4.0 XAML. The 4.0 XAML has ClearTypeHint specified in several control templates, and #ifdef directives in the XAML direct the conditional compilation.
Sample Code for this article is attached.
- Microsoft Ribbon for WPF – Download the WPF team’s Ribbon release, a managed Ribbon implementation.
- Downloading the Ribbon MSI is necessary to run this article's samples. You can also download the Ribbon Source & Samples MSI from here.
- Anonymous
November 02, 2010
The comment has been removed - Anonymous
November 03, 2010
The comment has been removed - Anonymous
November 06, 2010
WOW Great post. I've been trying to get ClearType work for the last couple of days. It's a pain I must say. This post helped me a lot. I have found ClearType to be very inconsistent in RibbonWindow.
- When I enabled UseLayoutRounding in Ribbon, some of the RibbonTab Headers went to Greyscale Cleartype.
- I can't get Cleartype to work in a listView that uses a VirtualizingStackPanel.
- Simple Textboxes and Buttons are also reveting to Greyscale Cleartype. I just can't get these work properly. In concluion: it still needs a lot of work.
Anonymous
November 08, 2010
Patrick, thanks again, that's good to hear. I double checked the docs and you're right of course, it's right there in plain sight and seems familiar enough. Not sure how I missed it before, sorry about that! By the way, there's also a note there that says "On many controls, the ClearTypeHint attached property has no effect unless you set a non-opaque background behind the text." I wonder if this should say "opaque" instead of "non-opaque".Anonymous
November 09, 2010
@James - Glad you found this helpful! Agreed, enabling ClearType in RibbonWindow is a pain because ClearType rendering is turned off for RibbonWindow's entire tree by default and one must set ClearTypeHint="Enabled" every time the tree branches into a new IRT. This is certainly a subpar experience that we would like to improve upon (ideally getting the expected ClearType experience by default for RibbonWindow). #1 - I tried setting Ribbon.UseLayoutRounding, but still saw the RibbonTabHeaders render in ClearType. Are you styling them or setting clip or Background in a way that would affect ClearType rendering? I'm happy to take a look if you have a repro or more detailed repro steps. #2 - I was able to get ClearType in a ListView that uses VirtualizingStackPanel. In ListView.ItemTemplate, I include a Border element with RenderOptions.ClearTypeHint="Enabled" and Background="White" (the same as the RibbonWindow), and with this I get clear type for the ListViewItems. You may want to try something similar. #3 - TextBox contains new IRTs in its tree but Button does not. Button should be able to inherit RenderOptions.ClearTypeHint. I'll check with our Text team about the best way to enable ClearType for TextBox since it seems tricky. I agree with your conclusion that work is needed here. We have filed a bug to investigate and improve customer experience for ClearType in RibbonWindow. @Tom - You're right, that note should say "opaque" instead of "non-opaque". Thanks, we'll get this fixed!Anonymous
November 09, 2010
@James I spoke to Varsha, and we have a good example of how to enable ClearType for TextBox family of controls in our RibbonWindowSample. TextBox has a ScrollViewer in its template that is an IRT. Basically, to enable ClearType for TextBox you restyle ScrollViewer and set ContentTemplate to include a Border element with an opaque background and RenderOptions.ClearTypeHint="Enabled". Look for this Style in the v4.0 UserControlWord.xaml. The default Style for RibbonTextBox also restyles ScrollViewer like this.