Charles Petzold

Manipulating Character Outlines in Silverlight

October 11, 2009
New York, N.Y.

In the blog entry Using Text Outlines in Silverlight I described a WPF program called TextOutlineGenerator that converts the outlines of a particular text string in a particular font to XAML, which can then be copied into a Silverlight program. I have a new version of TextOutlineGenerator with a few more features: It can now separate the text into letters, format the XAML, and strip the XAML of references to the IsStroked and IsSmoothJoin properties, which aren't supported in Silverlight. In addition, the program displays the size of the FormattedText object (or objects, if letters are separated).

I needed those features for the following experimental Silverlight app:


As you might deduce from the image, the program lets you interactively manipulate the straight lines and Bezier curves that define the outlines of letters in the text string. It's basically just an experiment about manipulating individual points of a PathGeometry. There is no way to save your "work."

All the interaction is through Thumb objects. Each of the letters is a Path on top of an (invisible) Thumb, and when that Thumb is clicked, the program creates four Thumb objects for the four corners of the character box, and one Thumb object for every Point in the PathGeometry defining the letter.

Most of the code in MainPage.xaml.cs is dedicated to keeping all these Thumb objects and the points of the PathGeometry synchronized. The Thumb objects are positioned using the Canvas.Left and Canvas.Top attached properties. The PathGeometry objects defining the letters are positioned based solely on the Point coordinates. No Transform properties are set, but transforms are instead applied to the points of the PathGeometry through the static PathGeometryHelper.Transform method in the project.

Here's the ManipulateCharacterOutlines source code. As with any Silverlight project, I discovered several mysterious issues. For example, the Thumb class is sealed for no apparent reason. Consequently, I used the Tag property to store information with each Thumb.

The text itself came out of TextOutlineGenerator, with a Times New Roman font, a point size of 144, separating letters and separating components, which creates a bunch of PathFigure objects that I copied into the Resources section of MainPage.xaml. I originally wanted to enclose the multiple components of each letter in a PathFigureCollection but that didn't work, and I couldn't use a custom collection either, so eventually I enclosed all the PathFigure objects for each letter in a PathGeometry and then put all these PathGeometry objects in an ItemsControl. I couldn't think of anything else that would store a collection of PathGeometry objects and work in a Resources section (which in Silverlight is very fussy).