diff --git a/Source/Document Structure/SvgFragment.cs b/Source/Document Structure/SvgFragment.cs
index c17ccdaa5c7d76b53008766f4a901c765ae63198..ef8c813196b7281f7a70b943f618c300f55b5ef6 100644
--- a/Source/Document Structure/SvgFragment.cs
+++ b/Source/Document Structure/SvgFragment.cs
@@ -1,6 +1,7 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
+using System.Xml;
namespace Svg
{
@@ -41,7 +42,7 @@ namespace Svg
private SvgUnit _x;
private SvgUnit _y;
-
+
///
/// Gets or sets the position where the left point of the svg should start.
///
@@ -51,10 +52,10 @@ namespace Svg
get { return _x; }
set
{
- if(_x != value)
+ if (_x != value)
{
_x = value;
- OnAttributeChanged(new AttributeEventArgs{ Attribute = "x", Value = value });
+ OnAttributeChanged(new AttributeEventArgs { Attribute = "x", Value = value });
}
}
}
@@ -68,10 +69,10 @@ namespace Svg
get { return _y; }
set
{
- if(_y != value)
+ if (_y != value)
{
_y = value;
- OnAttributeChanged(new AttributeEventArgs{ Attribute = "y", Value = value });
+ OnAttributeChanged(new AttributeEventArgs { Attribute = "y", Value = value });
}
}
}
@@ -115,7 +116,7 @@ namespace Svg
get { return this.Attributes.GetAttribute("viewBox"); }
set { this.Attributes["viewBox"] = value; }
}
-
+
///
/// Gets or sets the aspect of the viewport.
///
@@ -185,29 +186,29 @@ namespace Svg
break;
}
}
-
+
///
/// Gets the for this element.
///
///
public GraphicsPath Path
{
- get
- {
+ get
+ {
var path = new GraphicsPath();
AddPaths(this, path);
-
+
return path;
}
}
-
+
///
/// Gets the bounds of the svg element.
///
/// The bounds.
- public RectangleF Bounds
- {
+ public RectangleF Bounds
+ {
get
{
return this.Path.GetBounds();
@@ -246,7 +247,7 @@ namespace Svg
}
}
- if (isWidthperc)
+ if (isWidthperc)
{
w = (bounds.Width + bounds.X) * (Width.Value * 0.01f);
}
@@ -254,11 +255,11 @@ namespace Svg
{
w = Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this);
}
- if (isHeightperc)
+ if (isHeightperc)
{
h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f);
}
- else
+ else
{
h = Height.ToDeviceValue(null, UnitRenderingType.Vertical, this);
}
@@ -282,6 +283,20 @@ namespace Svg
return newObj;
}
+ //Override the default behavior, writing out the namespaces.
+ protected override void WriteStartElement(XmlTextWriter writer)
+ {
+ base.WriteStartElement(writer);
+ foreach (var ns in SvgAttributeAttribute.Namespaces)
+ {
+ if (string.IsNullOrEmpty(ns.Key))
+ writer.WriteAttributeString("xmlns", ns.Value);
+ else
+ writer.WriteAttributeString("xmlns:" + ns.Key, ns.Value);
+ }
+
+ writer.WriteAttributeString("version", "1.1");
+ }
}
}
\ No newline at end of file
diff --git a/Source/SvgDocument.cs b/Source/SvgDocument.cs
index 2bc106c916ee947670dc3e40328f73fbe0dcf21a..e19a2c9d0765c2d1a2dee373e736c60128f95d60 100644
--- a/Source/SvgDocument.cs
+++ b/Source/SvgDocument.cs
@@ -11,6 +11,8 @@ using System.Xml;
using System.Linq;
using ExCSS;
using Svg.Css;
+using System.Threading;
+using System.Globalization;
namespace Svg
{
@@ -488,6 +490,18 @@ namespace Svg
//Trace.TraceInformation("End Render");
}
+ public override void Write(XmlTextWriter writer)
+ {
+ //Save previous culture and switch to invariant for writing
+ var previousCulture = Thread.CurrentThread.CurrentCulture;
+ Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+
+ base.Write(writer);
+
+ //Switch culture back
+ Thread.CurrentThread.CurrentCulture = previousCulture;
+ }
+
public void Write(Stream stream)
{
@@ -499,7 +513,7 @@ namespace Svg
if (!String.IsNullOrEmpty(this.ExternalCSSHref))
xmlWriter.WriteProcessingInstruction("xml-stylesheet", String.Format("type=\"text/css\" href=\"{0}\"", this.ExternalCSSHref));
- this.WriteElement(xmlWriter);
+ this.Write(xmlWriter);
xmlWriter.Flush();
}
diff --git a/Source/SvgElement.cs b/Source/SvgElement.cs
index 54680281498db2fd4bf59c745724c067c0c3420b..de729d3e8a1e28355a2d21b16222ba4e2e590312 100644
--- a/Source/SvgElement.cs
+++ b/Source/SvgElement.cs
@@ -520,16 +520,11 @@ namespace Svg
this.Render(renderer);
}
- public void WriteElement(XmlTextWriter writer)
+ /// Derrived classes may decide that the element should not be written. For example, the text element shouldn't be written if it's empty.
+ public virtual bool ShouldWriteElement()
{
- //Save previous culture and switch to invariant for writing
- var previousCulture = Thread.CurrentThread.CurrentCulture;
- Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
-
- this.Write(writer);
-
- //Switch culture back
- Thread.CurrentThread.CurrentCulture = previousCulture;
+ //Write any element who has a name.
+ return (this.ElementName != String.Empty);
}
protected virtual void WriteStartElement(XmlTextWriter writer)
@@ -537,18 +532,8 @@ namespace Svg
if (this.ElementName != String.Empty)
{
writer.WriteStartElement(this.ElementName);
- if (this.ElementName == "svg")
- {
- foreach (var ns in SvgAttributeAttribute.Namespaces)
- {
- if (string.IsNullOrEmpty(ns.Key))
- writer.WriteAttributeString("xmlns", ns.Value);
- else
- writer.WriteAttributeString("xmlns:" + ns.Key, ns.Value);
- }
- writer.WriteAttributeString("version", "1.1");
- }
}
+
this.WriteAttributes(writer);
}
@@ -677,9 +662,9 @@ namespace Svg
return resolved;
}
- protected virtual void Write(XmlTextWriter writer)
+ public virtual void Write(XmlTextWriter writer)
{
- if (this.ElementName != String.Empty)
+ if (ShouldWriteElement())
{
this.WriteStartElement(writer);
this.WriteChildren(writer);
diff --git a/Source/SvgExtentions.cs b/Source/SvgExtentions.cs
index 9a93277e6db3ba45e3bf1a1cacbda828e655e701..333a4bace6091996811e3930efde7974906ecda7 100644
--- a/Source/SvgExtentions.cs
+++ b/Source/SvgExtentions.cs
@@ -54,7 +54,7 @@ namespace Svg
{
using (XmlTextWriter xml = new XmlTextWriter(str))
{
- elem.WriteElement(xml);
+ elem.Write(xml);
result = str.ToString();
}
diff --git a/Source/Text/SvgTextBase.cs b/Source/Text/SvgTextBase.cs
index 9db224f181ec9a63b071b31cfb0416b95db9a985..1a07ad636cdafc0772dce2d330809ba66d0268e5 100644
--- a/Source/Text/SvgTextBase.cs
+++ b/Source/Text/SvgTextBase.cs
@@ -19,7 +19,7 @@ namespace Svg
protected SvgUnitCollection _dx = new SvgUnitCollection();
private string _rotate;
private List _rotations = new List();
-
+
///
/// Gets or sets the text to be rendered.
///
@@ -143,7 +143,7 @@ namespace Svg
{
this._rotate = value;
this._rotations.Clear();
- this._rotations.AddRange(from r in _rotate.Split(new char[] {',', ' ', '\r', '\n', '\t'}, StringSplitOptions.RemoveEmptyEntries) select float.Parse(r));
+ this._rotations.AddRange(from r in _rotate.Split(new char[] { ',', ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries) select float.Parse(r));
this.IsPathDirty = true;
OnAttributeChanged(new AttributeEventArgs { Attribute = "rotate", Value = value });
}
@@ -230,14 +230,14 @@ namespace Svg
/// The bounds.
public override System.Drawing.RectangleF Bounds
{
- get
+ get
{
var path = this.Path(null);
foreach (var elem in this.Children.OfType())
{
path.AddPath(elem.Path(null), false);
}
- return path.GetBounds();
+ return path.GetBounds();
}
}
@@ -296,9 +296,9 @@ namespace Svg
public override GraphicsPath Path(ISvgRenderer renderer)
{
//if there is a TSpan inside of this text element then path should not be null (even if this text is empty!)
- var nodes = GetContentNodes().Where(x => x is SvgContentNode &&
- string.IsNullOrEmpty(x.Content.Trim(new[] {'\r', '\n', '\t'})));
-
+ var nodes = GetContentNodes().Where(x => x is SvgContentNode &&
+ string.IsNullOrEmpty(x.Content.Trim(new[] { '\r', '\n', '\t' })));
+
if (_path == null || IsPathDirty || nodes.Count() == 1)
{
renderer = (renderer ?? SvgRenderer.FromNull());
@@ -913,5 +913,10 @@ namespace Svg
}
}
+ /// Empty text elements are not legal - only write this element if it has children.
+ public override bool ShouldWriteElement()
+ {
+ return (this.HasChildren() || this.Nodes.Count > 0);
+ }
}
}