diff --git a/Basic Shapes/SvgVisualElement.cs b/Basic Shapes/SvgVisualElement.cs index 65cab4f3bbb046e20803042619e8abd9ed9ca29e..e11a49f0871609e9b1cf9ed412974c8a8768abc0 100644 --- a/Basic Shapes/SvgVisualElement.cs +++ b/Basic Shapes/SvgVisualElement.cs @@ -18,7 +18,6 @@ namespace Svg private bool _dirty; private bool _requiresSmoothRendering; private Region _previousClip; - private SvgClipRule clipRule = SvgClipRule.NonZero; /// /// Gets the for this element. @@ -53,7 +52,7 @@ namespace Svg } /// - /// + /// Gets or sets the algorithm which is to be used to determine the clipping region. /// [SvgAttribute("clip-rule")] public SvgClipRule ClipRule @@ -82,7 +81,7 @@ namespace Svg /// /// Renders the and contents to the specified object. /// - /// The object to render to. + /// The object to render to. protected override void Render(SvgRenderer renderer) { if (this.Path != null && this.Visible) @@ -90,54 +89,66 @@ 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 - if (this.Fill != null) + this.RenderFill(renderer); + 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); + } + } + + /// + /// Renders the fill of the to the specified + /// + /// The object to render to. + 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 - if (this.Stroke != null) + /// + /// Renders the stroke of the to the specified + /// + /// The object to render to. + 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); - using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth)) + if (pen != null) { - if (pen != null) + if (this.StrokeDashArray != null) { - if (this.StrokeDashArray != null) - { - pen.DashPattern = this.StrokeDashArray.ConvertAll(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); + /* 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(); } - } - } - // Reset the smoothing mode - if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias) - { - renderer.SmoothingMode = SmoothingMode.Default; + renderer.DrawPath(pen, this.Path); + } } - - this.ResetClip(renderer); - this.PopTransforms(renderer); } } diff --git a/Basic Shapes/SvgVisualElementStyle.cs b/Basic Shapes/SvgVisualElementStyle.cs index ea5d906f8c05c9c7ca1a613611a1d70bd3aa02ed..ff0067355d89599a530f703c7ef356ccfda95124 100644 --- a/Basic Shapes/SvgVisualElementStyle.cs +++ b/Basic Shapes/SvgVisualElementStyle.cs @@ -62,6 +62,9 @@ namespace Svg set { this.Attributes["FillOpacity"] = FixOpacityValue(value); } } + /// + /// Gets or sets the width of the stroke (if the property has a valid value specified. + /// [SvgAttribute("stroke-width")] public virtual SvgUnit StrokeWidth { @@ -104,6 +107,9 @@ namespace Svg set { this.Attributes["StrokeDashOffset"] = value; } } + /// + /// Gets or sets the opacity of the stroke, if the property has been specified. 1.0 is fully opaque; 0.0 is transparent. + /// [SvgAttribute("stroke-opacity")] public virtual float StrokeOpacity { diff --git a/DataTypes/SvgUnit.cs b/DataTypes/SvgUnit.cs index 09ced84e3ff7aacaff47db34e760c05bdf47bbb0..589ca0c8dff166c739ebaadf7f7ce89a90fa516d 100644 --- a/DataTypes/SvgUnit.cs +++ b/DataTypes/SvgUnit.cs @@ -148,10 +148,7 @@ namespace Svg return new SvgUnit(SvgUnitType.Percentage, this.Value * 100); default: throw new NotImplementedException(); - break; } - - return this; } /// diff --git a/Paths/SvgPathBuilder.cs b/Paths/SvgPathBuilder.cs index 387d125ad6527fa1c0ac2e794824d81cdafacab6..1a0b46bd68da231a2e7d6030d1edf7fd0a782ff6 100644 --- a/Paths/SvgPathBuilder.cs +++ b/Paths/SvgPathBuilder.cs @@ -189,10 +189,14 @@ 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 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++) diff --git a/SvgDocument.cs b/SvgDocument.cs index e350752d4c70099939ee7f90a2f282332862572f..bf5178d7180af71f1e4634e12a7360da574e3dc7 100644 --- a/SvgDocument.cs +++ b/SvgDocument.cs @@ -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); } diff --git a/SvgElementFactory.cs b/SvgElementFactory.cs index d83d080676c254986b4c0523ce2696253b0d965b..99cdc8bdf11b181784d98489ba54453f2a564db1 100644 --- a/SvgElementFactory.cs +++ b/SvgElementFactory.cs @@ -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 /// /// Contains information about a type inheriting from . /// - private struct ElementInfo + [DebuggerDisplay("{ElementName}, {ElementType}")] + internal sealed class ElementInfo { /// /// Gets the SVG name of the . @@ -195,11 +194,17 @@ namespace Svg /// Name of the element. /// Type of the element. public ElementInfo(string elementName, Type elementType) - : this() { this.ElementName = elementName; this.ElementType = elementType; } + + /// + /// Initializes a new instance of the class. + /// + public ElementInfo() + { + } } } } \ No newline at end of file diff --git a/Text/SvgText.cs b/Text/SvgText.cs index d099a8dcef4fac8cb6717d1e2b59c26641c7dded..24090e8883ca372014f2d6dcde0017e2ce10553f 100644 --- a/Text/SvgText.cs +++ b/Text/SvgText.cs @@ -186,15 +186,6 @@ namespace Svg get { return this.Path.GetBounds(); } } - /// - /// Renders the and contents to the specified object. - /// - /// The object to render to. - protected override void Render(SvgRenderer renderer) - { - base.Render(renderer); - } - static private int MeasureString(SvgRenderer renderer, string text, Font font) { GraphicsPath p = new GraphicsPath(); diff --git a/Text/SvgTextSpan.cs b/Text/SvgTextSpan.cs index cd00df9ac9ffe91ad55391741d6de5cd73216742..f7c6b01df660eea6844a8f8037a651bfb8a872e8 100644 --- a/Text/SvgTextSpan.cs +++ b/Text/SvgTextSpan.cs @@ -6,6 +6,7 @@ using System.Text; namespace Svg { + [SvgElement("tspan")] public class SvgTextSpan : SvgText { ///