Commit 796f6eba authored by Josh McCullough's avatar Josh McCullough
Browse files

Simplified element writing (moved WriteElement(XmlTextWriter) out to

SvgDocument as Write(XmlTextWriter); allowed elements to decide whether or
not they should be written. E.g. text elements should not be written
unless they have children.
parent e4cb89ac
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Xml;
namespace Svg namespace Svg
{ {
...@@ -41,7 +42,7 @@ namespace Svg ...@@ -41,7 +42,7 @@ namespace Svg
private SvgUnit _x; private SvgUnit _x;
private SvgUnit _y; private SvgUnit _y;
/// <summary> /// <summary>
/// Gets or sets the position where the left point of the svg should start. /// Gets or sets the position where the left point of the svg should start.
/// </summary> /// </summary>
...@@ -51,10 +52,10 @@ namespace Svg ...@@ -51,10 +52,10 @@ namespace Svg
get { return _x; } get { return _x; }
set set
{ {
if(_x != value) if (_x != value)
{ {
_x = value; _x = value;
OnAttributeChanged(new AttributeEventArgs{ Attribute = "x", Value = value }); OnAttributeChanged(new AttributeEventArgs { Attribute = "x", Value = value });
} }
} }
} }
...@@ -68,10 +69,10 @@ namespace Svg ...@@ -68,10 +69,10 @@ namespace Svg
get { return _y; } get { return _y; }
set set
{ {
if(_y != value) if (_y != value)
{ {
_y = value; _y = value;
OnAttributeChanged(new AttributeEventArgs{ Attribute = "y", Value = value }); OnAttributeChanged(new AttributeEventArgs { Attribute = "y", Value = value });
} }
} }
} }
...@@ -115,7 +116,7 @@ namespace Svg ...@@ -115,7 +116,7 @@ namespace Svg
get { return this.Attributes.GetAttribute<SvgViewBox>("viewBox"); } get { return this.Attributes.GetAttribute<SvgViewBox>("viewBox"); }
set { this.Attributes["viewBox"] = value; } set { this.Attributes["viewBox"] = value; }
} }
/// <summary> /// <summary>
/// Gets or sets the aspect of the viewport. /// Gets or sets the aspect of the viewport.
/// </summary> /// </summary>
...@@ -185,29 +186,29 @@ namespace Svg ...@@ -185,29 +186,29 @@ namespace Svg
break; break;
} }
} }
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public GraphicsPath Path public GraphicsPath Path
{ {
get get
{ {
var path = new GraphicsPath(); var path = new GraphicsPath();
AddPaths(this, path); AddPaths(this, path);
return path; return path;
} }
} }
/// <summary> /// <summary>
/// Gets the bounds of the svg element. /// Gets the bounds of the svg element.
/// </summary> /// </summary>
/// <value>The bounds.</value> /// <value>The bounds.</value>
public RectangleF Bounds public RectangleF Bounds
{ {
get get
{ {
return this.Path.GetBounds(); return this.Path.GetBounds();
...@@ -246,7 +247,7 @@ namespace Svg ...@@ -246,7 +247,7 @@ namespace Svg
} }
} }
if (isWidthperc) if (isWidthperc)
{ {
w = (bounds.Width + bounds.X) * (Width.Value * 0.01f); w = (bounds.Width + bounds.X) * (Width.Value * 0.01f);
} }
...@@ -254,11 +255,11 @@ namespace Svg ...@@ -254,11 +255,11 @@ namespace Svg
{ {
w = Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this); w = Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this);
} }
if (isHeightperc) if (isHeightperc)
{ {
h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f); h = (bounds.Height + bounds.Y) * (Height.Value * 0.01f);
} }
else else
{ {
h = Height.ToDeviceValue(null, UnitRenderingType.Vertical, this); h = Height.ToDeviceValue(null, UnitRenderingType.Vertical, this);
} }
...@@ -282,6 +283,20 @@ namespace Svg ...@@ -282,6 +283,20 @@ namespace Svg
return newObj; 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
...@@ -11,6 +11,8 @@ using System.Xml; ...@@ -11,6 +11,8 @@ using System.Xml;
using System.Linq; using System.Linq;
using ExCSS; using ExCSS;
using Svg.Css; using Svg.Css;
using System.Threading;
using System.Globalization;
namespace Svg namespace Svg
{ {
...@@ -488,6 +490,18 @@ namespace Svg ...@@ -488,6 +490,18 @@ namespace Svg
//Trace.TraceInformation("End Render"); //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) public void Write(Stream stream)
{ {
...@@ -499,7 +513,7 @@ namespace Svg ...@@ -499,7 +513,7 @@ namespace Svg
if (!String.IsNullOrEmpty(this.ExternalCSSHref)) if (!String.IsNullOrEmpty(this.ExternalCSSHref))
xmlWriter.WriteProcessingInstruction("xml-stylesheet", String.Format("type=\"text/css\" href=\"{0}\"", this.ExternalCSSHref)); xmlWriter.WriteProcessingInstruction("xml-stylesheet", String.Format("type=\"text/css\" href=\"{0}\"", this.ExternalCSSHref));
this.WriteElement(xmlWriter); this.Write(xmlWriter);
xmlWriter.Flush(); xmlWriter.Flush();
} }
......
...@@ -520,16 +520,11 @@ namespace Svg ...@@ -520,16 +520,11 @@ namespace Svg
this.Render(renderer); this.Render(renderer);
} }
public void WriteElement(XmlTextWriter writer) /// <summary>Derrived classes may decide that the element should not be written. For example, the text element shouldn't be written if it's empty.</summary>
public virtual bool ShouldWriteElement()
{ {
//Save previous culture and switch to invariant for writing //Write any element who has a name.
var previousCulture = Thread.CurrentThread.CurrentCulture; return (this.ElementName != String.Empty);
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
this.Write(writer);
//Switch culture back
Thread.CurrentThread.CurrentCulture = previousCulture;
} }
protected virtual void WriteStartElement(XmlTextWriter writer) protected virtual void WriteStartElement(XmlTextWriter writer)
...@@ -537,18 +532,8 @@ namespace Svg ...@@ -537,18 +532,8 @@ namespace Svg
if (this.ElementName != String.Empty) if (this.ElementName != String.Empty)
{ {
writer.WriteStartElement(this.ElementName); 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); this.WriteAttributes(writer);
} }
...@@ -575,7 +560,8 @@ namespace Svg ...@@ -575,7 +560,8 @@ namespace Svg
forceWrite = false; forceWrite = false;
writeStyle = (attr.Attribute.Name == "fill"); writeStyle = (attr.Attribute.Name == "fill");
if ((attr.Attribute.Name == "fill") && (Parent != null))
if (writeStyle && (Parent != null))
{ {
if(propertyValue == SvgColourServer.NotSet) continue; if(propertyValue == SvgColourServer.NotSet) continue;
...@@ -676,9 +662,9 @@ namespace Svg ...@@ -676,9 +662,9 @@ namespace Svg
return resolved; 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.WriteStartElement(writer);
this.WriteChildren(writer); this.WriteChildren(writer);
......
...@@ -54,7 +54,7 @@ namespace Svg ...@@ -54,7 +54,7 @@ namespace Svg
{ {
using (XmlTextWriter xml = new XmlTextWriter(str)) using (XmlTextWriter xml = new XmlTextWriter(str))
{ {
elem.WriteElement(xml); elem.Write(xml);
result = str.ToString(); result = str.ToString();
} }
......
...@@ -19,7 +19,7 @@ namespace Svg ...@@ -19,7 +19,7 @@ namespace Svg
protected SvgUnitCollection _dx = new SvgUnitCollection(); protected SvgUnitCollection _dx = new SvgUnitCollection();
private string _rotate; private string _rotate;
private List<float> _rotations = new List<float>(); private List<float> _rotations = new List<float>();
/// <summary> /// <summary>
/// Gets or sets the text to be rendered. /// Gets or sets the text to be rendered.
/// </summary> /// </summary>
...@@ -143,7 +143,7 @@ namespace Svg ...@@ -143,7 +143,7 @@ namespace Svg
{ {
this._rotate = value; this._rotate = value;
this._rotations.Clear(); 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; this.IsPathDirty = true;
OnAttributeChanged(new AttributeEventArgs { Attribute = "rotate", Value = value }); OnAttributeChanged(new AttributeEventArgs { Attribute = "rotate", Value = value });
} }
...@@ -230,14 +230,14 @@ namespace Svg ...@@ -230,14 +230,14 @@ namespace Svg
/// <value>The bounds.</value> /// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds public override System.Drawing.RectangleF Bounds
{ {
get get
{ {
var path = this.Path(null); var path = this.Path(null);
foreach (var elem in this.Children.OfType<SvgVisualElement>()) foreach (var elem in this.Children.OfType<SvgVisualElement>())
{ {
path.AddPath(elem.Path(null), false); path.AddPath(elem.Path(null), false);
} }
return path.GetBounds(); return path.GetBounds();
} }
} }
...@@ -296,9 +296,9 @@ namespace Svg ...@@ -296,9 +296,9 @@ namespace Svg
public override GraphicsPath Path(ISvgRenderer renderer) 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!) //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 && var nodes = GetContentNodes().Where(x => x is SvgContentNode &&
string.IsNullOrEmpty(x.Content.Trim(new[] {'\r', '\n', '\t'}))); string.IsNullOrEmpty(x.Content.Trim(new[] { '\r', '\n', '\t' })));
if (_path == null || IsPathDirty || nodes.Count() == 1) if (_path == null || IsPathDirty || nodes.Count() == 1)
{ {
renderer = (renderer ?? SvgRenderer.FromNull()); renderer = (renderer ?? SvgRenderer.FromNull());
...@@ -913,5 +913,10 @@ namespace Svg ...@@ -913,5 +913,10 @@ namespace Svg
} }
} }
/// <summary>Empty text elements are not legal - only write this element if it has children.</summary>
public override bool ShouldWriteElement()
{
return (this.HasChildren() || this.Nodes.Count > 0);
}
} }
} }
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