"vscode:/vscode.git/clone" did not exist on "0860e3de4781f1e97f24970d3c65514eec5e8b1a"
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