Commit b3b2655c authored by davescriven's avatar davescriven
Browse files

- Fixed a bug that caused <text/> elements to be parsed incorrectly, leading...

- Fixed a bug that caused <text/> elements to be parsed incorrectly, leading to exceptions within the document.
parent 101984ba
...@@ -18,7 +18,6 @@ namespace Svg ...@@ -18,7 +18,6 @@ namespace Svg
private bool _dirty; private bool _dirty;
private bool _requiresSmoothRendering; private bool _requiresSmoothRendering;
private Region _previousClip; private Region _previousClip;
private SvgClipRule clipRule = SvgClipRule.NonZero;
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element. /// Gets the <see cref="GraphicsPath"/> for this element.
...@@ -53,7 +52,7 @@ namespace Svg ...@@ -53,7 +52,7 @@ namespace Svg
} }
/// <summary> /// <summary>
/// /// Gets or sets the algorithm which is to be used to determine the clipping region.
/// </summary> /// </summary>
[SvgAttribute("clip-rule")] [SvgAttribute("clip-rule")]
public SvgClipRule ClipRule public SvgClipRule ClipRule
...@@ -82,7 +81,7 @@ namespace Svg ...@@ -82,7 +81,7 @@ namespace Svg
/// <summary> /// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary> /// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> /// <param name="graphics">The <see cref="SvgRenderer"/> object to render to.</param>
protected override void Render(SvgRenderer renderer) protected override void Render(SvgRenderer renderer)
{ {
if (this.Path != null && this.Visible) if (this.Path != null && this.Visible)
...@@ -90,54 +89,66 @@ namespace Svg ...@@ -90,54 +89,66 @@ namespace Svg
this.PushTransforms(renderer); this.PushTransforms(renderer);
this.SetClip(renderer); this.SetClip(renderer);
// If this element needs smoothing enabled turn anti aliasing on // If this element needs smoothing enabled turn anti-aliasing on
if (this.RequiresSmoothRendering) if (this.RequiresSmoothRendering)
{ {
renderer.SmoothingMode = SmoothingMode.AntiAlias; renderer.SmoothingMode = SmoothingMode.AntiAlias;
} }
// Fill first so that the stroke can overlay this.RenderFill(renderer);
if (this.Fill != null) this.RenderStroke(renderer);
// Reset the smoothing mode
if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias)
{ {
using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity)) renderer.SmoothingMode = SmoothingMode.Default;
}
this.ResetClip(renderer);
this.PopTransforms(renderer);
}
}
/// <summary>
/// Renders the fill of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected internal virtual void RenderFill(SvgRenderer renderer)
{
if (this.Fill != null)
{
using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity))
{
if (brush != null)
{ {
if (brush != null) renderer.FillPath(brush, this.Path);
{
renderer.FillPath(brush, this.Path);
}
} }
} }
}
}
// Stroke is the last thing to do /// <summary>
if (this.Stroke != null) /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected internal virtual void RenderStroke(SvgRenderer renderer)
{
if (this.Stroke != null)
{
float strokeWidth = this.StrokeWidth.ToDeviceValue(this);
using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
{ {
float strokeWidth = this.StrokeWidth.ToDeviceValue(this); if (pen != null)
using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
{ {
if (pen != null) if (this.StrokeDashArray != null)
{ {
if (this.StrokeDashArray != null) /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/
{ pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray();
pen.DashPattern = this.StrokeDashArray.ConvertAll<float>(delegate(SvgUnit unit)
{
// divide by stroke width - GDI behaviour that I don't quite understand yet.
return unit.Value / ((strokeWidth <= 0) ? 1 : strokeWidth);
}).ToArray();
}
renderer.DrawPath(pen, this.Path);
} }
}
}
// Reset the smoothing mode renderer.DrawPath(pen, this.Path);
if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias) }
{
renderer.SmoothingMode = SmoothingMode.Default;
} }
this.ResetClip(renderer);
this.PopTransforms(renderer);
} }
} }
......
...@@ -62,6 +62,9 @@ namespace Svg ...@@ -62,6 +62,9 @@ namespace Svg
set { this.Attributes["FillOpacity"] = FixOpacityValue(value); } set { this.Attributes["FillOpacity"] = FixOpacityValue(value); }
} }
/// <summary>
/// Gets or sets the width of the stroke (if the <see cref="Stroke"/> property has a valid value specified.
/// </summary>
[SvgAttribute("stroke-width")] [SvgAttribute("stroke-width")]
public virtual SvgUnit StrokeWidth public virtual SvgUnit StrokeWidth
{ {
...@@ -104,6 +107,9 @@ namespace Svg ...@@ -104,6 +107,9 @@ namespace Svg
set { this.Attributes["StrokeDashOffset"] = value; } set { this.Attributes["StrokeDashOffset"] = value; }
} }
/// <summary>
/// Gets or sets the opacity of the stroke, if the <see cref="Stroke"/> property has been specified. 1.0 is fully opaque; 0.0 is transparent.
/// </summary>
[SvgAttribute("stroke-opacity")] [SvgAttribute("stroke-opacity")]
public virtual float StrokeOpacity public virtual float StrokeOpacity
{ {
......
...@@ -148,10 +148,7 @@ namespace Svg ...@@ -148,10 +148,7 @@ namespace Svg
return new SvgUnit(SvgUnitType.Percentage, this.Value * 100); return new SvgUnit(SvgUnitType.Percentage, this.Value * 100);
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
break;
} }
return this;
} }
/// <summary> /// <summary>
......
...@@ -189,10 +189,14 @@ namespace Svg ...@@ -189,10 +189,14 @@ namespace Svg
var lastSegment = segments.Last; var lastSegment = segments.Last;
if (isRelativeX) if (isRelativeX)
{
point.X += lastSegment.End.X; point.X += lastSegment.End.X;
}
if (isRelativeY) if (isRelativeY)
{
point.Y += lastSegment.End.Y; point.Y += lastSegment.End.Y;
}
} }
return point; return point;
...@@ -235,7 +239,7 @@ namespace Svg ...@@ -235,7 +239,7 @@ namespace Svg
private static IEnumerable<float> ParseCoordinates(string coords) private static IEnumerable<float> ParseCoordinates(string coords)
{ {
// TODO: Handle "1-1" (new PointF(1, -1); // TODO: Handle "1-1" (new PointF(1, -1);
var parts = coords.Remove(0, 1).Replace("-", " -").Split(new[] { ',', ' ' }, var parts = coords.Remove(0, 1).Replace("-", " -").Split(new[] { ',', ' ', '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries); StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < parts.Length; i++) for (var i = 0; i < parts.Length; i++)
......
...@@ -265,7 +265,7 @@ namespace Svg ...@@ -265,7 +265,7 @@ namespace Svg
throw new ArgumentNullException("document"); throw new ArgumentNullException("document");
} }
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(document.InnerXml)); Stream stream = new MemoryStream(UTF8Encoding.Default.GetBytes(document.InnerXml));
return Open(stream, null); return Open(stream, null);
} }
......
...@@ -101,11 +101,10 @@ namespace Svg ...@@ -101,11 +101,10 @@ namespace Svg
} }
else else
{ {
var validTypes = AvailableElements.Where(e => e.ElementName == elementName); ElementInfo validType = AvailableElements.SingleOrDefault(e => e.ElementName == elementName);
if (validType != null)
if (validTypes.Count() > 0)
{ {
createdElement = Activator.CreateInstance(validTypes.First().ElementType) as SvgElement; createdElement = (SvgElement)Activator.CreateInstance(validType.ElementType);
} }
} }
...@@ -158,11 +157,10 @@ namespace Svg ...@@ -158,11 +157,10 @@ namespace Svg
private static void SetPropertyValue(SvgElement element, string attributeName, string attributeValue, SvgDocument document) private static void SetPropertyValue(SvgElement element, string attributeName, string attributeValue, SvgDocument document)
{ {
var properties = TypeDescriptor.GetProperties(element.GetType(), new SvgAttributeAttribute[] { new SvgAttributeAttribute(attributeName) }); var properties = TypeDescriptor.GetProperties(element.GetType(), new SvgAttributeAttribute[] { new SvgAttributeAttribute(attributeName) });
PropertyDescriptor descriptor = null;
if (properties.Count > 0) if (properties.Count > 0)
{ {
descriptor = properties[0]; PropertyDescriptor descriptor = properties[0];
try try
{ {
...@@ -178,7 +176,8 @@ namespace Svg ...@@ -178,7 +176,8 @@ namespace Svg
/// <summary> /// <summary>
/// Contains information about a type inheriting from <see cref="SvgElement"/>. /// Contains information about a type inheriting from <see cref="SvgElement"/>.
/// </summary> /// </summary>
private struct ElementInfo [DebuggerDisplay("{ElementName}, {ElementType}")]
internal sealed class ElementInfo
{ {
/// <summary> /// <summary>
/// Gets the SVG name of the <see cref="SvgElement"/>. /// Gets the SVG name of the <see cref="SvgElement"/>.
...@@ -195,11 +194,17 @@ namespace Svg ...@@ -195,11 +194,17 @@ namespace Svg
/// <param name="elementName">Name of the element.</param> /// <param name="elementName">Name of the element.</param>
/// <param name="elementType">Type of the element.</param> /// <param name="elementType">Type of the element.</param>
public ElementInfo(string elementName, Type elementType) public ElementInfo(string elementName, Type elementType)
: this()
{ {
this.ElementName = elementName; this.ElementName = elementName;
this.ElementType = elementType; this.ElementType = elementType;
} }
/// <summary>
/// Initializes a new instance of the <see cref="ElementInfo"/> class.
/// </summary>
public ElementInfo()
{
}
} }
} }
} }
\ No newline at end of file
...@@ -186,15 +186,6 @@ namespace Svg ...@@ -186,15 +186,6 @@ namespace Svg
get { return this.Path.GetBounds(); } get { return this.Path.GetBounds(); }
} }
/// <summary>
/// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object.
/// </summary>
/// <param name="graphics">The <see cref="Graphics"/> object to render to.</param>
protected override void Render(SvgRenderer renderer)
{
base.Render(renderer);
}
static private int MeasureString(SvgRenderer renderer, string text, Font font) static private int MeasureString(SvgRenderer renderer, string text, Font font)
{ {
GraphicsPath p = new GraphicsPath(); GraphicsPath p = new GraphicsPath();
......
...@@ -6,6 +6,7 @@ using System.Text; ...@@ -6,6 +6,7 @@ using System.Text;
namespace Svg namespace Svg
{ {
[SvgElement("tspan")]
public class SvgTextSpan : SvgText public class SvgTextSpan : SvgText
{ {
/// <summary> /// <summary>
......
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