diff --git a/Source/Basic Shapes/SvgLine.cs b/Source/Basic Shapes/SvgLine.cs index 348c8a07d4d62fccaf0c5acbddcd204132625424..1ece3ee9ce991ca9dc99406a26ae8e8f5230a368 100644 --- a/Source/Basic Shapes/SvgLine.cs +++ b/Source/Basic Shapes/SvgLine.cs @@ -4,6 +4,7 @@ using System.Text; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; +using Svg.ExtensionMethods; namespace Svg { @@ -85,7 +86,7 @@ namespace Svg [SvgAttribute("marker-end")] public Uri MarkerEnd { - get { return this.Attributes.GetAttribute("marker-end"); } + get { return this.Attributes.GetAttribute("marker-end").ReplaceWithNullIfNone(); } set { this.Attributes["marker-end"] = value; } } @@ -96,7 +97,7 @@ namespace Svg [SvgAttribute("marker-mid")] public Uri MarkerMid { - get { return this.Attributes.GetAttribute("marker-mid"); } + get { return this.Attributes.GetAttribute("marker-mid").ReplaceWithNullIfNone(); } set { this.Attributes["marker-mid"] = value; } } @@ -107,7 +108,7 @@ namespace Svg [SvgAttribute("marker-start")] public Uri MarkerStart { - get { return this.Attributes.GetAttribute("marker-start"); } + get { return this.Attributes.GetAttribute("marker-start").ReplaceWithNullIfNone(); } set { this.Attributes["marker-start"] = value; } } diff --git a/Source/Basic Shapes/SvgPolygon.cs b/Source/Basic Shapes/SvgPolygon.cs index a59a32832cc7dc97cd2122e3f29d17c8327e396a..7eb427b59a156ce032297afafaebcca9fa61b1d9 100644 --- a/Source/Basic Shapes/SvgPolygon.cs +++ b/Source/Basic Shapes/SvgPolygon.cs @@ -4,6 +4,7 @@ using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using System.Diagnostics; +using Svg.ExtensionMethods; using Svg.Pathing; namespace Svg @@ -32,7 +33,7 @@ namespace Svg [SvgAttribute("marker-end")] public Uri MarkerEnd { - get { return this.Attributes.GetAttribute("marker-end"); } + get { return this.Attributes.GetAttribute("marker-end").ReplaceWithNullIfNone(); } set { this.Attributes["marker-end"] = value; } } @@ -43,7 +44,7 @@ namespace Svg [SvgAttribute("marker-mid")] public Uri MarkerMid { - get { return this.Attributes.GetAttribute("marker-mid"); } + get { return this.Attributes.GetAttribute("marker-mid").ReplaceWithNullIfNone(); } set { this.Attributes["marker-mid"] = value; } } @@ -54,7 +55,7 @@ namespace Svg [SvgAttribute("marker-start")] public Uri MarkerStart { - get { return this.Attributes.GetAttribute("marker-start"); } + get { return this.Attributes.GetAttribute("marker-start").ReplaceWithNullIfNone(); } set { this.Attributes["marker-start"] = value; } } diff --git a/Source/Basic Shapes/SvgPolyline.cs b/Source/Basic Shapes/SvgPolyline.cs index 0aa692424a48b59f5c635c557c9416d537bccce2..650b8fad405f506490ecaaa5ae50de0067ee3cc0 100644 --- a/Source/Basic Shapes/SvgPolyline.cs +++ b/Source/Basic Shapes/SvgPolyline.cs @@ -4,6 +4,7 @@ using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using System.Diagnostics; +using Svg.ExtensionMethods; namespace Svg { @@ -19,7 +20,7 @@ namespace Svg [SvgAttribute("marker-end")] public Uri MarkerEnd { - get { return this.Attributes.GetAttribute("marker-end"); } + get { return this.Attributes.GetAttribute("marker-end").ReplaceWithNullIfNone(); } set { this.Attributes["marker-end"] = value; } } @@ -30,7 +31,7 @@ namespace Svg [SvgAttribute("marker-mid")] public Uri MarkerMid { - get { return this.Attributes.GetAttribute("marker-mid"); } + get { return this.Attributes.GetAttribute("marker-mid").ReplaceWithNullIfNone(); } set { this.Attributes["marker-mid"] = value; } } @@ -41,7 +42,7 @@ namespace Svg [SvgAttribute("marker-start")] public Uri MarkerStart { - get { return this.Attributes.GetAttribute("marker-start"); } + get { return this.Attributes.GetAttribute("marker-start").ReplaceWithNullIfNone(); } set { this.Attributes["marker-start"] = value; } } diff --git a/Source/Css/CssQuery.cs b/Source/Css/CssQuery.cs index fcb2bc00525237ea837db25f8cd245b16e9c8683..04d8f94b5f7b146994b642bd40fbee942edbbcfc 100644 --- a/Source/Css/CssQuery.cs +++ b/Source/Css/CssQuery.cs @@ -9,9 +9,9 @@ namespace Svg.Css { internal static class CssQuery { - public static IEnumerable QuerySelectorAll(this SvgElement elem, string selector) + public static IEnumerable QuerySelectorAll(this SvgElement elem, string selector, SvgElementFactory elementFactory) { - var generator = new SelectorGenerator(new SvgElementOps()); + var generator = new SelectorGenerator(new SvgElementOps(elementFactory)); Fizzler.Parser.Parse(selector, generator); return generator.Selector(Enumerable.Repeat(elem, 1)); } diff --git a/Source/Css/SvgElementOps.cs b/Source/Css/SvgElementOps.cs index 28cb6e401bdfbdf53d730d8d51851c2415f87a45..cda93e74c90eefd43a24eee0873f92d49b5b784b 100644 --- a/Source/Css/SvgElementOps.cs +++ b/Source/Css/SvgElementOps.cs @@ -8,10 +8,17 @@ namespace Svg.Css { internal class SvgElementOps : IElementOps { - public Selector Type(NamespacePrefix prefix, string name) + private readonly SvgElementFactory _elementFactory; + + public SvgElementOps(SvgElementFactory elementFactory) + { + _elementFactory = elementFactory; + } + + public Selector Type(NamespacePrefix prefix, string name) { SvgElementFactory.ElementInfo type = null; - if (SvgElementFactory.AvailableElements.TryGetValue(name, out type)) + if (_elementFactory.AvailableElements.TryGetValue(name, out type)) { return nodes => nodes.Where(n => n.GetType() == type.ElementType); } diff --git a/Source/ExtensionMethods/UriExtensions.cs b/Source/ExtensionMethods/UriExtensions.cs new file mode 100644 index 0000000000000000000000000000000000000000..aa300f9945471bc8e0b162032a90493aadded7a2 --- /dev/null +++ b/Source/ExtensionMethods/UriExtensions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Svg.ExtensionMethods +{ + public static class UriExtensions + { + public static Uri ReplaceWithNullIfNone(this Uri uri) + { + if(uri == null) { return null; } + return string.Equals(uri.ToString(), "none", StringComparison.OrdinalIgnoreCase) ? null : uri; + } + } +} diff --git a/Source/Paths/SvgPath.cs b/Source/Paths/SvgPath.cs index 9d5c2ea837f44e769102846a8eb896f57b0c2b76..ce9e322413873f4fcf6a4e6acdf7fcad61382e91 100644 --- a/Source/Paths/SvgPath.cs +++ b/Source/Paths/SvgPath.cs @@ -6,6 +6,7 @@ using System.Drawing.Drawing2D; using System.Xml.Serialization; using System.Xml; using System.Diagnostics; +using Svg.ExtensionMethods; using Svg.Pathing; using Svg.Transforms; @@ -51,7 +52,7 @@ namespace Svg [SvgAttribute("marker-end", true)] public Uri MarkerEnd { - get { return this.Attributes.GetAttribute("marker-end"); } + get { return this.Attributes.GetAttribute("marker-end").ReplaceWithNullIfNone(); } set { this.Attributes["marker-end"] = value; } } @@ -62,7 +63,7 @@ namespace Svg [SvgAttribute("marker-mid", true)] public Uri MarkerMid { - get { return this.Attributes.GetAttribute("marker-mid"); } + get { return this.Attributes.GetAttribute("marker-mid").ReplaceWithNullIfNone(); } set { this.Attributes["marker-mid"] = value; } } @@ -73,7 +74,7 @@ namespace Svg [SvgAttribute("marker-start", true)] public Uri MarkerStart { - get { return this.Attributes.GetAttribute("marker-start"); } + get { return this.Attributes.GetAttribute("marker-start").ReplaceWithNullIfNone(); } set { this.Attributes["marker-start"] = value; } } diff --git a/Source/Svg.csproj b/Source/Svg.csproj index ea132a119e11395dd05e6a30dd2e8252005a1aa7..64115c6c9698cd5c9a8d910c213d0cad942d5e29 100644 --- a/Source/Svg.csproj +++ b/Source/Svg.csproj @@ -107,6 +107,7 @@ + @@ -352,6 +353,7 @@ + diff --git a/Source/Svg.nuspec b/Source/Svg.nuspec new file mode 100644 index 0000000000000000000000000000000000000000..9fb7779f8480b2da9d759c12c5b33ed32af9607f --- /dev/null +++ b/Source/Svg.nuspec @@ -0,0 +1,11 @@ + + + + $id$ + $version$ + $title$ + $author$ + $author$ + TaxModel/PAW altered implementation of the Svg library + + \ No newline at end of file diff --git a/Source/SvgDocument.cs b/Source/SvgDocument.cs index f0dd47b7cee8ee09f7202603f178e8a14698b317..ceae70b2f7a99a975ff3ea693b576e13f7a377f0 100644 --- a/Source/SvgDocument.cs +++ b/Source/SvgDocument.cs @@ -243,7 +243,8 @@ namespace Svg SvgElement element = null; SvgElement parent; T svgDocument = null; - + var elementFactory = new SvgElementFactory(); + var styles = new List(); while (reader.Read()) @@ -259,11 +260,11 @@ namespace Svg // Create element if (elementStack.Count > 0) { - element = SvgElementFactory.CreateElement(reader, svgDocument); + element = elementFactory.CreateElement(reader, svgDocument); } else { - svgDocument = SvgElementFactory.CreateDocument(reader); + svgDocument = elementFactory.CreateDocument(reader); element = svgDocument; } @@ -349,7 +350,7 @@ namespace Svg foreach (var selector in selectors) { - elemsToStyle = svgDocument.QuerySelectorAll(rule.Selector.ToString()); + elemsToStyle = svgDocument.QuerySelectorAll(rule.Selector.ToString(), elementFactory); foreach (var elem in elemsToStyle) { foreach (var decl in rule.Declarations) diff --git a/Source/SvgElementFactory.cs b/Source/SvgElementFactory.cs index aad12db6e27b0d3a006c8f737b997afdc0dd73f1..193899c9e3be51fad790e5529ee49b96bac24dcd 100644 --- a/Source/SvgElementFactory.cs +++ b/Source/SvgElementFactory.cs @@ -14,13 +14,13 @@ namespace Svg /// internal class SvgElementFactory { - private static Dictionary availableElements; - private static Parser cssParser = new Parser(); + private Dictionary availableElements; + private Parser cssParser = new Parser(); /// /// Gets a list of available types that can be used when creating an . /// - public static Dictionary AvailableElements + public Dictionary AvailableElements { get { @@ -47,7 +47,7 @@ namespace Svg /// The containing the node to parse into an . /// The parameter cannot be null. /// The CreateDocument method can only be used to parse root <svg> elements. - public static T CreateDocument(XmlReader reader) where T : SvgDocument, new() + public T CreateDocument(XmlReader reader) where T : SvgDocument, new() { if (reader == null) { @@ -68,7 +68,7 @@ namespace Svg /// The containing the node to parse into a subclass of . /// The that the created element belongs to. /// The and parameters cannot be null. - public static SvgElement CreateElement(XmlReader reader, SvgDocument document) + public SvgElement CreateElement(XmlReader reader, SvgDocument document) { if (reader == null) { @@ -78,7 +78,7 @@ namespace Svg return CreateElement(reader, false, document); } - private static SvgElement CreateElement(XmlReader reader, bool fragmentIsDocument, SvgDocument document) where T : SvgDocument, new() + private SvgElement CreateElement(XmlReader reader, bool fragmentIsDocument, SvgDocument document) where T : SvgDocument, new() { SvgElement createdElement = null; string elementName = reader.LocalName; @@ -122,7 +122,7 @@ namespace Svg return createdElement; } - private static void SetAttributes(SvgElement element, XmlReader reader, SvgDocument document) + private void SetAttributes(SvgElement element, XmlReader reader, SvgDocument document) { //Trace.TraceInformation("Begin SetAttributes"); diff --git a/Source/Text/GdiFontDefn.cs b/Source/Text/GdiFontDefn.cs index 8fc81228af2b50c871714ec10f98fd0d17cdabe9..eb0c42c0e29fc4ef14ff21923d61c3dea3bc1bb0 100644 --- a/Source/Text/GdiFontDefn.cs +++ b/Source/Text/GdiFontDefn.cs @@ -68,8 +68,8 @@ namespace Svg return new SizeF(rect.Width, Ascent(renderer)); } - private static Graphics _graphics; - private static Graphics GetGraphics(object renderer) + private Graphics _graphics; + private Graphics GetGraphics(object renderer) { var provider = renderer as IGraphicsProvider; if (provider == null) diff --git a/Tests/Svg.UnitTests/CssQueryTest.cs b/Tests/Svg.UnitTests/CssQueryTest.cs index 110714fd2e3c98d28846cc1ca89c9a26ed5a6661..f671ecdfc306879f9d534fa1e51869584c920fcd 100644 --- a/Tests/Svg.UnitTests/CssQueryTest.cs +++ b/Tests/Svg.UnitTests/CssQueryTest.cs @@ -5,13 +5,11 @@ using ExCSS; namespace Svg.UnitTests { - - - /// - ///This is a test class for CssQueryTest and is intended - ///to contain all CssQueryTest Unit Tests - /// - [TestClass()] + /// + ///This is a test class for CssQueryTest and is intended + ///to contain all CssQueryTest Unit Tests + /// + [TestClass()] public class CssQueryTest { diff --git a/Tests/Svg.UnitTests/MultiThreadingTest.cs b/Tests/Svg.UnitTests/MultiThreadingTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..3926f40ffdc0f311e7ab076ce4605881d8b65108 --- /dev/null +++ b/Tests/Svg.UnitTests/MultiThreadingTest.cs @@ -0,0 +1,59 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Threading.Tasks; +using System.Xml; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Svg.UnitTests +{ + + [TestClass()] + public class MultiThreadingTest + { + + private const string TestFile = @"d:\temp\test.svg"; + private const int ExpectedSize = 600000; + private XmlDocument GetXMLDoc() + { + var xmlDoc = new XmlDocument(); + if(!System.IO.File.Exists(TestFile)) { Assert.Inconclusive("Test file missing"); } + xmlDoc.LoadXml(System.IO.File.ReadAllText(TestFile)); + return xmlDoc; + } + + [TestMethod] + public void TestSingleThread() + { + LoadFile(); + } + + [TestMethod] + public void TestMultiThread() + { + bool valid = true; + Parallel.For(0, 3, (x) => + { + LoadFile(); + }); + Assert.IsTrue(valid, "One or more of the runs was invalid"); + Trace.WriteLine("Done"); + } + private void LoadFile() + { + var xml = GetXMLDoc(); + Trace.WriteLine("Reading and drawing file"); + SvgDocument d = SvgDocument.Open(xml); + var b = d.Draw(); + Trace.WriteLine("Done reading file"); + using (var ms = new MemoryStream()) + { + b.Save(ms, ImageFormat.Png); + ms.Flush(); + Assert.IsTrue(ms.Length >= ExpectedSize, "File does not match expected minimum size"); + } + } + } +} \ No newline at end of file diff --git a/Tests/Svg.UnitTests/Svg.UnitTests.csproj b/Tests/Svg.UnitTests/Svg.UnitTests.csproj index 0cfcb0b9932762790b8bdb8f38272d0a9ca36589..1653578f375f35d078e4d15b16a98010ae448e0c 100644 --- a/Tests/Svg.UnitTests/Svg.UnitTests.csproj +++ b/Tests/Svg.UnitTests/Svg.UnitTests.csproj @@ -49,6 +49,7 @@ +