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

 

I.                    What is ClearType and where is it available?

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:

  • Opaque surface
    • 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.   

 

II.                  Why is it necessary to opt in to ClearType when using RibbonWindow in Aero theme?

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. 

 

III.                How WPF Ribbon achieves ClearType

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.

 

V.                  IRTs and ClearTypeHint

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:

  1. Render an opaque Background within this ScrollContentPresenter.
  2. 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.

 

VI.                Determining if text is rendering as ClearType

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.

 

VII.              Conditional Compilation of ClearType for .NET 4.0

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. 

 

VIII.            Sample Code & Related Links

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.

RibbonClearTypeSamples.zip