diff --git a/Source/DataTypes/SvgUnit.cs b/Source/DataTypes/SvgUnit.cs
index 3c437bd6008662f47bd7fc16909448ce562faa9d..86dd7e8a3ffee1ac2fb3371d399cc02eece52cd6 100644
--- a/Source/DataTypes/SvgUnit.cs
+++ b/Source/DataTypes/SvgUnit.cs
@@ -21,12 +21,12 @@ namespace Svg
///
/// Gets and empty .
///
- public static readonly SvgUnit Empty = new SvgUnit();
+ public static readonly SvgUnit Empty = new SvgUnit(SvgUnitType.User, 0);
///
/// Gets an with a value of none.
///
- public static readonly SvgUnit None = new SvgUnit(SvgUnitType.None,0f);
+ public static readonly SvgUnit None = new SvgUnit(SvgUnitType.None, 0f);
///
/// Gets a value to determine whether the unit is empty.
diff --git a/Source/Painting/EnumConverters.cs b/Source/Painting/EnumConverters.cs
index 3e4ab87f6f8c7852d43c94ad7680faadc424dc46..96b7ba7701b982b583d9ead2134d4c8c88fc9370 100644
--- a/Source/Painting/EnumConverters.cs
+++ b/Source/Painting/EnumConverters.cs
@@ -1,110 +1,118 @@
-using System;
-using System.ComponentModel;
-using System.Globalization;
-
-namespace Svg
-{
-
- //just overrrides canconvert and returns true
- public class BaseConverter : TypeConverter
- {
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- if (sourceType == typeof(string))
- {
- return true;
- }
-
- return base.CanConvertFrom(context, sourceType);
- }
-
- public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
- {
- if (destinationType == typeof(string))
- {
- return true;
- }
-
- return base.CanConvertTo(context, destinationType);
- }
- }
-
- public sealed class SvgBoolConverter : BaseConverter
- {
- public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
- {
- if (value == null)
- {
- return true;
- }
-
- if (!(value is string))
- {
- throw new ArgumentOutOfRangeException("value must be a string.");
- }
-
- return (string)value == "visible" ? true : false;
- }
-
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
- {
- if (destinationType == typeof(string))
- {
- return ((bool)value) ? "visible" : "hidden";
- }
-
- return base.ConvertTo(context, culture, value, destinationType);
- }
- }
-
- //converts enums to lower case strings
- public class EnumBaseConverter : BaseConverter
- {
- public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
- {
- if (value == null)
- {
- return Activator.CreateInstance(typeof(T));
- }
-
- if (!(value is string))
- {
- throw new ArgumentOutOfRangeException("value must be a string.");
- }
-
- return (T)Enum.Parse(typeof(T), (string)value, true);
- }
-
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
- {
- if (destinationType == typeof(string))
- {
- return ((T)value).ToString().ToLower();
- }
-
- return base.ConvertTo(context, culture, value, destinationType);
- }
- }
-
- //implementation for fill-rule
- public sealed class SvgFillRuleConverter : EnumBaseConverter
- {
- }
-
- //implementaton for clip rule
- public sealed class SvgClipRuleConverter : EnumBaseConverter
- {
- }
-
- //implementaton for clip rule
- public sealed class SvgTextAnchorConverter : EnumBaseConverter
- {
- }
-
- //implementaton for preserve aspect ratio
- public sealed class SvgPreserverAspectRatioConverter : EnumBaseConverter
- {
- }
-
-}
+using System;
+using System.ComponentModel;
+using System.Globalization;
+
+namespace Svg
+{
+
+ //just overrrides canconvert and returns true
+ public class BaseConverter : TypeConverter
+ {
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ {
+ return true;
+ }
+
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
+ {
+ if (destinationType == typeof(string))
+ {
+ return true;
+ }
+
+ return base.CanConvertTo(context, destinationType);
+ }
+ }
+
+ public sealed class SvgBoolConverter : BaseConverter
+ {
+ public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+
+ if (!(value is string))
+ {
+ throw new ArgumentOutOfRangeException("value must be a string.");
+ }
+
+ return (string)value == "visible" ? true : false;
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (destinationType == typeof(string))
+ {
+ return ((bool)value) ? "visible" : "hidden";
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+
+ //converts enums to lower case strings
+ public class EnumBaseConverter : BaseConverter
+ {
+ public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
+ {
+ if (value == null)
+ {
+ return Activator.CreateInstance(typeof(T));
+ }
+
+ if (!(value is string))
+ {
+ throw new ArgumentOutOfRangeException("value must be a string.");
+ }
+
+ return (T)Enum.Parse(typeof(T), (string)value, true);
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (destinationType == typeof(string))
+ {
+ return ((T)value).ToString().ToLower();
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+
+ //implementation for fill-rule
+ public sealed class SvgFillRuleConverter : EnumBaseConverter
+ {
+ }
+
+ //implementaton for clip rule
+ public sealed class SvgClipRuleConverter : EnumBaseConverter
+ {
+ }
+
+ //implementaton for clip rule
+ public sealed class SvgTextAnchorConverter : EnumBaseConverter
+ {
+ }
+
+ //implementaton for preserve aspect ratio
+ public sealed class SvgPreserverAspectRatioConverter : EnumBaseConverter
+ {
+ }
+
+ public sealed class SvgStrokeLineCapConverter : EnumBaseConverter
+ {
+ }
+
+ public sealed class SvgStrokeLineJoinConverter : EnumBaseConverter
+ {
+ }
+
+}
diff --git a/Source/Painting/SvgStrokeLineCap.cs b/Source/Painting/SvgStrokeLineCap.cs
index 41a94e23a949773e204a9f0e9c206920e454339f..f937e7f778fe366a34cdb46e440c9a2c24f64421 100644
--- a/Source/Painting/SvgStrokeLineCap.cs
+++ b/Source/Painting/SvgStrokeLineCap.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
+using System.ComponentModel;
namespace Svg
{
+ [TypeConverter(typeof(SvgStrokeLineCapConverter))]
public enum SvgStrokeLineCap
{
Butt,
diff --git a/Source/Painting/SvgStrokeLineJoin.cs b/Source/Painting/SvgStrokeLineJoin.cs
index 7a81a2ee24cc6f7fd6af7c6897dd127e44cccca5..7af2288ae07950cce802fec03ab44d83fb2f59b0 100644
--- a/Source/Painting/SvgStrokeLineJoin.cs
+++ b/Source/Painting/SvgStrokeLineJoin.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
+using System.ComponentModel;
namespace Svg
{
+ [TypeConverter(typeof(SvgStrokeLineJoinConverter))]
public enum SvgStrokeLineJoin
{
Miter,
diff --git a/Source/Paths/SvgPathBuilder.cs b/Source/Paths/SvgPathBuilder.cs
index b290edcb49edc48fd6b9fcc298a0ea49e606128e..a08375074e671b70e8c5bb86d95abda31bf455da 100644
--- a/Source/Paths/SvgPathBuilder.cs
+++ b/Source/Paths/SvgPathBuilder.cs
@@ -18,7 +18,7 @@ namespace Svg
}
}
- internal class SvgPathBuilder : TypeConverter
+ public class SvgPathBuilder : TypeConverter
{
///
/// Parses the specified string into a collection of path segments.
@@ -46,6 +46,20 @@ namespace Svg
isRelative = char.IsLower(command);
// http://www.w3.org/TR/SVG11/paths.html#PathDataGeneralInformation
+ CreatePathSegment(command, segments, coords, isRelative);
+ }
+ }
+ catch (Exception exc)
+ {
+ Trace.TraceError("Error parsing path \"{0}\": {1}", path, exc.Message);
+ }
+
+ return segments;
+ }
+
+ public static void CreatePathSegment(char command, SvgPathSegmentList segments, List coords, bool isRelative)
+ {
+
switch (command)
{
case 'm': // relative moveto
@@ -148,14 +162,6 @@ namespace Svg
segments.Add(new SvgClosePathSegment());
break;
}
- }
- }
- catch (Exception exc)
- {
- Trace.TraceError("Error parsing path \"{0}\": {1}", path, exc.Message);
- }
-
- return segments;
}
private static PointF Reflect(PointF point, PointF mirror)
diff --git a/Source/Svg.csproj b/Source/Svg.csproj
index a365fd4a9e50efad77a606c930daf1fdb1e833c4..7704593b486c91a179066ce19b8e7f61c66f96e4 100644
--- a/Source/Svg.csproj
+++ b/Source/Svg.csproj
@@ -121,6 +121,7 @@
+
diff --git a/Source/SvgDefinitionDefaults.cs b/Source/SvgDefinitionDefaults.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7896e4d276bed62944449cb70727ebb6fbfa1c1a
--- /dev/null
+++ b/Source/SvgDefinitionDefaults.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Svg
+{
+ ///
+ /// Holds a dictionary of the default values of the SVG specification
+ ///
+ public static class SvgDefaults
+ {
+ //internal dictionary for the defaults
+ private static readonly Dictionary _defaults = new Dictionary();
+
+ static SvgDefaults()
+ {
+ _defaults["viewBox"] = "0, 0, 0, 0";
+
+ _defaults["visibility"] = "visible";
+ _defaults["opacity"] = "1";
+ _defaults["clip-rule"] = "nonzero";
+
+ _defaults["transform"] = "";
+
+ _defaults["fill"] = "Black";
+ _defaults["fill-opacity"] = "1";
+ _defaults["fill-rule"] = "nonzero";
+
+ _defaults["stroke"] = "none";
+ _defaults["stroke-opacity"] = "1";
+ _defaults["stroke-width"] = "1";
+ _defaults["stroke-miterlimit"] = "4";
+ _defaults["stroke-linecap"] = "butt";
+ _defaults["stroke-linejoin"] = "miter";
+ _defaults["stroke-dasharray"] = "none";
+ _defaults["stroke-dashoffset"] = "0";
+ }
+
+ ///
+ /// Checks whether the property value is the default value of the svg definition.
+ ///
+ /// Name of the svg attribute
+ /// .NET value of the attribute
+ public static bool IsDefault(string attributeName, string value)
+ {
+ if (_defaults.ContainsKey(attributeName))
+ {
+ if (_defaults[attributeName] == value) return true;
+ else if (attributeName == "fill") return value == "#000000";
+ }
+ return false;
+ }
+ }
+}
diff --git a/Source/SvgElement.cs b/Source/SvgElement.cs
index 6bb904315bb0de3c7bb0177289330322015fff78..1f299452e74b2f727559b601b150182f35561b1d 100644
--- a/Source/SvgElement.cs
+++ b/Source/SvgElement.cs
@@ -22,6 +22,7 @@ namespace Svg
private SvgElementCollection _children;
private static readonly object _loadEventKey = new object();
private Matrix _graphicsMatrix;
+ private Dictionary _customAttributes;
///
/// Gets the name of the element.
@@ -137,6 +138,11 @@ namespace Svg
}
}
+ public Dictionary CustomAttributes
+ {
+ get { return this._customAttributes; }
+ }
+
///
/// Applies the required transforms to .
///
@@ -276,12 +282,13 @@ namespace Svg
this._children = new SvgElementCollection(this);
this._eventHandlers = new EventHandlerList();
this._elementName = string.Empty;
+ this._customAttributes = new Dictionary();
}
public virtual void InitialiseFromXML(XmlTextReader reader, SvgDocument document)
{
-
+ throw new NotImplementedException();
}
@@ -343,25 +350,27 @@ namespace Svg
if (propertyValue != null)
{
var type = propertyValue.GetType();
+ string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
- object defaultValue = null;
- if(type.IsValueType)
- defaultValue = Activator.CreateInstance(type);
-
- if (!propertyValue.Equals(defaultValue) || type == typeof(float) || type == typeof(bool) || type == typeof(SvgColourServer))
+ if (!SvgDefaults.IsDefault(attr.Attribute.Name, value))
{
- string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
-
writer.WriteAttributeString(attr.Attribute.NamespaceAndName, value);
}
}
else if(attr.Attribute.Name == "fill") //if fill equals null, write 'none'
{
string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
- writer.WriteAttributeString(attr.Attribute.NamespaceAndName, value);
+ writer.WriteAttributeString(attr.Attribute.NamespaceAndName, value);
}
}
}
+
+ //add the custom attributes
+ foreach (var item in this._customAttributes)
+ {
+ writer.WriteAttributeString(item.Key, item.Value);
+ }
+
}
protected virtual void Write(XmlTextWriter writer)
diff --git a/Source/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/Source/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
index 341b11fa1d2075dabeb44ceb8a9ee60708224484..1867c4d45b05c10adbe13ba39fb031dbc657acf9 100644
Binary files a/Source/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache and b/Source/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/Source/obj/Release/ResolveAssemblyReference.cache b/Source/obj/Release/ResolveAssemblyReference.cache
deleted file mode 100644
index b74b5ef69b54cde8674c69ea59c6b5f0592e900d..0000000000000000000000000000000000000000
Binary files a/Source/obj/Release/ResolveAssemblyReference.cache and /dev/null differ