public static GraphicsPath CreatePath(SvgPathElement element) { GraphicsPath gp = new GraphicsPath(); SvgPointF initPoint = new SvgPointF(0, 0); SvgPointF lastPoint = new SvgPointF(0, 0); SvgPointF ptXY = new SvgPointF(0, 0); SvgPathSeg segment = null; SvgPathSegMoveto pathMoveTo = null; SvgPathSegLineto pathLineTo = null; SvgPathSegCurveto pathCurveTo = null; SvgPathSegArc pathArc = null; SvgPathSegList segments = element.PathSegList; int nElems = segments.NumberOfItems; for (int i = 0; i < nElems; i++) { segment = segments.GetItem(i); switch (segment.PathType) { case SvgPathType.MoveTo: //if (DynamicCast.Cast(segment, out pathMoveTo)) pathMoveTo = (SvgPathSegMoveto)segment; gp.StartFigure(); lastPoint = initPoint = pathMoveTo.AbsXY; break; case SvgPathType.LineTo: //else if (DynamicCast.Cast(segment, out pathLineTo)) pathLineTo = (SvgPathSegLineto)segment; ptXY = pathLineTo.AbsXY; gp.AddLine(lastPoint.X, lastPoint.Y, ptXY.X, ptXY.Y); lastPoint = ptXY; break; case SvgPathType.CurveTo: //else if (DynamicCast.Cast(segment, out pathCurveTo)) pathCurveTo = (SvgPathSegCurveto)segment; SvgPointF xy = pathCurveTo.AbsXY; SvgPointF x1y1 = pathCurveTo.CubicX1Y1; SvgPointF x2y2 = pathCurveTo.CubicX2Y2; gp.AddBezier(lastPoint.X, lastPoint.Y, x1y1.X, x1y1.Y, x2y2.X, x2y2.Y, xy.X, xy.Y); lastPoint = xy; break; case SvgPathType.ArcTo: //else if (DynamicCast.Cast(segment, out pathArc)) pathArc = (SvgPathSegArc)segment; ptXY = pathArc.AbsXY; if (lastPoint.Equals(ptXY)) { // If the endpoints (x, y) and (x0, y0) are identical, then this // is equivalent to omitting the elliptical arc segment entirely. } else if (pathArc.R1.Equals(0) || pathArc.R2.Equals(0)) { // Ensure radii are valid gp.AddLine(lastPoint.X, lastPoint.Y, ptXY.X, ptXY.Y); } else { CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues(); GraphicsPath subPath = new GraphicsPath(); subPath.StartFigure(); subPath.AddArc((float)(calcValues.Cx - calcValues.CorrRx), (float)(calcValues.Cy - calcValues.CorrRy), (float)calcValues.CorrRx * 2, (float)calcValues.CorrRy * 2, (float)calcValues.AngleStart, (float)calcValues.AngleExtent); Matrix matrix = new Matrix(); matrix.Translate(-(float)calcValues.Cx, -(float)calcValues.Cy); subPath.Transform(matrix); matrix = new Matrix(); matrix.Rotate((float)pathArc.Angle); subPath.Transform(matrix); matrix = new Matrix(); matrix.Translate((float)calcValues.Cx, (float)calcValues.Cy); subPath.Transform(matrix); gp.AddPath(subPath, true); } lastPoint = ptXY; break; case SvgPathType.Close: //else if (segment is SvgPathSegClosePath) gp.CloseFigure(); lastPoint = initPoint; break; } } string fillRule = element.GetPropertyValue("fill-rule"); if (fillRule == "evenodd") { gp.FillMode = FillMode.Alternate; } else { gp.FillMode = FillMode.Winding; } return(gp); }
public Geometry CreateGeometry(SvgPathElement element) { PathGeometry geometry = new PathGeometry(); var comparer = StringComparison.OrdinalIgnoreCase; string fillRule = element.GetPropertyValue("fill-rule"); string clipRule = element.GetAttribute("clip-rule"); if (!string.IsNullOrWhiteSpace(clipRule) && string.Equals(clipRule, "evenodd", comparer) || string.Equals(clipRule, CssConstants.ValNonzero, comparer)) { fillRule = clipRule; } if (string.Equals(fillRule, "evenodd", comparer)) { geometry.FillRule = FillRule.EvenOdd; } else if (string.Equals(fillRule, CssConstants.ValNonzero, comparer)) { geometry.FillRule = FillRule.Nonzero; } SvgPointF initPoint = new SvgPointF(0, 0); SvgPointF lastPoint = new SvgPointF(0, 0); SvgPointF ptXY = new SvgPointF(0, 0); SvgPathSeg segment = null; SvgPathSegMoveto pathMoveTo = null; SvgPathSegLineto pathLineTo = null; SvgPathSegCurveto pathCurveTo = null; SvgPathSegArc pathArc = null; SvgPathSegList segments = element.PathSegList; int numSegs = segments.NumberOfItems; if (numSegs == 0) { return(geometry); } PathFigure pathFigure = null; for (int i = 0; i < numSegs; i++) { segment = segments.GetItem(i); switch (segment.PathType) { case SvgPathType.MoveTo: //if (DynamicCast.Cast(segment, out pathMoveTo)) pathMoveTo = (SvgPathSegMoveto)segment; if (pathFigure != null) { pathFigure.IsClosed = false; pathFigure.IsFilled = true; geometry.Figures.Add(pathFigure); pathFigure = null; } lastPoint = initPoint = pathMoveTo.AbsXY; pathFigure = new PathFigure(); pathFigure.StartPoint = new Point(initPoint.ValueX, initPoint.ValueY); break; case SvgPathType.LineTo: //else if (DynamicCast.Cast(segment, out pathLineTo)) pathLineTo = (SvgPathSegLineto)segment; ptXY = pathLineTo.AbsXY; pathFigure.Segments.Add(new LineSegment(new Point(ptXY.ValueX, ptXY.ValueY), true)); lastPoint = ptXY; break; case SvgPathType.CurveTo: //else if (DynamicCast.Cast(segment, out pathCurveTo)) pathCurveTo = (SvgPathSegCurveto)segment; SvgPointF xy = pathCurveTo.AbsXY; SvgPointF x1y1 = pathCurveTo.CubicX1Y1; SvgPointF x2y2 = pathCurveTo.CubicX2Y2; pathFigure.Segments.Add(new BezierSegment(new Point(x1y1.ValueX, x1y1.ValueY), new Point(x2y2.ValueX, x2y2.ValueY), new Point(xy.ValueX, xy.ValueY), true)); lastPoint = xy; break; case SvgPathType.ArcTo: //else if (DynamicCast.Cast(segment, out pathArc)) pathArc = (SvgPathSegArc)segment; ptXY = pathArc.AbsXY; if (lastPoint.Equals(ptXY)) { // If the endpoints (x, y) and (x0, y0) are identical, then this // is equivalent to omitting the elliptical arc segment entirely. } else if (pathArc.R1.Equals(0) || pathArc.R2.Equals(0)) { // Ensure radii are valid pathFigure.Segments.Add(new LineSegment(new Point(ptXY.ValueX, ptXY.ValueY), true)); } else { CalculatedArcValues calcValues = pathArc.GetCalculatedArcValues(); pathFigure.Segments.Add(new ArcSegment(new Point(ptXY.ValueX, ptXY.ValueY), new Size(pathArc.R1, pathArc.R2), pathArc.Angle, pathArc.LargeArcFlag, pathArc.SweepFlag ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, true)); } lastPoint = ptXY; break; case SvgPathType.Close: //else if (segment is SvgPathSegClosePath) if (pathFigure != null) { pathFigure.IsClosed = true; pathFigure.IsFilled = true; geometry.Figures.Add(pathFigure); pathFigure = null; } lastPoint = initPoint; break; } } if (pathFigure != null) { pathFigure.IsClosed = false; pathFigure.IsFilled = true; geometry.Figures.Add(pathFigure); } return(geometry); }