Commit af7e5fd8 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 ee95905a
Showing with 66 additions and 47 deletions
+66 -47
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);
} }
...@@ -677,9 +662,9 @@ namespace Svg ...@@ -677,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