Implementing TextRunTypographyProperties

Low-level text rendering in WPF is achieved by implementing a TextSource class that returns TextRun objects which have TextRunProperties describing the formatting of the text. The TextSource is passed to a TextFormatter, which reads the runs and the properties and lays out the glyphs appropriately.

Recently we received a bug report that the furtive pataḥ was not being positioned correctly: it was centred under the consonant instead of being displayed to the right. However, this only happened when it was laid out by using the TextFormatter directly, instead of using a high-level class like TextBlock or FormattedText. Thus, we knew it was a bug in our code, and not a fundamental Hebrew display problem in WPF.

One inconvenience when using the low-level text formatting APIs is that many of the public types are abstract base classes that have to be implemented almost entirely from scratch. TextRunTypographyProperties, in particular, has over 40 abstract properties that must be implemented.

I eventually traced the problem to the use of typography properties. If the TextRunProperties.TypographyProperties property is null, WPF uses a default set of typography properties (this produced the correct output); otherwise it uses the properties from that instance (this produced the incorrect output). Further investigation revealed that setting the TextRunTypographyProperties.ContextualAlternates property to true caused the pataḥ to be positioned correctly.

Furtive Patah positioning

When we first implemented our own TextRunTypographyProperties class, we just let .NET initialise all the properties to their default values (false, 0, etc.), and then turned on a couple of properties we wanted: standard ligatures and old-style numerals. However, there are four properties that are documented as being true by default: ContextualAlternates, ContextualLigatures, Kerning, and StandardLigatures. Strictly speaking, the documentation is incorrect: these properties can’t be true by default, because TextRunTypographyProperties is an abstract class that has no default implementation. But if you are providing your own implementation, it would be wise to heed the documentation and set those properties to true by default.

Posted by Bradley Grainger on December 22, 2009