From b3b2655c6c1ad5a6c760d445be214407e0c4e74f Mon Sep 17 00:00:00 2001 From: davescriven Date: Fri, 26 Dec 2008 04:48:05 +0000 Subject: [PATCH] - Fixed a bug that caused elements to be parsed incorrectly, leading to exceptions within the document. --- Basic Shapes/SvgVisualElement.cs | 81 +++++++++++++++------------ Basic Shapes/SvgVisualElementStyle.cs | 6 ++ DataTypes/SvgUnit.cs | 3 - Paths/SvgPathBuilder.cs | 6 +- SvgDocument.cs | 2 +- SvgElementFactory.cs | 21 ++++--- Text/SvgText.cs | 9 --- Text/SvgTextSpan.cs | 1 + 8 files changed, 72 insertions(+), 57 deletions(-) diff --git a/Basic Shapes/SvgVisualElement.cs b/Basic Shapes/SvgVisualElement.cs index 65cab4f..e11a49f 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 ea5d906..ff00673 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 09ced84..589ca0c 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 387d125..1a0b46b 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 e350752..bf5178d 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 d83d080..99cdc8b 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 d099a8d..24090e8 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 cd00df9..f7c6b01 100644 --- a/Text/SvgTextSpan.cs +++ b/Text/SvgTextSpan.cs @@ -6,6 +6,7 @@ using System.Text; namespace Svg { + [SvgElement("tspan")] public class SvgTextSpan : SvgText { /// -- GitLab