Commit 867f632c authored by Marco Stroppel's avatar Marco Stroppel
Browse files

Copy the nodes of a SvgElement when creating a deep copy.

Added a test with a SvgText element where the whole text element was not written to XML of a deep copy of the SvgDocument.
parent 2bf55043
using System; namespace Svg
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{ {
public class SvgContentNode : ISvgNode public class SvgContentNode : ISvgNode
{ {
public string Content { get; set; } public string Content { get; set; }
/// <summary>
/// Create a deep copy of this <see cref="ISvgNode"/>.
/// </summary>
/// <returns>A deep copy of this <see cref="ISvgNode"/></returns>
public ISvgNode DeepCopy()
{
// Since strings are immutable in C#, we can just use the same reference here.
return new SvgContentNode { Content = this.Content };
}
} }
} }
...@@ -833,6 +833,11 @@ namespace Svg ...@@ -833,6 +833,11 @@ namespace Svg
public abstract SvgElement DeepCopy(); public abstract SvgElement DeepCopy();
ISvgNode ISvgNode.DeepCopy()
{
return DeepCopy();
}
public virtual SvgElement DeepCopy<T>() where T : SvgElement, new() public virtual SvgElement DeepCopy<T>() where T : SvgElement, new()
{ {
var newObj = new T(); var newObj = new T();
...@@ -887,7 +892,14 @@ namespace Svg ...@@ -887,7 +892,14 @@ namespace Svg
} }
} }
return newObj; if (this._nodes.Count > 0)
{
foreach (var node in this._nodes)
{
newObj.Nodes.Add(node.DeepCopy());
}
}
return newObj;
} }
/// <summary> /// <summary>
...@@ -1197,6 +1209,12 @@ namespace Svg ...@@ -1197,6 +1209,12 @@ namespace Svg
public interface ISvgNode public interface ISvgNode
{ {
string Content { get; } string Content { get; }
/// <summary>
/// Create a deep copy of this <see cref="ISvgNode"/>.
/// </summary>
/// <returns>A deep copy of this <see cref="ISvgNode"/></returns>
ISvgNode DeepCopy();
} }
/// <summary>This interface mostly indicates that a node is not to be drawn when rendering the SVG.</summary> /// <summary>This interface mostly indicates that a node is not to be drawn when rendering the SVG.</summary>
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 34.06945 33.11168" enable-background="new 0 0 34.06945 33.11168" xml:space="preserve" id="svg2">
<defs id="defs30"/>
<text y="21.539351" x="5.6560216" style="font-size:18.9988308px;font-family:NotoSans" id="text13" font-size="18.99883px">IP</text>
</svg>
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SmallEmbeddingImageTest.cs" /> <Compile Include="SmallEmbeddingImageTest.cs" />
<Compile Include="SvgTestHelper.cs" /> <Compile Include="SvgTestHelper.cs" />
<Compile Include="SvgTextElementDeepCopyTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Source\Svg.csproj"> <ProjectReference Include="..\..\Source\Svg.csproj">
...@@ -89,6 +90,9 @@ ...@@ -89,6 +90,9 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\hotfix-image-data-uri\Speedometer.svg" /> <EmbeddedResource Include="Resources\hotfix-image-data-uri\Speedometer.svg" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Issue_TextElement\Text.svg" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
......
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Linq;
using System.Xml;
namespace Svg.UnitTests
{
/// <summary>
/// Tests that the deep copy of a <see cref="SvgText"/> is done correctly where the
/// text element has contains only text and now other elements like <see cref="SvgTextSpan"/>.
/// </summary>
/// <seealso cref="Svg.UnitTests.SvgTestHelper" />
[TestClass]
public class SvgTextElementDeepCopyTest : SvgTestHelper
{
private const string PureTextElementSvg = "Issue_TextElement.Text.svg";
[TestMethod]
public void TestSvgTextElementDeepCopy()
{
var svgDocument = OpenSvg(GetResourceXmlDoc(GetFullResourceString(PureTextElementSvg)));
CheckDocument(svgDocument);
var deepCopy = (SvgDocument)svgDocument.DeepCopy<SvgDocument>();
CheckDocument(deepCopy);
}
/// <summary>
/// Checks the document if it contains the correct information when exported to XML.
/// </summary>
/// <param name="svgDocument">The SVG document to check.</param>
private static void CheckDocument(SvgDocument svgDocument)
{
Assert.AreEqual(2, svgDocument.Children.Count);
Assert.IsInstanceOfType(svgDocument.Children[0], typeof(SvgDefinitionList));
Assert.IsInstanceOfType(svgDocument.Children[1], typeof(SvgText));
var textElement = (SvgText)svgDocument.Children[1];
Assert.AreEqual("IP", textElement.Content);
var memoryStream = new MemoryStream();
svgDocument.Write(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var xmlDocument = new XmlDocument();
xmlDocument.Load(memoryStream);
Assert.AreEqual(2, xmlDocument.ChildNodes.Count);
var svgNode = xmlDocument.ChildNodes[1];
// Filter all significant whitespaces.
var svgChildren = svgNode.ChildNodes
.OfType<XmlNode>()
.Where(item => item.GetType() != typeof(XmlSignificantWhitespace))
.OfType<XmlNode>()
.ToArray();
Assert.AreEqual(2, svgChildren.Length);
var textNode = svgChildren[1];
Assert.AreEqual("text", textNode.Name);
Assert.AreEqual("IP", textNode.InnerText);
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment