diff --git a/Samples/SVGViewer/SvgViewer.Designer.cs b/Samples/SVGViewer/SvgViewer.Designer.cs
index c0b42f9ebc424630d4ce85826184621e0cc6fae0..4b78ae343d19f1acd6f8e06ed6ddbc59006b3e74 100644
--- a/Samples/SVGViewer/SvgViewer.Designer.cs
+++ b/Samples/SVGViewer/SvgViewer.Designer.cs
@@ -28,74 +28,79 @@
///
private void InitializeComponent()
{
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SVGViewer));
- this.toolStrip1 = new System.Windows.Forms.ToolStrip();
- this.open = new System.Windows.Forms.ToolStripButton();
- this.svgImage = new System.Windows.Forms.PictureBox();
- this.openSvgFile = new System.Windows.Forms.OpenFileDialog();
- this.textBox1 = new System.Windows.Forms.TextBox();
- this.toolStrip1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.svgImage)).BeginInit();
- this.SuspendLayout();
- //
- // toolStrip1
- //
- this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.open});
- this.toolStrip1.Location = new System.Drawing.Point(0, 0);
- this.toolStrip1.Name = "toolStrip1";
- this.toolStrip1.Size = new System.Drawing.Size(1060, 25);
- this.toolStrip1.TabIndex = 0;
- this.toolStrip1.Text = "toolStrip1";
- //
- // open
- //
- this.open.Image = ((System.Drawing.Image)(resources.GetObject("open.Image")));
- this.open.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.open.Name = "open";
- this.open.Size = new System.Drawing.Size(53, 22);
- this.open.Text = "Open";
- this.open.Click += new System.EventHandler(this.open_Click);
- //
- // svgImage
- //
- this.svgImage.Dock = System.Windows.Forms.DockStyle.Left;
- this.svgImage.Location = new System.Drawing.Point(0, 25);
- this.svgImage.Name = "svgImage";
- this.svgImage.Size = new System.Drawing.Size(565, 449);
- this.svgImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
- this.svgImage.TabIndex = 1;
- this.svgImage.TabStop = false;
- //
- // openSvgFile
- //
- this.openSvgFile.Filter = "Vector Graphics (*.svg)|*.svg";
- //
- // textBox1
- //
- this.textBox1.Location = new System.Drawing.Point(571, 25);
- this.textBox1.MaxLength = 327670;
- this.textBox1.Multiline = true;
- this.textBox1.Name = "textBox1";
- this.textBox1.Size = new System.Drawing.Size(477, 446);
- this.textBox1.TabIndex = 2;
- this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
- //
- // SVGViewer
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1060, 474);
- this.Controls.Add(this.textBox1);
- this.Controls.Add(this.svgImage);
- this.Controls.Add(this.toolStrip1);
- this.Name = "SVGViewer";
- this.Text = "SVG Viewer";
- this.toolStrip1.ResumeLayout(false);
- this.toolStrip1.PerformLayout();
- ((System.ComponentModel.ISupportInitialize)(this.svgImage)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SVGViewer));
+ this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.open = new System.Windows.Forms.ToolStripButton();
+ this.svgImage = new System.Windows.Forms.PictureBox();
+ this.openSvgFile = new System.Windows.Forms.OpenFileDialog();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.toolStrip1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.svgImage)).BeginInit();
+ this.SuspendLayout();
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.open});
+ this.toolStrip1.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.Size = new System.Drawing.Size(1060, 25);
+ this.toolStrip1.TabIndex = 0;
+ this.toolStrip1.Text = "toolStrip1";
+ //
+ // open
+ //
+ this.open.Image = ((System.Drawing.Image)(resources.GetObject("open.Image")));
+ this.open.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.open.Name = "open";
+ this.open.Size = new System.Drawing.Size(56, 22);
+ this.open.Text = "Open";
+ this.open.Click += new System.EventHandler(this.open_Click);
+ //
+ // svgImage
+ //
+ this.svgImage.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.svgImage.Location = new System.Drawing.Point(0, 25);
+ this.svgImage.Name = "svgImage";
+ this.svgImage.Size = new System.Drawing.Size(735, 449);
+ this.svgImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
+ this.svgImage.TabIndex = 1;
+ this.svgImage.TabStop = false;
+ //
+ // openSvgFile
+ //
+ this.openSvgFile.Filter = "Vector Graphics (*.svg)|*.svg";
+ //
+ // textBox1
+ //
+ this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox1.Location = new System.Drawing.Point(741, 25);
+ this.textBox1.MaxLength = 327670;
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(307, 446);
+ this.textBox1.TabIndex = 2;
+ this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
+ //
+ // SVGViewer
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1060, 474);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.svgImage);
+ this.Controls.Add(this.toolStrip1);
+ this.Name = "SVGViewer";
+ this.Text = "SVG Viewer";
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.svgImage)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
}
#endregion
diff --git a/Samples/SvgExamples/Workflow.svg b/Samples/SvgExamples/Workflow.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0ecd70c982fc88b54cdc58bd7a2b5332838f6d14
--- /dev/null
+++ b/Samples/SvgExamples/Workflow.svg
@@ -0,0 +1,181 @@
+
diff --git a/Source/DataTypes/SvgFontWeight.cs b/Source/DataTypes/SvgFontWeight.cs
index 0fe1b0db2b97833087f9d10613740551e198218f..a5b4bf8e2c89ef5cbdff049f3626fef64d772632 100644
--- a/Source/DataTypes/SvgFontWeight.cs
+++ b/Source/DataTypes/SvgFontWeight.cs
@@ -5,11 +5,10 @@ using System.Text;
namespace Svg.DataTypes
{
- public enum SvgFontWeight
- {
- normal,
- bold
- }
-
-
+ public enum SvgFontWeight
+ {
+ inherit,
+ normal,
+ bold
+ }
}
diff --git a/Source/DataTypes/SvgUnitCollection.cs b/Source/DataTypes/SvgUnitCollection.cs
index e3fa829982a82b7f645b9b59b7c65988923bdc23..284dfe03d1cb24fbfbec531df6b191251887511b 100644
--- a/Source/DataTypes/SvgUnitCollection.cs
+++ b/Source/DataTypes/SvgUnitCollection.cs
@@ -45,6 +45,7 @@ namespace Svg
{
if (value is string)
{
+ if (string.Compare(((string)value).Trim(), "none", StringComparison.InvariantCultureIgnoreCase) == 0) return null;
string[] points = ((string)value).Trim().Split(new char[] { ',', ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries);
SvgUnitCollection units = new SvgUnitCollection();
diff --git a/Source/Document Structure/SvgDescription.cs b/Source/Document Structure/SvgDescription.cs
index 34006e9e92370b118694f3a8fd81f726a05ea915..d8bd349c25b6eea60b48b257f0a9586f14d5ad1a 100644
--- a/Source/Document Structure/SvgDescription.cs
+++ b/Source/Document Structure/SvgDescription.cs
@@ -9,17 +9,9 @@ namespace Svg
[SvgElement("desc")]
public class SvgDescription : SvgElement
{
- private string _text;
-
- public string Text
- {
- get { return this._text; }
- set { this._text = value; }
- }
-
public override string ToString()
{
- return this.Text;
+ return this.Content;
}
@@ -31,7 +23,6 @@ namespace Svg
public override SvgElement DeepCopy()
{
var newObj = base.DeepCopy() as SvgDescription;
- newObj.Text = this.Text;
return newObj;
}
diff --git a/Source/Document Structure/SvgTitle.cs b/Source/Document Structure/SvgTitle.cs
index 77d85ffd097f354992ba58e7f1b5cea8ec123d59..be755d3bb55be635c405348b438a9e939eac3b84 100644
--- a/Source/Document Structure/SvgTitle.cs
+++ b/Source/Document Structure/SvgTitle.cs
@@ -7,7 +7,12 @@ namespace Svg
{
[SvgElement("title")]
public class SvgTitle : SvgElement
- {
+ {
+ public override string ToString()
+ {
+ return this.Content;
+ }
+
public override SvgElement DeepCopy()
{
return DeepCopy();
diff --git a/Source/Document Structure/SvgUse.cs b/Source/Document Structure/SvgUse.cs
index bd9152a05e46a2ab8f883f99538a423cc90eee16..8897f2f5c578567ae5aa510e99dffc0e8146061c 100644
--- a/Source/Document Structure/SvgUse.cs
+++ b/Source/Document Structure/SvgUse.cs
@@ -13,7 +13,7 @@ namespace Svg
{
private Uri _referencedElement;
- [SvgAttribute("xlink:href")]
+ [SvgAttribute("href", SvgAttributeAttribute.XLinkNamespace)]
public virtual Uri ReferencedElement
{
get { return this._referencedElement; }
diff --git a/Source/Extensions.cs b/Source/Extensions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1a228894c98aeb1d66bdb54b94b73a44122d0fbd
--- /dev/null
+++ b/Source/Extensions.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+
+namespace Svg
+{
+ public static class Extensions
+ {
+ public static IEnumerable Descendants(this IEnumerable source) where T : SvgElement
+ {
+ if (source == null) throw new ArgumentNullException("source");
+ return GetDescendants(source, false);
+ }
+ private static IEnumerable GetAncestors(IEnumerable source, bool self) where T : SvgElement
+ {
+ foreach (var start in source)
+ {
+ if (start != null)
+ {
+ for (var elem = (self ? start : start.Parent) as SvgElement; elem != null; elem = (elem.Parent as SvgElement))
+ {
+ yield return elem;
+ }
+ }
+ }
+ yield break;
+ }
+ private static IEnumerable GetDescendants(IEnumerable source, bool self) where T : SvgElement
+ {
+ var positons = new Stack();
+ int currPos;
+ SvgElement currParent;
+ foreach (var start in source)
+ {
+ if (start != null)
+ {
+ if (self) yield return start;
+
+ positons.Push(0);
+ currParent = start;
+
+ while (positons.Count > 0)
+ {
+ currPos = positons.Pop();
+ if (currPos < currParent.Children.Count)
+ {
+ yield return currParent.Children[currPos];
+ currParent = currParent.Children[currPos];
+ positons.Push(currPos + 1);
+ positons.Push(0);
+ }
+ else
+ {
+ currParent = currParent.Parent;
+ }
+ }
+ }
+ }
+ yield break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Filter Effects/feGaussianBlur/SvgGaussianBlur.cs b/Source/Filter Effects/feGaussianBlur/SvgGaussianBlur.cs
index c5183b6281b5e3ee3db05aa6c394a5632b1a9fd6..669022286e8a862e3941a3c01397eca0b345cb26 100644
--- a/Source/Filter Effects/feGaussianBlur/SvgGaussianBlur.cs
+++ b/Source/Filter Effects/feGaussianBlur/SvgGaussianBlur.cs
@@ -14,7 +14,7 @@ namespace Svg.FilterEffects
[SvgElement("feGaussianBlur")]
public class SvgGaussianBlur : SvgFilterPrimitive
{
- private int _stdDeviation;
+ private float _stdDeviation;
private BlurType _blurType;
private int[] _kernel;
@@ -26,12 +26,13 @@ namespace Svg.FilterEffects
{
}
- public SvgGaussianBlur(int stdDeviation)
+ public SvgGaussianBlur(float stdDeviation)
: this(stdDeviation, BlurType.Both)
{
}
- public SvgGaussianBlur(int stdDeviation, BlurType blurType) : base()
+ public SvgGaussianBlur(float stdDeviation, BlurType blurType)
+ : base()
{
_stdDeviation = stdDeviation;
_blurType = blurType;
@@ -42,13 +43,13 @@ namespace Svg.FilterEffects
private void PreCalculate()
{
- int sz = _stdDeviation * 2 + 1;
+ int sz = (int)(_stdDeviation * 2 + 1);
_kernel = new int[sz];
_multable = new int[sz, 256];
for (int i = 1; i <= _stdDeviation; i++)
{
- int szi = _stdDeviation - i;
- int szj = _stdDeviation + i;
+ int szi = (int)(_stdDeviation - i);
+ int szj = (int)(_stdDeviation + i);
_kernel[szj] = _kernel[szi] = (szi + 1) * (szi + 1);
_kernelSum += (_kernel[szj] + _kernel[szi]);
for (int j = 0; j < 256; j++)
@@ -56,11 +57,11 @@ namespace Svg.FilterEffects
_multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
}
}
- _kernel[_stdDeviation] = (_stdDeviation + 1) * (_stdDeviation + 1);
- _kernelSum += _kernel[_stdDeviation];
+ _kernel[(int)_stdDeviation] = (int)((_stdDeviation + 1) * (_stdDeviation + 1));
+ _kernelSum += _kernel[(int)_stdDeviation];
for (int j = 0; j < 256; j++)
{
- _multable[_stdDeviation, j] = _kernel[_stdDeviation] * j;
+ _multable[(int)_stdDeviation, j] = _kernel[(int)_stdDeviation] * j;
}
}
@@ -104,7 +105,7 @@ namespace Svg.FilterEffects
for (int i = 0; i < pixelCount; i++)
{
bsum = gsum = rsum = asum = 0;
- read = i - _stdDeviation;
+ read = (int)(i - _stdDeviation);
for (int z = 0; z < _kernel.Length; z++)
{
if (read < start)
@@ -156,7 +157,7 @@ namespace Svg.FilterEffects
index = 0;
for (int i = 0; i < src.Height; i++)
{
- int y = i - _stdDeviation;
+ int y = (int)(i - _stdDeviation);
start = y * src.Width;
for (int j = 0; j < src.Width; j++)
{
@@ -223,12 +224,12 @@ namespace Svg.FilterEffects
/// Gets or sets the radius of the blur (only allows for one value - not the two specified in the SVG Spec)
///
[SvgAttribute("stdDeviation")]
- public int StdDeviation
+ public float StdDeviation
{
get { return _stdDeviation; }
set
{
- if (value < 1)
+ if (value <= 0)
{
throw new InvalidOperationException("Radius must be greater then 0");
}
diff --git a/Source/Painting/SvgColourConverter.cs b/Source/Painting/SvgColourConverter.cs
index e36d2cf17452c91a799a773a462d849f5d6fd0c7..4c6d1a4db3a6b35981910b8e6aef892c1eb2750b 100644
--- a/Source/Painting/SvgColourConverter.cs
+++ b/Source/Painting/SvgColourConverter.cs
@@ -69,7 +69,18 @@ namespace Svg
alphaValue = (int)alphaDecimal;
}
}
- Color colorpart = System.Drawing.Color.FromArgb(alphaValue, int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]));
+
+ Color colorpart;
+ if (values[0].Trim().EndsWith("%"))
+ {
+ colorpart = System.Drawing.Color.FromArgb(alphaValue, (int)(255 * float.Parse(values[0].Trim().TrimEnd('%')) / 100f),
+ (int)(255 * float.Parse(values[1].Trim().TrimEnd('%')) / 100f),
+ (int)(255 * float.Parse(values[2].Trim().TrimEnd('%')) / 100f));
+ }
+ else
+ {
+ colorpart = System.Drawing.Color.FromArgb(alphaValue, int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]));
+ }
return colorpart;
}
diff --git a/Source/Painting/SvgDeferredPaintServer.cs b/Source/Painting/SvgDeferredPaintServer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..88172a33b0683b772f8d74e3c11238d15f135385
--- /dev/null
+++ b/Source/Painting/SvgDeferredPaintServer.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Svg
+{
+ ///
+ /// A wrapper for a paint server which isn't defined currently in the parse process, but
+ /// should be defined by the time the image needs to render.
+ ///
+ public class SvgDeferredPaintServer : SvgPaintServer
+ {
+ private bool _serverLoaded = false;
+ private SvgPaintServer _concreteServer;
+
+ public SvgDocument Document { get; set; }
+ public string DeferredId { get; set; }
+
+ public SvgDeferredPaintServer() { }
+ public SvgDeferredPaintServer(SvgDocument document, string id)
+ {
+ this.Document = document;
+ this.DeferredId = id;
+ }
+
+ private void EnsureServer()
+ {
+ if (!_serverLoaded)
+ {
+ _concreteServer = this.Document.IdManager.GetElementById(this.DeferredId) as SvgPaintServer;
+ _serverLoaded = true;
+ }
+ }
+
+ public override System.Drawing.Brush GetBrush(SvgVisualElement styleOwner, float opacity)
+ {
+ EnsureServer();
+ return _concreteServer.GetBrush(styleOwner, opacity);
+ }
+
+ public override SvgElement DeepCopy()
+ {
+ return DeepCopy();
+ }
+
+ public override SvgElement DeepCopy()
+ {
+ var newObj = base.DeepCopy() as SvgDeferredPaintServer;
+ newObj.Document = this.Document;
+ newObj.DeferredId = this.DeferredId;
+ return newObj;
+ }
+
+ public override bool Equals(object obj)
+ {
+ var other = obj as SvgDeferredPaintServer;
+ if (other == null)
+ return false;
+
+ return this.Document == other.Document && this.DeferredId == other.DeferredId;
+ }
+
+ public override int GetHashCode()
+ {
+ if (this.Document == null || this.DeferredId == null) return 0;
+ return this.Document.GetHashCode() ^ this.DeferredId.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return (_serverLoaded ? _serverLoaded.ToString() : string.Format("deferred: {0}", this.DeferredId));
+ }
+
+ public static T TryGet(SvgPaintServer server) where T : SvgPaintServer
+ {
+ var deferred = server as SvgDeferredPaintServer;
+ if (deferred == null)
+ {
+ return server as T;
+ }
+ else
+ {
+ return deferred._concreteServer as T;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Painting/SvgGradientServer.cs b/Source/Painting/SvgGradientServer.cs
index 27d16b6371aeee24b20014854fc414b56fc3f582..e904a17ba7c1682ba42e320607b9c1159bc0c6c9 100644
--- a/Source/Painting/SvgGradientServer.cs
+++ b/Source/Painting/SvgGradientServer.cs
@@ -13,7 +13,7 @@ namespace Svg
{
private SvgCoordinateUnits _gradientUnits;
private SvgGradientSpreadMethod _spreadMethod;
- private SvgGradientServer _inheritGradient;
+ private SvgPaintServer _inheritGradient;
private List _stops;
///
@@ -89,13 +89,12 @@ namespace Svg
/// Gets or sets another gradient fill from which to inherit the stops from.
///
[SvgAttribute("href")]
- public SvgGradientServer InheritGradient
+ public SvgPaintServer InheritGradient
{
get { return this._inheritGradient; }
set
{
this._inheritGradient = value;
- this.InheritStops();
}
}
@@ -220,14 +219,12 @@ namespace Svg
return blend;
}
- ///
- // If this gradient contains no stops then it will search any inherited gradients for stops.
- ///
- protected virtual void InheritStops()
+ protected void LoadStops()
{
- if (this.Stops.Count == 0 && this.InheritGradient != null)
+ var core = SvgDeferredPaintServer.TryGet(_inheritGradient);
+ if (this.Stops.Count == 0 && core != null)
{
- _stops.AddRange(this.InheritGradient.Stops);
+ _stops.AddRange(core.Stops);
}
}
diff --git a/Source/Painting/SvgLinearGradientServer.cs b/Source/Painting/SvgLinearGradientServer.cs
index 517aa5aad3f4ab396869e35ce62b3162c6b12574..9400c8a857c62c7a94975511a850c38b402d4d81 100644
--- a/Source/Painting/SvgLinearGradientServer.cs
+++ b/Source/Painting/SvgLinearGradientServer.cs
@@ -81,6 +81,7 @@ namespace Svg
public override Brush GetBrush(SvgVisualElement renderingElement, float opacity)
{
+ LoadStops();
if (IsInvalid)
{
return null;
diff --git a/Source/Painting/SvgPaintServerFactory.cs b/Source/Painting/SvgPaintServerFactory.cs
index 4c9bbee207b6c4533c04c3d3e32af56f9e86505b..a45a451eaa732b92931fe9ad647a4a5d742692f4 100644
--- a/Source/Painting/SvgPaintServerFactory.cs
+++ b/Source/Painting/SvgPaintServerFactory.cs
@@ -38,7 +38,18 @@ namespace Svg
{
return (SvgPaintServer)document.IdManager.GetElementById(value);
}
- else // Otherwise try and parse as colour
+ else if (value.StartsWith("#")) // Otherwise try and parse as colour
+ {
+ try
+ {
+ return new SvgColourServer((Color)_colourConverter.ConvertFrom(value.Trim()));
+ }
+ catch
+ {
+ return new SvgDeferredPaintServer(document, value);
+ }
+ }
+ else
{
return new SvgColourServer((Color)_colourConverter.ConvertFrom(value.Trim()));
}
@@ -49,7 +60,7 @@ namespace Svg
if (value is string)
{
var s = (string) value;
- if(String.Equals( s.Trim(), "none", StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(s))
+ if (String.Equals(s.Trim(), "none", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(s) || s.Trim().Length < 1)
return SvgPaintServer.None;
else
return SvgPaintServerFactory.Create(s, (SvgDocument)context);
diff --git a/Source/Painting/SvgRadialGradientServer.cs b/Source/Painting/SvgRadialGradientServer.cs
index 61654fcbc8853c10b1676efe5677ec3dfa885c73..fafb951f743458206d62a882a589d99ffa306a7a 100644
--- a/Source/Painting/SvgRadialGradientServer.cs
+++ b/Source/Painting/SvgRadialGradientServer.cs
@@ -97,6 +97,7 @@ namespace Svg
public override Brush GetBrush(SvgVisualElement renderingElement, float opacity)
{
+ LoadStops();
var origin = CalculateOrigin(renderingElement);
var centerPoint = CalculateCenterPoint(renderingElement, origin);
diff --git a/Source/Paths/SvgClosePathSegment.cs b/Source/Paths/SvgClosePathSegment.cs
index 3f028d041d6c25f8940d857d2dc60d0ab323f0df..d3909d7f4fcd0361ef14975955c6ac799c08e35d 100644
--- a/Source/Paths/SvgClosePathSegment.cs
+++ b/Source/Paths/SvgClosePathSegment.cs
@@ -8,6 +8,14 @@ namespace Svg.Pathing
{
public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath graphicsPath)
{
+ // Important for custom line caps. Force the path the close with an explicit line, not just an implicit close of the figure.
+ if (graphicsPath.PathPoints.Length > 1 && !graphicsPath.PathPoints[0].Equals(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1]))
+ {
+ int i = graphicsPath.PathTypes.Length - 1;
+ while (i >= 0 && graphicsPath.PathTypes[i] > 0) i--;
+ if (i < 0) i = 0;
+ graphicsPath.AddLine(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1], graphicsPath.PathPoints[i]);
+ }
graphicsPath.CloseFigure();
}
diff --git a/Source/Paths/SvgPathBuilder.cs b/Source/Paths/SvgPathBuilder.cs
index 7595c91dc2c09cab382da5cbcb1ed07c4b1f60f6..f4bb24016f586211b9d6d9be25f081ee65b471d1 100644
--- a/Source/Paths/SvgPathBuilder.cs
+++ b/Source/Paths/SvgPathBuilder.cs
@@ -222,9 +222,9 @@ namespace Svg
{
var lastSegment = segments.Last;
- // if the last element is a SvgClosePathSegment the position of the previous element should be used because the position of SvgClosePathSegment is 0,0
+ // if the last element is a SvgClosePathSegment the position of the previous move to should be used because the position of SvgClosePathSegment is 0,0
if (lastSegment is SvgClosePathSegment)
- lastSegment = segments[segments.Count - 2];
+ lastSegment = segments.OfType().Last();
if (isRelativeX)
{
@@ -290,6 +290,7 @@ namespace Svg
{
if (value is string)
{
+ if (string.IsNullOrEmpty((string)value)) return new SvgPathSegmentList();
return Parse((string)value);
}
diff --git a/Source/Svg.csproj b/Source/Svg.csproj
index b5bd45c6f708948de807a0df80e8d1eb4717e3d3..9b7a51b156284d734958b6fa4b00b1676cfaee14 100644
--- a/Source/Svg.csproj
+++ b/Source/Svg.csproj
@@ -116,7 +116,9 @@
+
+
diff --git a/Source/SvgDocument.cs b/Source/SvgDocument.cs
index 8952be19a17c5aa9b99c12d8961c3552bf77d807..4aa51887466e614bf0d396252d5c864011052035 100644
--- a/Source/SvgDocument.cs
+++ b/Source/SvgDocument.cs
@@ -241,7 +241,7 @@ namespace Svg
element.Content = value.ToString();
// Reset content value for new element
- value.Clear();
+ value.Length = 0;
}
break;
case XmlNodeType.CDATA:
@@ -277,8 +277,10 @@ namespace Svg
throw new ArgumentNullException("document");
}
- Stream stream = new MemoryStream(UTF8Encoding.Default.GetBytes(document.InnerXml));
- return Open(stream, null);
+ using (var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(document.InnerXml)))
+ {
+ return Open(stream, null);
+ }
}
public static Bitmap OpenAsBitmap(string path)
diff --git a/Source/SvgElement.cs b/Source/SvgElement.cs
index f1607718c4bf5497fbe081dcc3f8ff84c04fcce3..4a5df1e42b8c4227b87c52f43d702829eb061d02 100644
--- a/Source/SvgElement.cs
+++ b/Source/SvgElement.cs
@@ -117,6 +117,15 @@ namespace Svg
get { return this._children; }
}
+ public IEnumerable Descendants()
+ {
+ return this.AsEnumerable().Descendants();
+ }
+ private IEnumerable AsEnumerable()
+ {
+ yield return this;
+ }
+
///
/// Gets a value to determine whether the element has children.
///
@@ -763,6 +772,7 @@ namespace Svg
onmouseout = ""
*/
+#if Net4
///
/// Use this method to provide your implementation ISvgEventCaller which can register Actions
/// and call them if one of the events occurs. Make sure, that your SvgElement has a unique ID.
@@ -804,6 +814,7 @@ namespace Svg
caller.UnregisterAction(rpcID + "onmouseout");
}
}
+#endif
[SvgAttribute("onclick")]
public event EventHandler Click;
@@ -826,12 +837,14 @@ namespace Svg
[SvgAttribute("onmouseout")]
public event EventHandler MouseOut;
+#if Net4
protected Action CreateMouseEventAction(Action