Commit 9521956d authored by Tebjan Halm's avatar Tebjan Halm Committed by Eric Domke
Browse files

Revert ".Net 3.5 Support and Rendering Improvements (Markers, TSpans, Paths, etc.)"

parent 2261cfdb
...@@ -22,14 +22,12 @@ namespace SVGViewer ...@@ -22,14 +22,12 @@ namespace SVGViewer
private void open_Click(object sender, EventArgs e) private void open_Click(object sender, EventArgs e)
{ {
//if (openSvgFile.ShowDialog() == DialogResult.OK) if (openSvgFile.ShowDialog() == DialogResult.OK)
//{ {
//var path = openSvgFile.FileName; SvgDocument svgDoc = SvgDocument.Open(openSvgFile.FileName);
var path = @"C:\Users\edomke\AppData\Local\Temp\map.svg";
SvgDocument svgDoc = SvgDocument.Open(path);
RenderSvg(svgDoc); RenderSvg(svgDoc);
//} }
} }
private string FXML = ""; private string FXML = "";
......
...@@ -5,12 +5,11 @@ using System.Text; ...@@ -5,12 +5,11 @@ using System.Text;
namespace Svg.DataTypes namespace Svg.DataTypes
{ {
public enum SvgFontWeight public enum SvgFontWeight
{ {
inherit, normal,
normal, bold
bold }
}
} }
...@@ -7,8 +7,8 @@ namespace Svg ...@@ -7,8 +7,8 @@ namespace Svg
/// <summary> /// <summary>
/// Represents an orientation in an Scalable Vector Graphics document. /// Represents an orientation in an Scalable Vector Graphics document.
/// </summary> /// </summary>
[TypeConverter(typeof(SvgOrientConverter))] [TypeConverter(typeof(SvgOrientConverter))]
public class SvgOrient public class SvgOrient
{ {
private bool _isAuto = true; private bool _isAuto = true;
private float _angle; private float _angle;
...@@ -100,22 +100,6 @@ namespace Svg ...@@ -100,22 +100,6 @@ namespace Svg
{ {
return new SvgOrient(value); return new SvgOrient(value);
} }
public static implicit operator SvgOrient(string value)
{
float angle;
if (value == "auto")
{
return new SvgOrient();
}
else if (float.TryParse(value, out angle))
{
return new SvgOrient(angle);
}
else
{
throw new ArgumentException("The value '" + value + "' cannot be converted to an SVG value.");
}
}
} }
......
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Globalization; using System.Globalization;
namespace Svg namespace Svg.DataTypes
{ {
public sealed class SvgOrientConverter : TypeConverter public sealed class SvgOrientConverter : TypeConverter
{ {
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{ {
if (value == null || value.ToString() == string.Empty || value.ToString() == "auto") if (value == null)
{ {
return new SvgOrient(); return new SvgUnit(SvgUnitType.User, 0.0f);
} }
else if (value is float)
{ if (!(value is string))
return new SvgOrient((float)value); {
} throw new ArgumentOutOfRangeException("value must be a string.");
else if (value is int) }
{
return new SvgOrient((float)value); switch (value.ToString())
} {
case "auto":
throw new ArgumentException("The value '" + value.ToString() + "' cannot be converted to an SVG value."); return (new SvgOrient());
} default:
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) float fTmp = float.MinValue;
{ if(!float.TryParse(value.ToString(), out fTmp))
if (sourceType == typeof(string) || sourceType == typeof(float) || sourceType == typeof(int)) throw new ArgumentOutOfRangeException("value must be a valid float.");
{ return (new SvgOrient(fTmp));
return true; }
} }
return base.CanConvertFrom(context, sourceType); public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
} {
if (sourceType == typeof(string))
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
{ return true;
if (destinationType == typeof(string)) }
{
return true; return base.CanConvertFrom(context, sourceType);
} }
return base.CanConvertTo(context, destinationType); public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
} {
if (destinationType == typeof(string))
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
{ return true;
if (destinationType == typeof(string)) }
{
return ((SvgOrient)value).ToString(); return base.CanConvertTo(context, destinationType);
} }
return base.ConvertTo(context, culture, value, destinationType); public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
} {
} return base.ConvertTo(context, culture, value, destinationType);
}
}
} }
...@@ -45,7 +45,6 @@ namespace Svg ...@@ -45,7 +45,6 @@ namespace Svg
{ {
if (value is string) if (value is string)
{ {
if (string.Compare(((string)value).Trim(), "none", StringComparison.InvariantCultureIgnoreCase) == 0) return null;
string[] points = ((string)value).Trim().Split(new char[] { ',', ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries); string[] points = ((string)value).Trim().Split(new char[] { ',', ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries);
SvgUnitCollection units = new SvgUnitCollection(); SvgUnitCollection units = new SvgUnitCollection();
......
...@@ -5,14 +5,24 @@ using System.ComponentModel; ...@@ -5,14 +5,24 @@ using System.ComponentModel;
namespace Svg namespace Svg
{ {
[DefaultProperty("Text")]
[SvgElement("desc")] [SvgElement("desc")]
public class SvgDescription : SvgElement public class SvgDescription : SvgElement
{ {
private string _text;
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public override string ToString() public override string ToString()
{ {
return this.Content; return this.Text;
} }
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgDescription>(); return DeepCopy<SvgDescription>();
...@@ -21,6 +31,7 @@ namespace Svg ...@@ -21,6 +31,7 @@ namespace Svg
public override SvgElement DeepCopy<T>() public override SvgElement DeepCopy<T>()
{ {
var newObj = base.DeepCopy<T>() as SvgDescription; var newObj = base.DeepCopy<T>() as SvgDescription;
newObj.Text = this.Text;
return newObj; return newObj;
} }
......
...@@ -7,12 +7,7 @@ namespace Svg ...@@ -7,12 +7,7 @@ namespace Svg
{ {
[SvgElement("title")] [SvgElement("title")]
public class SvgTitle : SvgElement public class SvgTitle : SvgElement
{ {
public override string ToString()
{
return this.Content;
}
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgTitle>(); return DeepCopy<SvgTitle>();
......
...@@ -13,7 +13,7 @@ namespace Svg ...@@ -13,7 +13,7 @@ namespace Svg
{ {
private Uri _referencedElement; private Uri _referencedElement;
[SvgAttribute("href", SvgAttributeAttribute.XLinkNamespace)] [SvgAttribute("xlink:href")]
public virtual Uri ReferencedElement public virtual Uri ReferencedElement
{ {
get { return this._referencedElement; } get { return this._referencedElement; }
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Svg
{
public static class Extensions
{
public static IEnumerable<SvgElement> Descendants<T>(this IEnumerable<T> source) where T : SvgElement
{
if (source == null) throw new ArgumentNullException("source");
return GetDescendants<T>(source, false);
}
private static IEnumerable<SvgElement> GetAncestors<T>(IEnumerable<T> source, bool self) where T : SvgElement
{
foreach (var start in source)
{
if (start != null)
{
for (var elem = (self ? start : start.Parent) as SvgElement; elem != null; elem = (elem.Parent as SvgElement))
{
yield return elem;
}
}
}
yield break;
}
private static IEnumerable<SvgElement> GetDescendants<T>(IEnumerable<T> source, bool self) where T : SvgElement
{
var positons = new Stack<int>();
int currPos;
SvgElement currParent;
foreach (var start in source)
{
if (start != null)
{
if (self) yield return start;
positons.Push(0);
currParent = start;
while (positons.Count > 0)
{
currPos = positons.Pop();
if (currPos < currParent.Children.Count)
{
yield return currParent.Children[currPos];
currParent = currParent.Children[currPos];
positons.Push(currPos + 1);
positons.Push(0);
}
else
{
currParent = currParent.Parent;
}
}
}
}
yield break;
}
}
}
...@@ -14,7 +14,7 @@ namespace Svg.FilterEffects ...@@ -14,7 +14,7 @@ namespace Svg.FilterEffects
[SvgElement("feGaussianBlur")] [SvgElement("feGaussianBlur")]
public class SvgGaussianBlur : SvgFilterPrimitive public class SvgGaussianBlur : SvgFilterPrimitive
{ {
private float _stdDeviation; private int _stdDeviation;
private BlurType _blurType; private BlurType _blurType;
private int[] _kernel; private int[] _kernel;
...@@ -26,13 +26,12 @@ namespace Svg.FilterEffects ...@@ -26,13 +26,12 @@ namespace Svg.FilterEffects
{ {
} }
public SvgGaussianBlur(float stdDeviation) public SvgGaussianBlur(int stdDeviation)
: this(stdDeviation, BlurType.Both) : this(stdDeviation, BlurType.Both)
{ {
} }
public SvgGaussianBlur(float stdDeviation, BlurType blurType) public SvgGaussianBlur(int stdDeviation, BlurType blurType) : base()
: base()
{ {
_stdDeviation = stdDeviation; _stdDeviation = stdDeviation;
_blurType = blurType; _blurType = blurType;
...@@ -43,13 +42,13 @@ namespace Svg.FilterEffects ...@@ -43,13 +42,13 @@ namespace Svg.FilterEffects
private void PreCalculate() private void PreCalculate()
{ {
int sz = (int)(_stdDeviation * 2 + 1); int sz = _stdDeviation * 2 + 1;
_kernel = new int[sz]; _kernel = new int[sz];
_multable = new int[sz, 256]; _multable = new int[sz, 256];
for (int i = 1; i <= _stdDeviation; i++) for (int i = 1; i <= _stdDeviation; i++)
{ {
int szi = (int)(_stdDeviation - i); int szi = _stdDeviation - i;
int szj = (int)(_stdDeviation + i); int szj = _stdDeviation + i;
_kernel[szj] = _kernel[szi] = (szi + 1) * (szi + 1); _kernel[szj] = _kernel[szi] = (szi + 1) * (szi + 1);
_kernelSum += (_kernel[szj] + _kernel[szi]); _kernelSum += (_kernel[szj] + _kernel[szi]);
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
...@@ -57,11 +56,11 @@ namespace Svg.FilterEffects ...@@ -57,11 +56,11 @@ namespace Svg.FilterEffects
_multable[szj, j] = _multable[szi, j] = _kernel[szj] * j; _multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
} }
} }
_kernel[(int)_stdDeviation] = (int)((_stdDeviation + 1) * (_stdDeviation + 1)); _kernel[_stdDeviation] = (_stdDeviation + 1) * (_stdDeviation + 1);
_kernelSum += _kernel[(int)_stdDeviation]; _kernelSum += _kernel[_stdDeviation];
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
{ {
_multable[(int)_stdDeviation, j] = _kernel[(int)_stdDeviation] * j; _multable[_stdDeviation, j] = _kernel[_stdDeviation] * j;
} }
} }
...@@ -105,7 +104,7 @@ namespace Svg.FilterEffects ...@@ -105,7 +104,7 @@ namespace Svg.FilterEffects
for (int i = 0; i < pixelCount; i++) for (int i = 0; i < pixelCount; i++)
{ {
bsum = gsum = rsum = asum = 0; bsum = gsum = rsum = asum = 0;
read = (int)(i - _stdDeviation); read = i - _stdDeviation;
for (int z = 0; z < _kernel.Length; z++) for (int z = 0; z < _kernel.Length; z++)
{ {
if (read < start) if (read < start)
...@@ -157,7 +156,7 @@ namespace Svg.FilterEffects ...@@ -157,7 +156,7 @@ namespace Svg.FilterEffects
index = 0; index = 0;
for (int i = 0; i < src.Height; i++) for (int i = 0; i < src.Height; i++)
{ {
int y = (int)(i - _stdDeviation); int y = i - _stdDeviation;
start = y * src.Width; start = y * src.Width;
for (int j = 0; j < src.Width; j++) for (int j = 0; j < src.Width; j++)
{ {
...@@ -224,12 +223,12 @@ namespace Svg.FilterEffects ...@@ -224,12 +223,12 @@ namespace Svg.FilterEffects
/// Gets or sets the radius of the blur (only allows for one value - not the two specified in the SVG Spec) /// Gets or sets the radius of the blur (only allows for one value - not the two specified in the SVG Spec)
/// </summary> /// </summary>
[SvgAttribute("stdDeviation")] [SvgAttribute("stdDeviation")]
public float StdDeviation public int StdDeviation
{ {
get { return _stdDeviation; } get { return _stdDeviation; }
set set
{ {
if (value <= 0) if (value < 1)
{ {
throw new InvalidOperationException("Radius must be greater then 0"); throw new InvalidOperationException("Radius must be greater then 0");
} }
......
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Local" id="ad4d99d5-165f-493c-9b8f-937d51b9a02a" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are default test settings for a local test run.</Description>
<Deployment enabled="false" />
<Execution>
<TestTypeSpecific />
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>
\ No newline at end of file
...@@ -50,18 +50,7 @@ namespace Svg ...@@ -50,18 +50,7 @@ namespace Svg
//so we have to determine the corosponding byte value //so we have to determine the corosponding byte value
alphaValue = (int)(decimal.Parse(values[3]) * 255); alphaValue = (int)(decimal.Parse(values[3]) * 255);
} }
Color colorpart = System.Drawing.Color.FromArgb(alphaValue, int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]));
Color colorpart;
if (values[0].Trim().EndsWith("%"))
{
colorpart = System.Drawing.Color.FromArgb(alphaValue, (int)(255 * float.Parse(values[0].Trim().TrimEnd('%')) / 100f),
(int)(255 * float.Parse(values[1].Trim().TrimEnd('%')) / 100f),
(int)(255 * float.Parse(values[2].Trim().TrimEnd('%')) / 100f));
}
else
{
colorpart = System.Drawing.Color.FromArgb(alphaValue, int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]));
}
return colorpart; return colorpart;
} }
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Svg
{
/// <summary>
/// A wrapper for a paint server which isn't defined currently in the parse process, but
/// should be defined by the time the image needs to render.
/// </summary>
public class SvgDeferredPaintServer : SvgPaintServer
{
private bool _serverLoaded = false;
private SvgPaintServer _concreteServer;
public SvgDocument Document { get; set; }
public string DeferredId { get; set; }
public SvgDeferredPaintServer() {}
public SvgDeferredPaintServer(SvgDocument document, string id)
{
this.Document = document;
this.DeferredId = id;
}
private void EnsureServer()
{
if (!_serverLoaded)
{
_concreteServer = this.Document.IdManager.GetElementById(this.DeferredId) as SvgPaintServer;
_serverLoaded = true;
}
}
public override System.Drawing.Brush GetBrush(SvgVisualElement styleOwner, float opacity)
{
EnsureServer();
return _concreteServer.GetBrush(styleOwner, opacity);
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgDeferredPaintServer>();
}
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgDeferredPaintServer;
newObj.Document = this.Document;
newObj.DeferredId = this.DeferredId;
return newObj;
}
public override bool Equals(object obj)
{
var other = obj as SvgDeferredPaintServer;
if (other == null)
return false;
return this.Document == other.Document && this.DeferredId == other.DeferredId;
}
public override int GetHashCode()
{
if (this.Document == null || this.DeferredId == null) return 0;
return this.Document.GetHashCode() ^ this.DeferredId.GetHashCode();
}
public override string ToString()
{
return (_serverLoaded ? _serverLoaded.ToString() : string.Format("deferred: {0}", this.DeferredId));
}
public static T TryGet<T>(SvgPaintServer server) where T : SvgPaintServer
{
var deferred = server as SvgDeferredPaintServer;
if (deferred == null)
{
return server as T;
}
else
{
return deferred._concreteServer as T;
}
}
}
}
...@@ -11,7 +11,7 @@ namespace Svg ...@@ -11,7 +11,7 @@ namespace Svg
{ {
private SvgCoordinateUnits _gradientUnits; private SvgCoordinateUnits _gradientUnits;
private SvgGradientSpreadMethod _spreadMethod = SvgGradientSpreadMethod.Pad; private SvgGradientSpreadMethod _spreadMethod = SvgGradientSpreadMethod.Pad;
private SvgPaintServer _inheritGradient; private SvgGradientServer _inheritGradient;
private List<SvgGradientStop> _stops; private List<SvgGradientStop> _stops;
/// <summary> /// <summary>
...@@ -86,12 +86,13 @@ namespace Svg ...@@ -86,12 +86,13 @@ namespace Svg
/// Gets or sets another gradient fill from which to inherit the stops from. /// Gets or sets another gradient fill from which to inherit the stops from.
/// </summary> /// </summary>
[SvgAttribute("href")] [SvgAttribute("href")]
public SvgPaintServer InheritGradient public SvgGradientServer InheritGradient
{ {
get { return this._inheritGradient; } get { return this._inheritGradient; }
set set
{ {
this._inheritGradient = value; this._inheritGradient = value;
this.InheritStops();
} }
} }
...@@ -189,15 +190,18 @@ namespace Svg ...@@ -189,15 +190,18 @@ namespace Svg
return blend; return blend;
} }
protected void LoadStops() /// <summary>
// If this gradient contains no stops then it will search any inherited gradients for stops.
/// </summary>
protected virtual void InheritStops()
{ {
var core = SvgDeferredPaintServer.TryGet<SvgGradientServer>(_inheritGradient); if (this.Stops.Count == 0 && this.InheritGradient != null)
if (this.Stops.Count == 0 && core != null)
{ {
_stops.AddRange(core.Stops); _stops.AddRange(this.InheritGradient.Stops);
} }
} }
public override SvgElement DeepCopy<T>() public override SvgElement DeepCopy<T>()
{ {
var newObj = base.DeepCopy<T>() as SvgGradientServer; var newObj = base.DeepCopy<T>() as SvgGradientServer;
......
...@@ -75,7 +75,6 @@ namespace Svg ...@@ -75,7 +75,6 @@ namespace Svg
public override Brush GetBrush(SvgVisualElement owner, float opacity) public override Brush GetBrush(SvgVisualElement owner, float opacity)
{ {
LoadStops();
// Need at least 2 colours to do the gradient fill // Need at least 2 colours to do the gradient fill
if (this.Stops.Count < 2) if (this.Stops.Count < 2)
{ {
......
...@@ -14,16 +14,8 @@ namespace Svg ...@@ -14,16 +14,8 @@ namespace Svg
[SvgElement("marker")] [SvgElement("marker")]
public class SvgMarker : SvgVisualElement, ISvgViewPort public class SvgMarker : SvgVisualElement, ISvgViewPort
{ {
private SvgMarkerUnits _svgMarkerUnits = SvgMarkerUnits.strokeWidth;
private SvgOrient _svgOrient = new SvgOrient(); private SvgOrient _svgOrient = new SvgOrient();
[SvgAttribute("markerUnits")]
public virtual SvgMarkerUnits MarkerUnits
{
get { return _svgMarkerUnits; }
set { _svgMarkerUnits = value; }
}
[SvgAttribute("refX")] [SvgAttribute("refX")]
public virtual SvgUnit RefX public virtual SvgUnit RefX
{ {
......
...@@ -38,18 +38,7 @@ namespace Svg ...@@ -38,18 +38,7 @@ namespace Svg
{ {
return (SvgPaintServer)document.IdManager.GetElementById(value); return (SvgPaintServer)document.IdManager.GetElementById(value);
} }
else if (value.StartsWith("#")) // Otherwise try and parse as colour else // Otherwise try and parse as colour
{
try
{
return new SvgColourServer((Color)_colourConverter.ConvertFrom(value.Trim()));
}
catch
{
return new SvgDeferredPaintServer(document, value);
}
}
else
{ {
return new SvgColourServer((Color)_colourConverter.ConvertFrom(value.Trim())); return new SvgColourServer((Color)_colourConverter.ConvertFrom(value.Trim()));
} }
...@@ -60,7 +49,7 @@ namespace Svg ...@@ -60,7 +49,7 @@ namespace Svg
if (value is string) if (value is string)
{ {
var s = (string) value; var s = (string) value;
if(String.Equals( s.Trim(), "none", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(s) || s.Trim().Length < 1) if(String.Equals( s.Trim(), "none", StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(s))
return SvgPaintServer.None; return SvgPaintServer.None;
else else
return SvgPaintServerFactory.Create(s, (SvgDocument)context); return SvgPaintServerFactory.Create(s, (SvgDocument)context);
......
...@@ -76,7 +76,6 @@ namespace Svg ...@@ -76,7 +76,6 @@ namespace Svg
public override Brush GetBrush(SvgVisualElement renderingElement, float opacity) public override Brush GetBrush(SvgVisualElement renderingElement, float opacity)
{ {
LoadStops();
float radius = this.Radius.ToDeviceValue(renderingElement); float radius = this.Radius.ToDeviceValue(renderingElement);
if (radius <= 0) if (radius <= 0)
......
...@@ -8,14 +8,6 @@ namespace Svg.Pathing ...@@ -8,14 +8,6 @@ namespace Svg.Pathing
{ {
public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath graphicsPath) public override void AddToPath(System.Drawing.Drawing2D.GraphicsPath graphicsPath)
{ {
// Important for custom line caps. Force the path the close with an explicit line, not just an implicit close of the figure.
if (graphicsPath.PathPoints.Length > 1 && !graphicsPath.PathPoints[0].Equals(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1]))
{
int i = graphicsPath.PathTypes.Length - 1;
while (i >= 0 && graphicsPath.PathTypes[i] > 0) i--;
if (i < 0) i = 0;
graphicsPath.AddLine(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1], graphicsPath.PathPoints[i]);
}
graphicsPath.CloseFigure(); graphicsPath.CloseFigure();
} }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Linq;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Xml.Serialization; using System.Xml.Serialization;
...@@ -27,12 +26,12 @@ namespace Svg ...@@ -27,12 +26,12 @@ namespace Svg
public SvgPathSegmentList PathData public SvgPathSegmentList PathData
{ {
get { return this.Attributes.GetAttribute<SvgPathSegmentList>("d"); } get { return this.Attributes.GetAttribute<SvgPathSegmentList>("d"); }
set set
{ {
this.Attributes["d"] = value; this.Attributes["d"] = value;
value._owner = this; value._owner = this;
this.IsPathDirty = true; this.IsPathDirty = true;
} }
} }
/// <summary> /// <summary>
...@@ -41,7 +40,7 @@ namespace Svg ...@@ -41,7 +40,7 @@ namespace Svg
[SvgAttribute("pathLength")] [SvgAttribute("pathLength")]
public int PathLength public int PathLength
{ {
get { return this.Attributes.GetAttribute<int>("pathLength"); } get { return this.Attributes.GetAttribute<int>("pathLength"); }
set { this.Attributes["pathLength"] = value; } set { this.Attributes["pathLength"] = value; }
} }
...@@ -49,34 +48,34 @@ namespace Svg ...@@ -49,34 +48,34 @@ namespace Svg
/// <summary> /// <summary>
/// Gets or sets the marker (end cap) of the path. /// Gets or sets the marker (end cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-end")] [SvgAttribute("marker-end")]
public Uri MarkerEnd public Uri MarkerEnd
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-end"); } get { return this.Attributes.GetAttribute<Uri>("marker-end"); }
set { this.Attributes["marker-end"] = value; } set { this.Attributes["marker-end"] = value; }
} }
/// <summary> /// <summary>
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-mid")] [SvgAttribute("marker-mid")]
public Uri MarkerMid public Uri MarkerMid
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-mid"); } get { return this.Attributes.GetAttribute<Uri>("marker-mid"); }
set { this.Attributes["marker-mid"] = value; } set { this.Attributes["marker-mid"] = value; }
} }
/// <summary> /// <summary>
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-start")] [SvgAttribute("marker-start")]
public Uri MarkerStart public Uri MarkerStart
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-start"); } get { return this.Attributes.GetAttribute<Uri>("marker-start"); }
set { this.Attributes["marker-start"] = value; } set { this.Attributes["marker-start"] = value; }
} }
/// <summary> /// <summary>
...@@ -138,61 +137,62 @@ namespace Svg ...@@ -138,61 +137,62 @@ namespace Svg
pathData._owner = this; pathData._owner = this;
} }
/// <summary> /// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/>
/// </summary> /// </summary>
/// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param>
protected internal override void RenderStroke(SvgRenderer renderer) protected internal override void RenderStroke(SvgRenderer renderer)
{ {
if (this.Stroke != null) if (this.Stroke != null)
{ {
float strokeWidth = this.StrokeWidth.ToDeviceValue(this); float strokeWidth = this.StrokeWidth.ToDeviceValue(this);
using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth)) using (Pen pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth))
{ {
if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0)
{ {
/* divide by stroke width - GDI behaviour that I don't quite understand yet.*/ /* 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(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray();
} }
renderer.DrawPath(pen, this.Path); renderer.DrawPath(pen, this.Path);
if (this.MarkerStart != null) if (this.MarkerStart != null)
{ {
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString()); SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, Path.PathPoints[0], Path.PathPoints[0], Path.PathPoints[1]); marker.RenderMarker(renderer, this, Path.PathPoints[0], Path.PathPoints[0], Path.PathPoints[1]);
} }
if (this.MarkerMid != null) if (this.MarkerMid != null)
{ {
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString()); SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
for (int i = 1; i <= Path.PathPoints.Length - 2; i++) for (int i = 1; i <= Path.PathPoints.Length - 2; i++)
marker.RenderMarker(renderer, this, Path.PathPoints[i], Path.PathPoints[i - 1], Path.PathPoints[i], Path.PathPoints[i + 1]); marker.RenderMarker(renderer, this, Path.PathPoints[i], Path.PathPoints[i - 1], Path.PathPoints[i], Path.PathPoints[i + 1]);
} }
if (this.MarkerEnd != null) if (this.MarkerEnd != null)
{ {
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString()); SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString());
marker.RenderMarker(renderer, this, Path.PathPoints[Path.PathPoints.Length - 1], Path.PathPoints[Path.PathPoints.Length - 2], Path.PathPoints[Path.PathPoints.Length - 1]); marker.RenderMarker(renderer, this, Path.PathPoints[Path.PathPoints.Length - 1], Path.PathPoints[Path.PathPoints.Length - 2], Path.PathPoints[Path.PathPoints.Length - 1]);
} }
} }
} }
} }
public override SvgElement DeepCopy() public override SvgElement DeepCopy()
{ {
return DeepCopy<SvgPath>(); return DeepCopy<SvgPath>();
} }
public override SvgElement DeepCopy<T>() public override SvgElement DeepCopy<T>()
{ {
var newObj = base.DeepCopy<T>() as SvgPath; var newObj = base.DeepCopy<T>() as SvgPath;
foreach (var pathData in this.PathData) foreach (var pathData in this.PathData)
newObj.PathData.Add(pathData.Clone()); newObj.PathData.Add(pathData.Clone());
newObj.PathLength = this.PathLength; newObj.PathLength = this.PathLength;
newObj.MarkerStart = this.MarkerStart; newObj.MarkerStart = this.MarkerStart;
newObj.MarkerEnd = this.MarkerEnd; newObj.MarkerEnd = this.MarkerEnd;
return newObj; return newObj;
}
}
} }
} }
\ No newline at end of file
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