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
private bool _dirty;
private bool _requiresSmoothRendering;
private Region _previousClip;
private SvgClipRule clipRule = SvgClipRule.NonZero;
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
......@@ -53,7 +52,7 @@ namespace Svg
}
/// <summary>
///
/// Gets or sets the algorithm which is to be used to determine the clipping region.
/// </summary>
[SvgAttribute("clip-rule")]
public SvgClipRule ClipRule
......@@ -82,7 +81,7 @@ namespace Svg
/// <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>
/// <param name="graphics">The <see cref="SvgRenderer"/> object to render to.</param>
protected override void Render(SvgRenderer renderer)
{
if (this.Path != null && this.Visible)
......@@ -90,13 +89,32 @@ namespace Svg
this.PushTransforms(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)
{
renderer.SmoothingMode = SmoothingMode.AntiAlias;
}
// Fill first so that the stroke can overlay
this.RenderFill(renderer);
this.RenderStroke(renderer);
// Reset the smoothing mode
if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias)
{
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))
......@@ -107,8 +125,14 @@ namespace Svg
}
}
}
}
// Stroke is the last thing to do
/// <summary>
/// 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);
......@@ -118,27 +142,14 @@ namespace Svg
{
if (this.StrokeDashArray != null)
{
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();
/* 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();
}
renderer.DrawPath(pen, this.Path);
}
}
}
// Reset the smoothing mode
if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias)
{
renderer.SmoothingMode = SmoothingMode.Default;
}
this.ResetClip(renderer);
this.PopTransforms(renderer);
}
}
/// <summary>
......
......@@ -62,6 +62,9 @@ namespace Svg
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")]
public virtual SvgUnit StrokeWidth
{
......@@ -104,6 +107,9 @@ namespace Svg
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")]
public virtual float StrokeOpacity
{
......
......@@ -148,10 +148,7 @@ namespace Svg
return new SvgUnit(SvgUnitType.Percentage, this.Value * 100);
default:
throw new NotImplementedException();
break;
}
return this;
}
/// <summary>
......
......@@ -189,11 +189,15 @@ namespace Svg
var lastSegment = segments.Last;
if (isRelativeX)
{
point.X += lastSegment.End.X;
}
if (isRelativeY)
{
point.Y += lastSegment.End.Y;
}
}
return point;
}
......@@ -235,7 +239,7 @@ namespace Svg
private static IEnumerable<float> ParseCoordinates(string coords)
{
// 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);
for (var i = 0; i < parts.Length; i++)
......
......@@ -265,7 +265,7 @@ namespace Svg
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);
}
......
......@@ -101,11 +101,10 @@ namespace Svg
}
else
{
var validTypes = AvailableElements.Where(e => e.ElementName == elementName);
if (validTypes.Count() > 0)
ElementInfo validType = AvailableElements.SingleOrDefault(e => e.ElementName == elementName);
if (validType != null)
{
createdElement = Activator.CreateInstance(validTypes.First().ElementType) as SvgElement;
createdElement = (SvgElement)Activator.CreateInstance(validType.ElementType);
}
}
......@@ -158,11 +157,10 @@ namespace Svg
private static void SetPropertyValue(SvgElement element, string attributeName, string attributeValue, SvgDocument document)
{
var properties = TypeDescriptor.GetProperties(element.GetType(), new SvgAttributeAttribute[] { new SvgAttributeAttribute(attributeName) });
PropertyDescriptor descriptor = null;
if (properties.Count > 0)
{
descriptor = properties[0];
PropertyDescriptor descriptor = properties[0];
try
{
......@@ -178,7 +176,8 @@ namespace Svg
/// <summary>
/// Contains information about a type inheriting from <see cref="SvgElement"/>.
/// </summary>
private struct ElementInfo
[DebuggerDisplay("{ElementName}, {ElementType}")]
internal sealed class ElementInfo
{
/// <summary>
/// Gets the SVG name of the <see cref="SvgElement"/>.
......@@ -195,11 +194,17 @@ namespace Svg
/// <param name="elementName">Name of the element.</param>
/// <param name="elementType">Type of the element.</param>
public ElementInfo(string elementName, Type elementType)
: this()
{
this.ElementName = elementName;
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
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)
{
GraphicsPath p = new GraphicsPath();
......
......@@ -6,6 +6,7 @@ using System.Text;
namespace Svg
{
[SvgElement("tspan")]
public class SvgTextSpan : SvgText
{
/// <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