SvgPath.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Xml.Serialization;
  7. using System.Xml;
  8. using System.Diagnostics;
  9. using Svg.ExtensionMethods;
  10. using Svg.Pathing;
  11. using Svg.Transforms;
  12. #pragma warning disable
  13. namespace Svg
  14. {
  15. /// <summary>
  16. /// Represents an SVG path element.
  17. /// </summary>
  18. [SvgElement("path")]
  19. public class SvgPath : SvgVisualElement
  20. {
  21. private GraphicsPath _path;
  22. /// <summary>
  23. /// Gets or sets a <see cref="SvgPathSegmentList"/> of path data.
  24. /// </summary>
  25. [SvgAttribute("d", true)]
  26. public SvgPathSegmentList PathData
  27. {
  28. get { return this.Attributes.GetAttribute<SvgPathSegmentList>("d"); }
  29. set
  30. {
  31. this.Attributes["d"] = value;
  32. value._owner = this;
  33. this.IsPathDirty = true;
  34. }
  35. }
  36. /// <summary>
  37. /// Gets or sets the length of the path.
  38. /// </summary>
  39. [SvgAttribute("pathLength", true)]
  40. public float PathLength
  41. {
  42. get { return this.Attributes.GetAttribute<float>("pathLength"); }
  43. set { this.Attributes["pathLength"] = value; }
  44. }
  45. /// <summary>
  46. /// Gets or sets the marker (end cap) of the path.
  47. /// </summary>
  48. [SvgAttribute("marker-end", true)]
  49. public Uri MarkerEnd
  50. {
  51. get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
  52. set { this.Attributes["marker-end"] = value; }
  53. }
  54. /// <summary>
  55. /// Gets or sets the marker (start cap) of the path.
  56. /// </summary>
  57. [SvgAttribute("marker-mid", true)]
  58. public Uri MarkerMid
  59. {
  60. get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
  61. set { this.Attributes["marker-mid"] = value; }
  62. }
  63. /// <summary>
  64. /// Gets or sets the marker (start cap) of the path.
  65. /// </summary>
  66. [SvgAttribute("marker-start", true)]
  67. public Uri MarkerStart
  68. {
  69. get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
  70. set { this.Attributes["marker-start"] = value; }
  71. }
  72. /// <summary>
  73. /// Gets the <see cref="GraphicsPath"/> for this element.
  74. /// </summary>
  75. public override GraphicsPath Path(ISvgRenderer renderer)
  76. {
  77. if (this._path == null || this.IsPathDirty)
  78. {
  79. _path = new GraphicsPath();
  80. foreach (SvgPathSegment segment in this.PathData)
  81. {
  82. segment.AddToPath(_path);
  83. }
  84. this.IsPathDirty = false;
  85. }
  86. return _path;
  87. }
  88. internal void OnPathUpdated()
  89. {
  90. this.IsPathDirty = true;
  91. OnAttributeChanged(new AttributeEventArgs { Attribute = "d", Value = this.Attributes.GetAttribute<SvgPathSegmentList>("d") });
  92. }
  93. /// <summary>
  94. /// Gets the bounds of the element.
  95. /// </summary>
  96. /// <value>The bounds.</value>
  97. public override System.Drawing.RectangleF Bounds
  98. {
  99. get { return this.Path(null).GetBounds(); }
  100. }
  101. /// <summary>
  102. /// Initializes a new instance of the <see cref="SvgPath"/> class.
  103. /// </summary>
  104. public SvgPath()
  105. {
  106. var pathData = new SvgPathSegmentList();
  107. this.Attributes["d"] = pathData;
  108. pathData._owner = this;
  109. }
  110. /// <summary>
  111. /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
  112. /// </summary>
  113. /// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
  114. protected internal override bool RenderStroke(ISvgRenderer renderer)
  115. {
  116. var result = base.RenderStroke(renderer);
  117. var path = this.Path(renderer);
  118. if (this.MarkerStart != null)
  119. {
  120. SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
  121. marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
  122. }
  123. if (this.MarkerMid != null)
  124. {
  125. SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
  126. for (int i = 1; i <= path.PathPoints.Length - 2; i++)
  127. marker.RenderMarker(renderer, this, path.PathPoints[i], path.PathPoints[i - 1], path.PathPoints[i], path.PathPoints[i + 1]);
  128. }
  129. if (this.MarkerEnd != null)
  130. {
  131. SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString());
  132. marker.RenderMarker(renderer, this, path.PathPoints[path.PathPoints.Length - 1], path.PathPoints[path.PathPoints.Length - 2], path.PathPoints[path.PathPoints.Length - 1]);
  133. }
  134. return result;
  135. }
  136. public override SvgElement DeepCopy()
  137. {
  138. return DeepCopy<SvgPath>();
  139. }
  140. public override SvgElement DeepCopy<T>()
  141. {
  142. var newObj = base.DeepCopy<T>() as SvgPath;
  143. foreach (var pathData in this.PathData)
  144. newObj.PathData.Add(pathData.Clone());
  145. newObj.PathLength = this.PathLength;
  146. newObj.MarkerStart = this.MarkerStart;
  147. newObj.MarkerEnd = this.MarkerEnd;
  148. return newObj;
  149. }
  150. }
  151. }
  152. #pragma warning restore