Layout Rounding

WPF’s layout engine frequently gives elements sub-pixel positions. Antialiasing algorithms cause these sub-pixel positioned elements to be rendered over multiple physical pixels after filtering. This can result in blurry lines and other non desirable rendering artifacts. Layout rounding has been introduced in WPF 4.0 to allow developers to force the WPF layout system to position elements on pixel boundaries, eliminating many of the negative side effects of sub-pixel positioning.

Two common situations where negative side effects display themselves are grid and image rendering. Many times grids are created using “star sizing,” resulting in all rows having proportional sizes (The same technique can be used for columns. For simplicity's sake, I will just refer to rows in this post). If the space being divided into rows is not a multiple of the smallest row, each row will have a fractional size. When this occurs, the content of each row will be antialiased at row boundaries. An example of this is below. The effect of the antialiasing creates the banding effect.

<Grid Height="100" Width="200">

<Grid.RowDefinitions>

<RowDefinition Height="*"/>

<RowDefinition Height="*"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<Rectangle Grid.Row="0" Fill="DarkBlue"/>

<Rectangle Grid.Row="1" Fill="DarkBlue"/>

<Rectangle Grid.Row="2" Fill="DarkBlue"/>

</Grid>

XAML for a grid that uses “star sizing” to measure row height. Each row will have a height of 33.33… since the total space for all rows is 100, and this space must be divided equally between three rows.

 

grid banding

The grid rendered from the above XAML and zoomed to 200%. Since the only contents of each row are a dark blue Rectangles, one could reasonably expect a solid dark blue window. Without layout rounding, seams will be rendered at the row boundaries. These are artifacts from antialiasing.

Image clarity can also be improved by layout rounding. Bitmap images contain color information for individual pixels.

 

smiley2

A bitmap image of a smiley face. Each red square represents one image pixel.

 

If an image is not placed on whole pixel boundaries, the color of one physical pixel has contributions from multiple image pixels. This results in a blurry rendered image.

 

smiley rendered

The bitmap image from above is placed at (1.5, 1.5). This results in the color of each physical pixel (black) depending on the color of 4 image pixels (red).

 

 

Below are a couple examples of the effect that sub-pixel image positioning can have on the clarity of an image.

squares

The left image is the original. The right image is rendered on sup-pixel boundaries

 

lady

The left image is the original. The right image is rendered on sup-pixel boundaries

 

Layout Rounding API

The attached property UseLayoutRounding has been introduced to allow layout rounding functionality to be toggled on or off.

This property can either be True or False. The value of this property is inherited by an element’s children.

· True – This element will use layout rounding

· False (default) – This element will not use layout rounding

Code snipit of this property in action

<Grid UseLayoutRounding="True" Height="100" Width="200">

<Grid.RowDefinitions>

<RowDefinition Height="*"/>

<RowDefinition Height="*"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<Rectangle Grid.Row="0" Fill="DarkBlue"/>

<Rectangle Grid.Row="1" Fill="DarkBlue"/>

<Rectangle Grid.Row="2" Fill="DarkBlue"/>

</Grid>

no grid banding

The grid rendered from the above XAML and zoomed to 200%. Notice that setting UseLayoutRounding=”True” resolved the banding issue in the image above.

UseLayoutRounding Usage

Layout rounding should be used in UI scenarios where the exact location of objects can be sacrificed for overall appearance of the application. Since rounding of layout parameters occurs when using this feature, precise element placement is lost. A few of the effects layout rounding can have on exact layout are…

· width and or height of elements may grow or shrink by at most1 pixel

· placement of an object can move by at most 1 pixel

· centered elements can be vertically or horizontally off center by at most1 pixel

If your app has an unexpectedly blurry image or icon, fuzzy lines or borders that should be crisp, or grid banding try using layout rounding.

-Chipalo