SharpVectors 1.0 Beta
Introduction
The SVG# Reloaded project aims to provide libraries and tools to parse, convert and view the SVG on Windows, especially on the Windows Presentation Foundation platform.
Background
A few months ago, I was looking for a library to convert SVG diagrams to XAML for use in an WPF application. I initially thought some of the available open source projects could easily handle the project, but all failed. The next step was to look for a commercial library, the only one found also failed to handle the project so I have no choice but to create one since I have already told my boss it should not be a problem.
I started with the SharpVectorGraphics (aka SVG#), and hence the name SVG# Reloaded.
Project Information
This project is currently hosted on Codeplex.
The SharpVectors 1.0 is currently placed in the Beta stage to allow for more time to work on the documentation, fix bugs and accept suggestions. The final release is schedule for January, 2011.
The SVG to XAML/WPF conversion is complete enough and I have used it in the real world application.
Quick Start
The SVG# Reloaded is packaged in several .NET assemblies. The library itself is divided into two parts; the data handling (parsing and modeling) and the rendering. This makes it possible to have different rendering engines and currently we have the WPF based rendering engine and the GDI+ based rendering engine (an improvement over the original SVG# rendering but less complete compared with the WPF rendering engine).
WPF Package
For the WPF package, this is the dependency diagram:
SharpVectors.Core
: This is the core library defining all the required interfaces as defined by the W3C SVG specifications, including the events and the style sheets interfaces.
SharpVectors.Dom
: This is an extension to the .NET Framework implementation of the XML DOM (XmlDocument
) to support the SVG.
SharpVectors.Css
: This is an extension to the .NET Framework DOM to support style sheets interfaces.
SharpVectors.Model
: This is the main implementation of the SVG DOM and interfaces. This is the parser of the SVG documents, reducing the SVG file to memory model of .NET objects. This and the above assemblies do not depend on GDI+ or the WPF libraries.
SharpVectors.Runtime
: This is an optional WPF library providing SVG object specific information at the runtime. This includes conversion classes to handle GlyphTypeface.FontUri
, which will otherwise be hard-coded with the full path information that may not work on the user's machine, classes to handle embedded images etc.
SharpVectors.Rendering.Wpf
: This is WPF library, which handles the rendering of the SVG object to the WPF drawing objects.
SharpVectors.Converters
: This is WPF library, which uses the SharpVectors.Rendering.Wpf
library to perform actual conversion for viewing.
NOTE: The current WPF package will only generate low level objects; Geometry
and Drawing
. Higher level objects like Shape
are not generated, so there is no support for Silverlight.
GDI+ Package
The dependency diagram is shown below:
SharpVectors.Rendering.Gdi
: This is GDI+ library, which handles the rendering of the SVG object to the System.Drawing
objects.
Using the Code
In this section, we will provide a number of illustrative examples to demonstrate the use of this library.
These sample codes are divided into two parts; converters and controls (including markup extensions). Complete VS.NET solution for these parts are provided for download, and here is a little guide to using these projects/solutions:
Converter Samples: SharpVectorsSamples
- These are the SVG to WPF converter samples used for the tutorials, a total of 8 simple projects (in C# and VB.NET)
- For the current assembly references in the projects to be automatically resolved, extract these samples to the following directory:
SharpVectorsReloaded\Samples\SharpVectorsSamples
Markup Extension and Controls Samples: SharpVectorsControlSamples
- These are the markup extensions and controls samples used for the tutorials, a total of 6 projects.
- For the current assembly references in the projects to be automatically resolved, extract these samples to the following directory:
SharpVectorsReloaded\Samples\SharpVectorsControlSamples
Converters: Overview
The SVG to WPF conversion is the main use of this SVG# Reloaded library currently. The other uses will be improved with time.
The following is a diagram showing all the available converters.
FileSvgConverter
: This converts the SVG file to the corresponding XAML file, which can be viewed in WPF application. The root object in the converted file is DrawingGroup
.
FileSvgReader
: This converts the SVG file to DrawingGroup
and can optionally save the result to a file as XAML.
ImageSvgConverter
: This converts the SVG file to static or bitmap image, which can be saved to a file.
DirectorySvgConverter
: This converts a directory (and optionally the sub-directories) of SVG files to XAML files in a specified directory, maintaining the original directory structure.
Now, the base class SvgConverter
defines the following common properties:
Converters: Illustrative Example
We will create a simple console application for illustration, using the following sample SVG file (named, Test.svg):
="1.0" ="no"
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="6cm" height="5cm" viewBox="0 0 600 500"
xmlns="http://www.w3.org/2000/svg" version="1.1">
-->
<rect x="1" y="1" width="598" height="498"
fill="none" stroke="blue"/>
<circle cx="300" cy="225" r="100" fill="red"/>
<text x="300" y="480" font-family="Verdana"
font-size="35" text-anchor="middle">
Sample Text 1
</text>
</svg>
- Create a console .NET 3.5 framework application, name it
FileSvgConverterSample
- Add the following WPF framework assemblies:
- WindowBase.dll
- PresentationCore.dll
- PresentationFramework.dll
- Add the following SVG# Reloaded assemblies
- SharpVectors.Converters.dll
- SharpVectors.Core.dll
- SharpVectors.Css.dll
- SharpVectors.Dom.dll
- SharpVectors.Model.dll
- SharpVectors.Rendering.Wpf.dll
- SharpVectors.Runtime.dll
- Modify the generated code to the following:
For the C# Application:
using System;
using SharpVectors.Converters;
using SharpVectors.Renderers.Wpf;
namespace FileSvgConverterSample
{
class Program
{
static void Main(string[] args)
{
WpfDrawingSettings settings = new WpfDrawingSettings();
settings.IncludeRuntime = false;
settings.TextAsGeometry = true;
string svgTestFile = "Test.svg";
FileSvgConverter converter = new FileSvgConverter(settings);
converter.Convert(svgTestFile);
}
}
}
For the VB.NET Application:
Imports SharpVectors.Converters
Imports SharpVectors.Renderers.Wpf
Module MainModule
Sub Main()
Dim settings As WpfDrawingSettings = New WpfDrawingSettings()
settings.IncludeRuntime = False
settings.TextAsGeometry = True
Dim svgTestFile As String = "Test.svg"
Dim converter As FileSvgConverter = New FileSvgConverter(settings)
converter.Convert(svgTestFile)
End Sub
End Module
- Compile and run the program. An XAML file, Test.xaml, will be generated in the working directory. The output will look like this when viewed (this is the illustrative sample for
FileSvgReader
):
Markup Extensions: Overview
These are WPF markup extensions or type converters for handling the SVG files in WPF applications.
Currently, the SVG# Reloaded provides one markup extension, SvgImageExtension
, which converts an SVG source file to a DrawingImage
.
- As shown in the diagram above, all the rendering settings are available on this markup extension as properties.
- The main property here is the
SvgImageExtension.Source
, which is the path to the SVG file, and the file itself can be located in the following:
- Web/Internet: The path in this case is the HTTP, FTP, etc. scheme URI of the file.
- Local Computer Disk: The path is the absolute or the relative URI to the SVG file.
- Resources: The path is the Microsoft Pack URI of the SVG resource file.
Markup Extensions: Illustrative Example
For the illustration, we will create a simple WPF Application shown below, each image displayed is an SVG file in the WPF Image
control:
- Create a .NET 3.5 WPF Application in C# or VB.NET, we will name it
SvgImageSample
and rename the main window, MainWindow
.
- As above, add the WPF package of the SVG# Reloaded assemblies.
- Modify the generated XAML code to the following (the C# or VB.NET codes are not modified):
<Window x:Class="SvgImageSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="SvgImage Sample" Height="346" Width="409" Background="White">
<Window.Resources>
<ResourceDictionary>
<sys:String x:Key="WebFile">
http://upload.wikimedia.org/wikipedia/commons/c/c7/SVG.svg
</sys:String>
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<TabControl SelectedIndex="0" OverridesDefaultStyle="False">
<TabItem>
<TabItem.Header>By Local File</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage ../Test1.svg}"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>By Web File</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage {StaticResource WebFile}}"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>By Local/Resource File</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage Test2.svg, TextAsGeometry=True}"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>By Sub-Folder File</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage \\SubFolder\\Test3.svg}"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>By Local/Resource File</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage /Resources/Test.svg}"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>By Properties</TabItem.Header>
<TabItem.Content>
-->
<Image Source="{svgc:SvgImage Source=/Resources/Test.svg}"/>
</TabItem.Content>
</TabItem>
</TabControl>
</DockPanel>
</Window>
NOTE: As shown above, the local relative path and resource path are similar, and in this case, the local directory is searched at runtime, and if no such file is found, it is assumed to be in the resource.
- Compile and run the program.
Viewbox Control: Overview
SvgViewbox
control is a WPF Viewbox
derived control for viewing the SVG files in WPF applications, and allowing you to use all the Viewbox
decorator properties.
It wraps a drawing canvas instead of image, so will support interactivity when added to future release of the drawing canvas.
The main property is the SvgViewbox.Source
, which is an System.Uri
specifying the path to the SVG file.
Viewbox Control: Illustrative Example
For the illustration, we will create the following WPF sample application:
- Create a WPF application project, named
SvgViewboxSample
, similar to the steps in previous sections.
- Modify the XAML of the main window to the following:
<Window x:Class="SvgViewboxSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
Title="SvgViewbox Sample" Height="346" Width="430" Background="White">
<DockPanel>
<TabControl SelectedIndex="0" OverridesDefaultStyle="False">
<TabItem>
<TabItem.Header>Web File</TabItem.Header>
<TabItem.Content>
-->
<svgc:SvgViewbox Source=
"http://croczilla.com/bits_and_pieces/svg/samples/tiger/tiger.svg"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Local File 1</TabItem.Header>
<TabItem.Content>
-->
<svgc:SvgViewbox Source="../Test1.svg"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Local File 2</TabItem.Header>
<TabItem.Content>
-->
<svgc:SvgViewbox Source="Test2.svg" TextAsGeometry="True"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Sub-Folder File</TabItem.Header>
<TabItem.Content>
-->
<svgc:SvgViewbox Source="\SubFolder\Test3.svg"/>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Resource File</TabItem.Header>
<TabItem.Content>
-->
<svgc:SvgViewbox Source="/Resources/Test.svg"
Stretch="Uniform"/>
</TabItem.Content>
</TabItem>
</TabControl>
</DockPanel>
</Window>
- Compile and run the program.
Canvas Control: Overview
SvgCanvas
control is a WPF Canvas derived control for viewing the SVG files in WPF applications, and allowing you to use all the canvas properties.
- It derives from a drawing canvas instead of the generic canvas control, so will support interactivity when added to future release of the drawing canvas.
- The main property is the
SvgCanvas.Source
, which is an System.Uri
specifying the path to the SVG file.
Canvas Control: Illustrative Example
For the illustration, we will create the following WPF sample application:
- Create a WPF application project, named
SvgCanvasSample
, similar to the steps above.
- Modify the XAML of the main window to the following:
<Window x:Class="SvgCanvasSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
Title="SvgCanvas Sample" Height="332" Width="413" Background="White">
<DockPanel>
<TabControl SelectedIndex="0" OverridesDefaultStyle="False">
<TabItem>
<TabItem.Header>Web File</TabItem.Header>
<TabItem.Content>
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
-->
<svgc:SvgCanvas Source=
"http://croczilla.com/bits_and_pieces/svg/samples/butterfly/butterfly.svg"/>
</ScrollViewer>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Local File 1</TabItem.Header>
<TabItem.Content>
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
-->
<svgc:SvgCanvas Source="../Test1.svg"/>
</ScrollViewer>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Local File 2</TabItem.Header>
<TabItem.Content>
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
-->
<svgc:SvgCanvas Source="Test2.svg"/>
</ScrollViewer>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Sub-Folder File</TabItem.Header>
<TabItem.Content>
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
-->
<svgc:SvgCanvas Source="\SubFolder\Test3.svg"/>
</ScrollViewer>
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>Resource File</TabItem.Header>
<TabItem.Content>
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
-->
<svgc:SvgCanvas Source="/Resources/Test.svg"/>
</ScrollViewer>
</TabItem.Content>
</TabItem>
</TabControl>
</DockPanel>
</Window>
- Compile and run the program.
Sample Applications
The SVG# Reloaded comes with some applications. The following two may be of interest to you.
WpfTestSvgSample
This is an application for browsing directory (recursively) of SVG files.
WpfW3CSvgTestSuite
This is an application for viewing the W3C Test Suite compliant results. It has two panes: top and bottom. The top pane is the generated WPF output, the bottom pane is the W3C expected output image.
By the test results, SVG# Reloaded is the most complete SVG reader for WPF!
You can download the strip-down test suite from the project site, since the size is still large for CodeProject file upload limit.
Points of Interest
Many parts of WPF are still work in progress. For instance, vertical texts (as in Japanese), which are supported well in GDI+ are still missing. Previously, the team claimed it was due to lack of time, but with WPF 4.0 released without it, one cannot tell their next excuse!
Credits
The SVG# Reloaded uses source codes from articles and other open source projects without which this might not be possible. We wish to acknowledge and thank the authors of these great articles and projects:
Conclusion
This is the most complete library available to handle the conversion of SVG files to WPF, that I know of. However, SVG itself is a large and complex specification, and even though one will expect the most modern framework, WPF, to easily handle this decade old specification, it is not able.
In this release, the conversion to WPF is complete enough, however, the controls will need some improvements before the final release.
In future version releases, I will work further on the support of the specifications. Any help in this direction is highly welcomed.
History
- November 16, 2010: Initial release of SharpVectors 1.0 Beta
- November 17, 2010: Improved formatting and added credits section