Commit 2d7852b7 authored by mrbean-bremen's avatar mrbean-bremen Committed by mrbean-bremen
Browse files

Moved similar marker related code to super class

- handle markers on paths with successive equal points
 (fixing drawing of __issue-345-01.svg)
parent e3b789e5
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using Svg.ExtensionMethods;
namespace Svg
{
......@@ -9,7 +7,7 @@ namespace Svg
/// Represents and SVG line element.
/// </summary>
[SvgElement("line")]
public class SvgLine : SvgPathBasedElement
public class SvgLine : SvgMarkerElement
{
private SvgUnit _startX;
private SvgUnit _startY;
......@@ -77,38 +75,6 @@ namespace Svg
}
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end")]
public Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-mid")]
public Uri MarkerMid
{
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start")]
public Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; }
}
public override SvgPaintServer Fill
{
get { return null; /* Line can't have a fill */ }
......@@ -152,37 +118,6 @@ namespace Svg
return this._path;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override bool RenderStroke(ISvgRenderer renderer)
{
var result = base.RenderStroke(renderer);
var path = this.Path(renderer);
if (this.MarkerStart != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
}
if (this.MarkerMid != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
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]);
}
if (this.MarkerEnd != null)
{
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]);
}
return result;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgLine>();
......
using Svg.ExtensionMethods;
using System;
namespace Svg
{
/// <summary>
/// Represents a path based element that can have markers.
/// </summary>
public abstract class SvgMarkerElement : SvgPathBasedElement
{
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end", true)]
public Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-mid", true)]
public Uri MarkerMid
{
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start", true)]
public Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; }
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override bool RenderStroke(ISvgRenderer renderer)
{
var result = base.RenderStroke(renderer);
var path = this.Path(renderer);
var pathLength = path.PathPoints.Length;
if (this.MarkerStart != null)
{
var refPoint1 = path.PathPoints[0];
var index = 1;
while (index < pathLength && path.PathPoints[index] == refPoint1)
{
++index;
}
var refPoint2 = path.PathPoints[index];
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, refPoint1, refPoint1, refPoint2);
}
if (this.MarkerMid != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
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]);
}
if (this.MarkerEnd != null)
{
var index = pathLength - 1;
var refPoint1 = path.PathPoints[index];
--index;
while (index > 0 && path.PathPoints[index] == refPoint1)
{
--index;
}
var refPoint2 = path.PathPoints[index];
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerEnd.ToString());
marker.RenderMarker(renderer, this, refPoint1, refPoint2, path.PathPoints[path.PathPoints.Length - 1]);
}
return result;
}
}
}
using System;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using Svg.ExtensionMethods;
namespace Svg
{
......@@ -9,7 +7,7 @@ namespace Svg
/// SvgPolygon defines a closed shape consisting of a set of connected straight line segments.
/// </summary>
[SvgElement("polygon")]
public class SvgPolygon : SvgPathBasedElement
public class SvgPolygon : SvgMarkerElement
{
private GraphicsPath _path;
......@@ -23,38 +21,6 @@ namespace Svg
set { this.Attributes["points"] = value; this.IsPathDirty = true; }
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end")]
public virtual Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-mid")]
public virtual Uri MarkerMid
{
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start")]
public virtual Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; }
}
public override GraphicsPath Path(ISvgRenderer renderer)
{
if (this._path == null || this.IsPathDirty)
......@@ -101,37 +67,6 @@ namespace Svg
return this._path;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override bool RenderStroke(ISvgRenderer renderer)
{
var result = base.RenderStroke(renderer);
var path = this.Path(renderer);
if (this.MarkerStart != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
}
if (this.MarkerMid != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
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]);
}
if (this.MarkerEnd != null)
{
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]);
}
return result;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgPolygon>();
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using Svg.ExtensionMethods;
namespace Svg
{
......@@ -14,38 +11,6 @@ namespace Svg
[SvgElement("polyline")]
public class SvgPolyline : SvgPolygon
{
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end")]
public override Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-mid")]
public override Uri MarkerMid
{
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start")]
public override Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; }
}
private GraphicsPath _Path;
public override GraphicsPath Path(ISvgRenderer renderer)
{
......@@ -87,36 +52,5 @@ namespace Svg
}
return _Path;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override bool RenderStroke(ISvgRenderer renderer)
{
var result = base.RenderStroke(renderer);
var path = this.Path(renderer);
if (this.MarkerStart != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
}
if (this.MarkerMid != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
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]);
}
if (this.MarkerEnd != null)
{
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]);
}
return result;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using System.Xml;
using System.Diagnostics;
using Svg.ExtensionMethods;
using Svg.Pathing;
using Svg.Transforms;
namespace Svg
{
......@@ -16,7 +7,7 @@ namespace Svg
/// Represents an SVG path element.
/// </summary>
[SvgElement("path")]
public class SvgPath : SvgVisualElement
public class SvgPath : SvgMarkerElement
{
private GraphicsPath _path;
......@@ -45,39 +36,7 @@ namespace Svg
set { this.Attributes["pathLength"] = value; }
}
/// <summary>
/// Gets or sets the marker (end cap) of the path.
/// </summary>
[SvgAttribute("marker-end", true)]
public Uri MarkerEnd
{
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-mid", true)]
public Uri MarkerMid
{
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; }
}
/// <summary>
/// Gets or sets the marker (start cap) of the path.
/// </summary>
[SvgAttribute("marker-start", true)]
public Uri MarkerStart
{
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; }
}
/// <summary>
/// Gets the <see cref="GraphicsPath"/> for this element.
......@@ -123,37 +82,6 @@ namespace Svg
pathData._owner = this;
}
/// <summary>
/// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="ISvgRenderer"/>
/// </summary>
/// <param name="renderer">The <see cref="ISvgRenderer"/> object to render to.</param>
protected internal override bool RenderStroke(ISvgRenderer renderer)
{
var result = base.RenderStroke(renderer);
var path = this.Path(renderer);
if (this.MarkerStart != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerStart.ToString());
marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]);
}
if (this.MarkerMid != null)
{
SvgMarker marker = this.OwnerDocument.GetElementById<SvgMarker>(this.MarkerMid.ToString());
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]);
}
if (this.MarkerEnd != null)
{
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]);
}
return result;
}
public override SvgElement DeepCopy()
{
return DeepCopy<SvgPath>();
......
......@@ -91,6 +91,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Basic Shapes\SvgImage.cs" />
<Compile Include="Basic Shapes\SvgMarkerElement.cs" />
<Compile Include="Basic Shapes\SvgPathBasedElement.cs" />
<Compile Include="Basic Shapes\SvgVisualElement.cs" />
<Compile Include="Basic Shapes\SvgCircle.cs" />
......
......@@ -187,6 +187,7 @@ __issue-323-03
__issue-329-01
__issue-338-01_stroke_width
__issue-342-01
__issue-345-01
__issue-354-01
__issue-385-01_Test_text-anchor-middle
__issue-398-01
......
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