Silverlight and XAML, have you guys met Old Man SVG?
Summary
XAML uses a vector graphics markup which is very similar to SVG, but since it's part of a complete application framework the designers decided to use a slightly different format. I'd expect that XAML would be able to load SVG, or that there would at least be plenty of tools to convert SVG to XAML, but it was tougher than I thought. After some background, I'll discuss some solutions I found.
UPDATE: Please don't jump the gun and assume that I'm complaining that XAML should have just used SVG. I'm not. I'm saying that it should be a lot easier to get SVG content into XAML format, preferably on the fly. While this post points to some tools to convert SVG to XAML, I didn't find a solution that was both free for public use and worked perfectly on my test files. In my opinion, XAML adoption would really benefit from SVG import or at least conversion.
XAML and SVG, separated at birth?
Windows Presentation Foundation introduced vector graphics as a first class citizen in the desktop development arena. XAML, the language used to define WPF applications, contains pretty good support for describing vector graphic images.
Of course, there was already a pre-existing W3C standard for vector graphics - SVG - which is supported in most modern browsers except Internet Explorer. Why doesn't WPF just use SVG for vector graphics? That question's pretty quickly answered when you start to actually study WPF - WPF is an entire application framework, and the vector graphics portion was written to fit with the rest of the framework. Ian Griffiths described it pretty well back in 2004:
"On the face of it, it seems strange to invent a new way of representing vector graphics in markup when a standard already exists. However, the principal advantage of these shape classes is that they have been designed to integrate into the Avalon programming model. The vector drawing elements derive from the same FrameworkElement base class as all other XAML elements, and follow the same naming conventions...
By not using SVG, Avalon ensures that vector graphics can be mixed in with any other kind of markup in your XAML, and can take advantage of all of the same layout facilities."
Aside: XUL, Mozilla's XML User Interface Language, took a different approach by aggregating existing technologies such as HTML, CSS, SVG, and Javascript. The benefit is that it uses accepted standards, but the tradeoff is that it's not as cohesive and consistent as the WPF system.
Microsoft doesn't care about SVG people!
However, the actual vector graphics code in these systems is remarkably similar, and it's a shame that XAML seems completely oblivious to the pre-existing SVG standard. This is of course an even bigger question now that Microsoft's new web technology, Silverlight is as ignorant of SVG as Internet Explorer's always been.
UPDATE: To clarify, I'm not saying that I think XAML should change, just that it should be able to import SVG. What I'd really like to see is something like is something like the XamlReader.Load() for SVG. SvgReader.Load() would pull SVG content into valid XAML and allow me to pop it into a content section.
I've been surprised at the lack of support and / or interest in loading SVG into WPF. SVG (scalable vector graphics) and WPF shapes are very similar. Compare the SVG and XAML code to create the Windows logo:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 105 95">
<path fill="#7B4" d="M106,13c-21,9-31,4-40-2l-10,35c9,6,20,11,40,2l10-35z"/>
<path fill="#49c" d="M39,83c-9-6-18-10-39-2l10-35c21-9,31-4,39,2l-10,35z"/>
<path fill="#E63" d="M51,42c-5-4-11-7-19-7c-6,0-12,1-20,5l10-35c20-8,30-4,39,2l-10,35z"/>
<path fill="#FD5" d="M55,52c9,6,18,10,39,2l-10,35c-21,8-30,3-39-3l10-34z"/>
</svg>
Now in XAML:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Path Data="M106,13c-21,9-31,4-40-2l-10,35c9,6,20,11,40,2l10-35z" Fill="#7B4"/>
<Path Data="M39,83c-9-6-18-10-39-2l10-35c21-9,31-4,39,2l-10,35z" Fill="#49c"/>
<Path Data="M51,42c-5-4-11-7-19-7c-6,0-12,1-20,5l10-35c20-8,30-4,39,2l-10,35z" Fill="#E63"/>
<Path Data="M55,52c9,6,18,10,39,2l-10,35c-21,8-30,3-39-3l10-34z" Fill="#FD5"/>
</Canvas>
Unfortunately, Microsoft seems to have decided to pretend that SVG just doesn't exist. Expression only works with XAML, and has no SVG import or export. Microsoft seems to see SVG as nothing more than the native format of their competitor, Adobe Illustrator, rather than the most widely accepted and used vector graphics file format. The only Microsoft application I can think of that supports SVG is Visio, and only via export.
The quest for the SVG to XAML converter
Since WPF is ignorant to SVG's existence, I went looking for an SVG to XAML converter. Since the formats are so similar, I figured it would be a no-brainer. Not so.
- SVG2XAML was discontinued in 2004. SharpVectorGraphics (SVG#), which powered SVG2XAML, was abandoned in 2005; the latest version wouldn't build for me.\
- Xamalon had support for Adobe Illustrator's SVG format, but unfortunately they were ahead of their time and couldn't hold out waiting for the long, long, Longhorn release.
- There's an Adobe Illustrator SVG to XAML converter, but it requires Illustrator. I'm an Inkscape user, though, so that's no help to me.
I was looking into starting an SVG to XAML project when I finally started finding some answers.
WPF-Graphics.com helped me to lose weight and pick up chicks
WPF-Graphics has some cool class libraries which convert a variety of vector formats to XAML, including SVG. The SVG reader, WPF-Graphics ReaderSVG, allows for loading from an SVG resource (locally of via URI) via some really simple code:
Viewbox svgButton = Ab2d.ReaderSvg.Instance.Read("openButton.svg"); myButtonsStackPanel.Children.Add(svgButton);
The sample application did a decent job with loading the basic paths for some of the SVG files I had sitting around (apologies, Scott). It didn't handle embedded bitmaps well, especially in dealing with absolute vs. relative coordinates which seems to be one of the tricky differences between SVG and XAML.
It's a free download, so give it a spin. Note that you'll need to have the Visual Studio 2005 extensions for .NET Framework 3.0 (November 2006 CTP) installed to build the project. The only bad thing I can think to say about Ab2d.ReaderSvg is the licence, which restricts use in a commercial program without the author's permission; I wonder if there's a cost involved and, if so, what it is.
Anything worthwhile can be done in Javascript...
Also very interesting is Sam Ruby's a javascript SVG to XAML converter that's working pretty well (information here, demo here). Here's a direct link to the javascript file.
Let's hear it for sleazy hacks
There's another way - eddwo's Cheap Trick for SVG > XAML Conversion:
1. Open the SVG in Inkscape.
2. Save it as a PDF.
3. Open the PDF in Adobe Reader.
4. Print the PDF to "Microsoft XPS Document Writer"
5. Rename the xps to zip.
6. From the zip extract out /Documents/1/Pages/1.fpage
7. Rename the fpage to xaml.
Within the file the top level element is FixedPage, which contains a Canvas with the relevant paths. You can pull out just the path data and use it in your app.
Rather a long way around, but it seems quite effective.
You can't print straight to the xps writer from inkscape, as it just prints as a bitmap rather than preserving the vectors.