Improved Gradient Conversion from Illustrator to WPF (and DrawingBrush)

I put my Flash experimentation on hold this past weekend and decided to add a little bit of functionality to my Adobe Illustrator to WPF/XAML Export Plug-In. The current version is still 0.14, and it works well with the February CTP of WPF. However, if you're interested in gradients or DrawingBrushes, read on.

First, I'd like to mention the mental retching that I experience by moving between these two projects. The Illustrator plug-in is written in C/C++, a language that I mostly forgot about nearly six years ago. Additionally, the Illustrator object model is different enough from WPF that it takes some cognitive gymnastics to recall how an element in Illustrator maps to another element (or elements) in WPF. The plug-in has no WPF dependencies, and it essentially spits out XML strings.

The Flash stuff, on the other hand, is a completely different world. It's all written in C#, has an actual WinFX dependency, uses the WPF object model, and serializes out to XAML. The managed code development environment of C# and WinFX is so much more productive as to be almost ridiculous; I make a lot more progress in a shorter period of time. The Flash file format is interesting, and the data storage formats can be tricky, but it's nothing that a little thinking can't overcome. But I digress...

The Illustrator plug-in has converted gradients since its first version. However, as soon as you transformed the artwork from its original location on the page, the artwork would transform properly during export, but the gradients most definitely wouldn't. If you had a bunch of small gradients, this might not have been noticeable, but for anything significant, it would look very ugly. Due to differences between the Illustrator and WPF coordinate systems, I could never find a way to make an accurate conversion. You'll be happy to know that gradient transformations are now fully supported, and in my initial testing, they work as-expected. I'd still like to simplify the resulting XAML a bit, but it's good enough for now.

I've also added support for Illustrator's gradient midpoints. If you look at the gradient tab in Illustrator (diagram to the right), you'll see that in addition to the five colors I've defined along the bottom, there are also small diamond-like sliders above the gradient. You can adjust these sliders by dragging them, and they represent the point where the color is a 50/50 mix of its adjacent colors. Illustrator allows these midpoints to fall anywhere between 13 and 87 percent of the distance between the two colors, and by manipulating them, you can achieve some nice effects.

Well, WPF doesn't support this midpoint concept for gradients. So, to achieve a similar result, the export plug-in looks at the midpoint value, and if it isn't exactly 50% (the default), it adds another WPF gradient stop at the correct location with a color that is computed to be a 50/50 mix of the colors to either side. If you look at the sample gradients in the diagram, version 0.14 shows "blurrier" yellow and blue bands, where the test version of 0.15 looks much more like the gradient as defined in Illustrator. The improvement is due entirely to the additional gradient stops.

If you were to compare the exported XAML between version 0.14 and version 0.15 for this same gradient definition, version 0.14 would have five colors. Version 0.15 outputs eight. Why eight instead of nine? After all, if you add the five colors and the four midpoints, shouldn't there be nine unique color stops? There would be, except that the third midpoint between red and blue happens to lie at exactly 50%. Since the normal WPF color blending works just fine for a midpoint of 50%, the plug-in simply skips it.

The last little improvement is to add support for exporting artwork to a DrawingBrush. If you're not creating a collection of interactive shapes, there's no reason to pay the penalty of full UI elements. Drawings are smaller and faster than shape objects, because they offer fewer features. If you're going to use your Illustrator artwork to define the look of a single UI element (like an icon), then it probably makes sense to use the DrawingBrush format to fill the icon with the exported XAML. If you're unclear about the differences, it's worth reading the Drawing Objects Overview and Shapes and Basic Drawing in the Windows Presentation Foundation from the Windows SDK documentation.

Since I don't want to pop-up a dialog box during my testing, version 0.15 of the plug-in currently exports to DrawingBrush format if you hold down the right shift key during export. Note that I haven't added clipping support to the DrawingBrush export, so that won't work at all. There are probably other DrawingBrush bugs that I haven't encountered yet, so please let me know if you find anything.

So, after all of that, if you're willing to put up with possible DrawingBrush and/or gradient bugs, feel free to help test version 0.15 of the plug-in.

Enjoy!