ClearType text filtering relies heavily on alpha blending (overview of ClearType). This algorithm must know the color of the text and the color behind the text before creating the final glyph bitmap. Determining the background color can sometimes be a very expensive process (eg. text in a container with a partially transparent background). In order to maintain acceptable performance, WPF disables ClearType when it encounters an element that could complicate this process.

 

The heuristic used to choose when to render with ClearType works by disabling ClearType whenever WPF reaches a node that introduces an intermediate texture that could be transparent. Some examples of this are placing text inside Effects, OpacityMask, VisualBrush, DrawingBrush, and layered windows. When used in layered windows, Clips and Opacity both also introduce these potentially-transparent intermediate surfaces and will disable ClearType.

 

To ensure correctness, this heuristic is overly aggressive, and sometimes ClearType is disabled on parts of visual trees where WPF can actually render ClearType. For example, consider the situation where an intermediate texture is an ancestor of a TextBlock with an opaque background. Since WPF knows the background color of the TextBlock, the ClearType algorithm can run correctly. Regardless of this fact, WPF will fall back to grayscale rendering because ClearType was disabled by the intermediate texture.

 

Setting ClearTypeHint will temporarily re-enable ClearType at the point in the tree where it’s set.  As we continue to walk the visual tree, it can be disabled again by the next intermediate render texture we encounter in a descendent node for that node’s descendents.  This allows a developer to turn ClearTypeHint on at the root of a layered window with an opaque background to get ClearType text where it was previously disabled, for example, without incorrectly trying to render text inside an Effect in that window with ClearType as well.

 

WPF needs to disable ClearType because the blending algorithm won’t work with a transparent intermediate texture – it will produce visually incorrect results.  This is the inherent danger in using ClearTypeHint – if you set it on a node being blended into a non-opaque intermediate texture then text will blend incorrectly and look wrong. It’s too expensive to keep track of which areas are opaque or not at run-time, which is why WPF’s errs on the side of caution when disabling ClearType.  ClearTypeHint can only be safely used when the developer ensures their text is being blended directly into an opaque area.

 

 

ClearTypeHint API

The property RenderOptions.ClearTypeHint has been introduced in WPF 4.0 to allow a developer to re-enable ClearType rendering on elements which have had ClearType disabled by an ancestor element. ClearTypeHint has two values which are inherited by its children.

·        Auto – This is the default behavior of WPF. If an app specifies that ClearType should be used (TextOptions.TextRenderingMode), the framework will use ClearType on all text in the visual tree until an element which disables ClearType is encountered. Any text that follows such an element will not use ClearType rendering.

·        Enabled – Re-enables ClearType rendering on an element which has had ClearType disabled by an ancestor element. Note that setting ClearTypeHint to “Enabled” makes it possible for that element or any of its children to use ClearType rendering which is controlled by TextOptions.TextRenderingMode.

 

ClearTypeHint Usage

There are a couple things to keep in mind when using ClearTypeHint.          

1)      Set ClearTypeHint below the intermediate texture in the visual tree.  If an OpacityMask is put on a TextBlock, setting ClearTypeHint on the TextBlock will not work because of the order of operations. RenderOptions are higher in the tree than OpacityMask/Effects/Clip/etc. 

2)      Ensure the text is being drawn into something opaque directly.  That means that the opaque background also needs to be set below the intermediate in the tree, otherwise the text will draw into a transparent surface first and then blend into something opaque which doesn’t work.

 

Below is the ControlTemplate for a glassy Button. The glassy effect is achieved by placing an OpacityMask on a Border element which is the parent of the ContentPresenter. The OpacityMask introduces an intermediate render texture and this disables ClearType for all children of the Border. ClearTypeHint has been set on the ContentPresenter to re-enable ClearType.

 

<ControlTemplate x:Key="GlassButton" TargetType="{x:Type Button}">

   <Border BorderBrush="#FFB0B0B0" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">

      <Border BorderBrush="#FF000000" BorderThickness="1,1,1,1"

              CornerRadius="4,4,4,4" Background="#ffE0E8FF">

         <Border.OpacityMask>

            <LinearGradientBrush StartPoint=".5,1" EndPoint=".5, 0">

               <GradientStop Color="Transparent" Offset="0"/>

               <GradientStop Color="Black" Offset=".4"/>

               <GradientStop Color="Black" Offset=".6"/>

               <GradientStop Color="Transparent" Offset="1"/>

            </LinearGradientBrush>

         </Border.OpacityMask>

         <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"

                           Width="Auto" RenderOptions.ClearTypeHint="Enabled"/>

      </Border>

   </Border>

</ControlTemplate>

NoCT Zoom

Zoomed screenshot of the button rendered without ClearTypeHint set on the ContentPresenter. Notice the grayscale text antialiasing.

 

CT Zoom

Zoomed screenshot of the button rendered with ClearTypeHint=”Enabled” set on the ContentPresenter. Notice the ClearType text antiailiasing (colored fringing).

 

 

There are a number of standard WPF 3.X controls which have ClearType rendering disabled due to an intermediate render texture. The default templates for these controls have been modified to use ClearTypeHint. If you use a modified version of WPF 3.X templates, you will have to update them to enable ClearType text rendering in these controls.

·                  ComboBox popup window

·                  DatePicker popup window

·                  MenuItem popup window

·                  ToolTip popup window

·                  ToolBarOverflow popup window

·                  NavigationWindow navigation popup window

·                  BrowserWindow navigation popup window

 

 

-Chipalo