diff --git a/SvgNet/SVGGraphics.cs b/SvgNet/SVGGraphics.cs
index 22eb1b7..e4dad09 100644
--- a/SvgNet/SVGGraphics.cs
+++ b/SvgNet/SVGGraphics.cs
@@ -18,6 +18,7 @@
using System.IO;
using System.Collections.Generic;
using System.Linq;
+using System.Text;
namespace SvgNet.SvgGdi
{
@@ -1979,6 +1980,8 @@ public void DrawLines(Pen pen, Point[] points)
DrawLines(pen, pts);
}
+
+
///
/// Implemented
///
@@ -1989,86 +1992,15 @@ public void DrawLines(Pen pen, Point[] points)
///
public void DrawPath(Pen pen, GraphicsPath path)
{
- //Save the original pen dash style in case we need to change it
- DashStyle originalPenDashStyle = pen.DashStyle;
-
- GraphicsPathIterator subpaths = new GraphicsPathIterator(path);
- GraphicsPath subpath = new GraphicsPath(path.FillMode);
- subpaths.Rewind();
-
- //Iterate through all the subpaths in the path. Each subpath will contain either
- //lines or Bezier curves
- for (int s = 0; s < subpaths.SubpathCount; s++)
+ foreach (SvgPath data in HandleGraphicsPath(path))
{
- bool isClosed;
- if (subpaths.NextSubpath(subpath, out isClosed) == 0)
- {
- continue; //go to next subpath if this one has zero points.
- }
- PointF start = new PointF(0, 0);
- PointF origin = subpath.PathPoints[0];
- PointF last = subpath.PathPoints[subpath.PathPoints.Length - 1];
- int bezierCurvePointsIndex = 0;
- PointF[] bezierCurvePoints = new PointF[4];
- for (int i = 0; i < subpath.PathPoints.Length; i++)
- {
- /* Each subpath point has a corresponding path point type which can be:
- *The point starts the subpath
- *The point is a line point
- *The point is Bezier curve point
- * Another point type like dash-mode
- */
- switch ((PathPointType)subpath.PathTypes[i] & PathPointType.PathTypeMask) //Mask off non path-type types
- {
- case PathPointType.Start:
- start = subpath.PathPoints[i];
- bezierCurvePoints[0] = subpath.PathPoints[i];
- bezierCurvePointsIndex = 1;
- pen.DashStyle = originalPenDashStyle; //Reset pen dash mode to original when starting subpath
- continue;
- case PathPointType.Line:
- DrawLine(pen, start, subpath.PathPoints[i]); //Draw a line segment ftom start point
- start = subpath.PathPoints[i]; //Move start point to line end
- bezierCurvePoints[0] = subpath.PathPoints[i]; //A line point can also be the start of a Bezier curve
- bezierCurvePointsIndex = 1;
- continue;
- case PathPointType.Bezier3:
- bezierCurvePoints[bezierCurvePointsIndex++] = subpath.PathPoints[i];
- if (bezierCurvePointsIndex == 4) //If 4 points including start have been found then draw the Bezier curve
- {
- DrawBezier(pen, bezierCurvePoints[0], bezierCurvePoints[1], bezierCurvePoints[2], bezierCurvePoints[3]);
- bezierCurvePoints = new PointF[4];
- bezierCurvePoints[0] = subpath.PathPoints[i];
- bezierCurvePointsIndex = 1;
- start = subpath.PathPoints[i]; //Move start point to curve end
- }
- continue;
- default:
- switch ((PathPointType)subpath.PathTypes[i])
- {
- case PathPointType.DashMode:
- pen.DashStyle = DashStyle.Dash;
- continue;
- default:
- throw new SvgException("Unknown path type value: " + subpath.PathTypes[i]);
- }
- }
- }
- if (isClosed) //If the subpath is closed and it is a linear figure then draw the last connecting line segment
- {
- PathPointType originType = (PathPointType)subpath.PathTypes[0];
- PathPointType lastType = (PathPointType) subpath.PathTypes[subpath.PathPoints.Length - 1];
-
- if (((lastType & PathPointType.PathTypeMask) == PathPointType.Line) && ((originType & PathPointType.PathTypeMask) == PathPointType.Line))
- {
- DrawLine(pen, last, origin);
- }
- }
-
+ SvgPathElement pathElement = new SvgPathElement();
+ pathElement.Style = new SvgStyle(pen);
+ pathElement.D = data;
+ if (!_transforms.Result.IsIdentity)
+ pathElement.Transform = new SvgTransformList(_transforms.Result.Clone());
+ _cur.AddChild(pathElement);
}
- subpath.Dispose();
- subpaths.Dispose();
- pen.DashStyle = originalPenDashStyle;
}
///
@@ -2355,33 +2287,15 @@ public void FillEllipse(Brush brush, Int32 x, Int32 y, Int32 width, Int32 height
///
public void FillPath(Brush brush, GraphicsPath path)
{
- GraphicsPathIterator subpaths = new GraphicsPathIterator(path);
- GraphicsPath subpath = new GraphicsPath(path.FillMode);
- subpaths.Rewind();
- for (int s = 0; s < subpaths.SubpathCount; s++)
+ foreach (var svgPath in HandleGraphicsPath(path))
{
- bool isClosed;
- if (subpaths.NextSubpath(subpath, out isClosed) < 2)
- {
- continue;
- }
- if (!isClosed)
- {
- //subpath.CloseAllFigures();
- }
- PathPointType lastType = (PathPointType)subpath.PathTypes[subpath.PathPoints.Length - 1];
- if (subpath.PathTypes.Any(pt => ((PathPointType) pt & PathPointType.PathTypeMask) == PathPointType.Line))
- {
- FillPolygon(brush, subpath.PathPoints, path.FillMode);
- }
- else
- {
- FillBeziers(brush, subpath.PathPoints, path.FillMode);
- }
-
+ var pathElement = new SvgPathElement();
+ pathElement.Style = HandleBrush(brush);
+ pathElement.D = svgPath;
+ if (!_transforms.Result.IsIdentity)
+ pathElement.Transform = new SvgTransformList(_transforms.Result.Clone());
+ _cur.AddChild(pathElement);
}
- subpath.Dispose();
- subpaths.Dispose();
}
///
@@ -3635,6 +3549,69 @@ private void FillBeziers(Brush brush, PointF[] points, FillMode fillmode)
_cur.AddChild(bez);
}
+ private IEnumerable HandleGraphicsPath(GraphicsPath path)
+ {
+ StringBuilder pathBuilder = new StringBuilder();
+ using (GraphicsPathIterator subpaths = new GraphicsPathIterator(path))
+ using (GraphicsPath subpath = new GraphicsPath(path.FillMode))
+ {
+ subpaths.Rewind();
+
+ //Iterate through all the subpaths in the path. Each subpath will contain either
+ //lines or Bezier curves
+ for (int s = 0; s < subpaths.SubpathCount; s++)
+ {
+ bool isClosed;
+ if (subpaths.NextSubpath(subpath, out isClosed) == 0)
+ {
+ continue; //go to next subpath if this one has zero points.
+ }
+
+ PathPointType lastType = PathPointType.Start;
+ for (int i = 0; i < subpath.PathPoints.Length; i++)
+ {
+ /* Each subpath point has a corresponding path point type which can be:
+ *The point starts the subpath
+ *The point is a line point
+ *The point is Bezier curve point
+ */
+ PointF point = subpath.PathPoints[i];
+ PathPointType pathType = (PathPointType)subpath.PathTypes[i] & PathPointType.PathTypeMask;
+ switch (pathType) //Mask off non path-type types
+ {
+ case PathPointType.Start:
+ //Move to start point
+ pathBuilder.AppendFormat(CultureInfo.InvariantCulture, "M {0},{1}", point.X, point.Y);
+ break;
+ case PathPointType.Line:
+ // Draw line to current point
+ if (lastType != PathPointType.Line) pathBuilder.Append(" L");
+ pathBuilder.AppendFormat(CultureInfo.InvariantCulture, " {0},{1}", point.X, point.Y);
+ break;
+ case PathPointType.Bezier3:
+ // Draw curve to current point
+ if (lastType != PathPointType.Bezier3) pathBuilder.Append(" C");
+ pathBuilder.AppendFormat(CultureInfo.InvariantCulture, " {0},{1}", point.X, point.Y);
+ break;
+ default:
+ continue;
+ }
+
+ lastType = pathType;
+ }
+
+ if (isClosed)
+ {
+ // Close path
+ pathBuilder.Append(" Z");
+ }
+
+ yield return new SvgPath(pathBuilder.ToString());
+ pathBuilder.Clear();
+ }
+ }
+ }
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// When a GDI instruction with a brush parameter is called, there can be a lot we have to do to emulate the brush. The aim is to return a