private void DrawFileViewLasso( CanvasDrawingSession ds, float leftTop, float leftHeight, float rightTop, float rightHeight) { var pathBuilder = new CanvasPathBuilder(ds); float num1 = Math.Min(4.0f, leftHeight * 0.5f); // bezier curve control point float num2 = Math.Min(4.0f, rightHeight * 0.5f); // bezier curve control point float y1 = leftTop + leftHeight; float y2 = rightTop + rightHeight; pathBuilder.BeginFigure(new Vector2(32.0f, leftTop)); pathBuilder.AddLine(new Vector2(36.0f, rightTop)); pathBuilder.AddLine(new Vector2(56.0f, rightTop)); pathBuilder.AddQuadraticBezier(new Vector2(60.0f, rightTop), new Vector2(60.0f, rightTop + num2)); pathBuilder.AddLine(new Vector2(60.0f, y2 - num2)); pathBuilder.AddQuadraticBezier(new Vector2(60.0f, y2), new Vector2(56.0f, y2)); pathBuilder.AddLine(new Vector2(36.0f, y2)); pathBuilder.AddLine(new Vector2(32.0f, y1)); pathBuilder.AddLine(new Vector2(12.0f, y1)); pathBuilder.AddQuadraticBezier(new Vector2(8.0f, y1), new Vector2(8.0f, y1 - num1)); pathBuilder.AddLine(new Vector2(8.0f, leftTop + num1)); pathBuilder.AddQuadraticBezier(new Vector2(8.0f, leftTop), new Vector2(12.0f, leftTop)); pathBuilder.EndFigure(CanvasFigureLoop.Closed); var finalGeo = CanvasGeometry.CreatePath(pathBuilder); ds.DrawGeometry(finalGeo, _lassoColor); }
/// <summary> /// Adds the Path Element to the Path. /// </summary> /// <param name="pathBuilder">CanvasPathBuilder object</param> /// <param name="currentPoint">The last active location in the Path before adding /// the Path Element</param> /// <param name="lastElement">The previous PathElement in the Path.</param> /// <returns>The latest location in the Path after adding the Path Element</returns> public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement) { // Calculate coordinates var controlPoint = new Vector2(_x1, _y1); var point = new Vector2(_x, _y); if (IsRelative) { controlPoint += currentPoint; point += currentPoint; } // Save the absolute control point so that it can be used by the following // SmoothQuadraticBezierElement (if any) _absoluteControlPoint = controlPoint; // Execute command pathBuilder.AddQuadraticBezier(controlPoint, point); // Set Last Element lastElement = this; // Return current point return(point); }
/// <summary> /// Adds the Path Element to the Path. /// </summary> /// <param name="pathBuilder">CanvasPathBuilder object</param> /// <param name="currentPoint">The last active location in the Path before adding /// the Path Element</param> /// <param name="lastElement">The previous PathElement in the Path.</param> /// <param name="logger">For logging purpose. To log the set of CanvasPathBuilder /// commands, used for creating the CanvasGeometry, in string format.</param> /// <returns>The latest location in the Path after adding the Path Element</returns> public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement, StringBuilder logger) { // Calculate coordinates var controlPoint = new Vector2(_x1, _y1); var point = new Vector2(_x, _y); if (IsRelative) { controlPoint += currentPoint; point += currentPoint; } // Save the absolute control point so that it can be used by the following // SmoothQuadraticBezierElement (if any) _absoluteControlPoint = controlPoint; // Execute command pathBuilder.AddQuadraticBezier(controlPoint, point); // Log command logger?.Append($"{Indent}pathBuilder.AddQuadraticBezier(new Vector2({controlPoint.X}, {controlPoint.Y})"); logger?.AppendLine($", new Vector2({point.X}, {point.Y}));"); // Set Last Element lastElement = this; // Return current point return(point); }
public void QuadTo(float x1, float y1, float x, float y) { var controlPoint = new System.Numerics.Vector2(x1, y1); var endPoint = new System.Numerics.Vector2(x, y); _pathBuilder.AddQuadraticBezier(controlPoint, endPoint); }
public void VerifySendPathTo() { // // This calls each of the path functions, once, and verfies that it works. // Sink behavior is verified in more detail in the geometry unit tests. // CanvasDevice device = new CanvasDevice(); CanvasPathBuilder pathBuilder = new CanvasPathBuilder(device); pathBuilder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate); pathBuilder.BeginFigure(0, 0); pathBuilder.AddLine(0, 0); pathBuilder.AddQuadraticBezier(new Vector2(), new Vector2()); pathBuilder.AddCubicBezier(new Vector2(), new Vector2(), new Vector2()); // D2D tries to be smart about degenerate arcs and redundant set segment options, and may sometimes actually // surpress them. Therefore, these calls use non-defaults. pathBuilder.AddArc(new Vector2 { X = 100, Y = 100 }, 10, 10, 90, CanvasSweepDirection.Clockwise, CanvasArcSize.Small); pathBuilder.SetSegmentOptions(CanvasFigureSegmentOptions.ForceUnstroked); pathBuilder.EndFigure(CanvasFigureLoop.Closed); CanvasGeometry pathGeometry = CanvasGeometry.CreatePath(pathBuilder); MyGeometryStreamReader myStreamReader = new MyGeometryStreamReader(); pathGeometry.SendPathTo(myStreamReader); myStreamReader.Verify(); }
public void QuadTo(float controlX, float controlY, float endX, float endY) { CheckPathBuilder(); _builder.AddQuadraticBezier(new Vector2() { X = controlX, Y = controlY }, new Vector2() { X = endX, Y = endY }); }
/// <summary> /// Adds the Path Element to the Path. /// </summary> /// <param name="pathBuilder">CanvasPathBuilder object</param> /// <param name="currentPoint">The last active location in the Path before adding /// the Path Element</param> /// <param name="lastElement">The previous PathElement in the Path.</param> /// <param name="logger">For logging purpose. To log the set of CanvasPathBuilder /// commands, used for creating the CanvasGeometry, in string format.</param> /// <returns>The latest location in the Path after adding the Path Element</returns> public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement, StringBuilder logger) { // Calculate coordinates // Check if the last element was a Quadratic Bezier var quadBezier = lastElement as QuadraticBezierElement; if (quadBezier != null) { // Reflect the control point of the Quadratic Bezier over the current point. The // resulting point will be the control point of this Bezier. _absoluteControlPoint = Utils.Reflect(quadBezier.GetControlPoint(), currentPoint); } // Or if the last element was s Smooth Quadratic Bezier else { var smoothQuadBezier = lastElement as SmoothQuadraticBezierElement; // If the last element was a Smooth Quadratic Bezier then reflect its control point // over the current point. The resulting point will be the control point of this // Bezier. Otherwise, if the last element was not a Smooth Quadratic Bezier, // then the currentPoint will be the control point of this Bezier. _absoluteControlPoint = smoothQuadBezier != null ? Utils.Reflect(smoothQuadBezier.GetControlPoint(), currentPoint) : currentPoint; } var point = new Vector2(_x, _y); if (IsRelative) { point += currentPoint; } // Execute command pathBuilder.AddQuadraticBezier(_absoluteControlPoint, point); // Log command logger?.Append($"{Indent}pathBuilder.AddQuadraticBezier(new Vector2({_absoluteControlPoint.X},"); logger?.AppendLine($" {_absoluteControlPoint.Y}), new Vector2({point.X}, {point.Y}));"); // Set Last Element lastElement = this; // Return current point return(point); }
/// <summary> /// Adds the Path Element to the Path. /// </summary> /// <param name="pathBuilder">CanvasPathBuilder object</param> /// <param name="currentPoint">The last active location in the Path before adding /// the Path Element</param> /// <param name="lastElement">The previous PathElement in the Path.</param> /// <returns>The latest location in the Path after adding the Path Element</returns> public override Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement) { // Calculate coordinates // Check if the last element was a Quadratic Bezier if (lastElement is QuadraticBezierElement quadBezier) { // Reflect the control point of the Quadratic Bezier over the current point. The // resulting point will be the control point of this Bezier. _absoluteControlPoint = Utils.Reflect(quadBezier.GetControlPoint(), currentPoint); } // Or if the last element was s Smooth Quadratic Bezier else { // If the last element was a Smooth Quadratic Bezier then reflect its control point // over the current point. The resulting point will be the control point of this // Bezier. Otherwise, if the last element was not a Smooth Quadratic Bezier, // then the currentPoint will be the control point of this Bezier. _absoluteControlPoint = lastElement is SmoothQuadraticBezierElement smoothQuadBezier ? Utils.Reflect(smoothQuadBezier.GetControlPoint(), currentPoint) : currentPoint; } var point = new Vector2(_x, _y); if (IsRelative) { point += currentPoint; } // Execute command pathBuilder.AddQuadraticBezier(_absoluteControlPoint, point); // Set Last Element lastElement = this; // Return current point return(point); }
public void Draw(object ds, XQBezier qbezier, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r) { var _ds = ds as CanvasDrawingSession; double thickness = qbezier.Style.Thickness / _state.Zoom; var brush = ToColor(qbezier.Style.Fill); var pen = ToColor(qbezier.Style.Stroke); var ss = CreateStrokeStyle(qbezier.Style); CanvasGeometry g; using (var builder = new CanvasPathBuilder(_ds)) { builder.BeginFigure((float)qbezier.Point1.X, (float)qbezier.Point1.Y); builder.AddQuadraticBezier( new N.Vector2( (float)qbezier.Point2.X, (float)qbezier.Point2.Y), new N.Vector2( (float)qbezier.Point3.X, (float)qbezier.Point3.Y)); builder.EndFigure(CanvasFigureLoop.Open); g = CanvasGeometry.CreatePath(builder); } if (qbezier.IsFilled) { _ds.FillGeometry(g, brush); } if (qbezier.IsStroked) { _ds.DrawGeometry(g, pen, (float)thickness, ss); } g.Dispose(); ss.Dispose(); }
private static CanvasGeometry BuildGeometry(ICanvasResourceCreator resourceCreator, IReadOnlyList <Vector2> points) { using (var builder = new CanvasPathBuilder(resourceCreator.Device)) { builder.BeginFigure(points[0]); for (var i = 0; i < points.Count / 3; i++) { builder.AddQuadraticBezier(points[(i * 3) + 1], points[(i * 3) + 2]); var lastIndex = (i * 3) + 3; if (lastIndex < points.Count - 1) { builder.AddLine(points[lastIndex]); } } builder.EndFigure(CanvasFigureLoop.Closed); return(CanvasGeometry.CreatePath(builder)); } }
public static CanvasGeometry AsPathFromSegment(this PathF path, int segmentIndex, float zoom, ICanvasResourceCreator creator) { float scale = 1 / zoom; var builder = new CanvasPathBuilder(creator); var type = path.GetSegmentType(segmentIndex); if (type == PathOperation.Line) { int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex); var startPoint = path[segmentStartingPointIndex - 1]; builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default); var point = path[segmentStartingPointIndex]; builder.AddLine(point.X * scale, point.Y * scale); } else if (type == PathOperation.Quad) { int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex); var startPoint = path[segmentStartingPointIndex - 1]; builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default); var controlPoint = path[segmentStartingPointIndex++]; var endPoint = path[segmentStartingPointIndex]; builder.AddQuadraticBezier( new Vector2(controlPoint.X * scale, controlPoint.Y * scale), new Vector2(endPoint.X * scale, endPoint.Y * scale)); } else if (type == PathOperation.Cubic) { int segmentStartingPointIndex = path.GetSegmentPointIndex(segmentIndex); var startPoint = path[segmentStartingPointIndex - 1]; builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default); var controlPoint1 = path[segmentStartingPointIndex++]; var controlPoint2 = path[segmentStartingPointIndex++]; var endPoint = path[segmentStartingPointIndex]; builder.AddCubicBezier( new Vector2(controlPoint1.X * scale, controlPoint1.Y * scale), new Vector2(controlPoint2.X * scale, controlPoint2.Y * scale), new Vector2(endPoint.X * scale, endPoint.Y * scale)); } else if (type == PathOperation.Arc) { path.GetSegmentInfo(segmentIndex, out var pointIndex, out var arcAngleIndex, out var arcClockwiseIndex); var topLeft = path[pointIndex++]; var bottomRight = path[pointIndex]; var startAngle = path.GetArcAngle(arcAngleIndex++); var endAngle = path.GetArcAngle(arcAngleIndex); var clockwise = path.GetArcClockwise(arcClockwiseIndex); while (startAngle < 0) { startAngle += 360; } while (endAngle < 0) { endAngle += 360; } var rotation = Geometry.GetSweep(startAngle, endAngle, clockwise); var absRotation = Math.Abs(rotation); var rectX = topLeft.X * scale; var rectY = topLeft.Y * scale; var rectWidth = (bottomRight.X * scale) - rectX; var rectHeight = (bottomRight.Y * scale) - rectY; var startPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -startAngle); var endPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -endAngle); builder.BeginFigure(startPoint.X * scale, startPoint.Y * scale, CanvasFigureFill.Default); builder.AddArc( new Vector2(endPoint.X, endPoint.Y), rectWidth / 2, rectHeight / 2, 0, clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise, absRotation >= 180 ? CanvasArcSize.Large : CanvasArcSize.Small ); } builder.EndFigure(CanvasFigureLoop.Open); return(CanvasGeometry.CreatePath(builder)); }
private CanvasGeometry CreatePath(CanvasDrawingSession session, SvgPathElement element) { if (this.PathCache.ContainsKey(element)) { return(this.PathCache[element]); } var open = false; var v = new Vector2 { X = 0.0F, Y = 0.0F }; CanvasGeometry geometry; using (var builder = new CanvasPathBuilder(this.ResourceCreator)) { var fillRule = element.Style.FillRule; if (fillRule.HasValue && fillRule.Value.Value != SvgFillRuleType.EvenOdd) { builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); } foreach (var segment in element.Segments) { if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ClosePath) { builder.EndFigure(CanvasFigureLoop.Closed); open = false; continue; } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.MoveToAbsolute) { if (open) { builder.EndFigure(CanvasFigureLoop.Open); } var casted = (SvgPathSegmentMoveToAbsolute)segment; v.X = casted.X; v.Y = casted.Y; builder.BeginFigure(v); open = true; continue; } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.MoveToRelative) { if (open) { builder.EndFigure(CanvasFigureLoop.Open); } var casted = (SvgPathSegmentMoveToRelative)segment; v.X += casted.X; v.Y += casted.Y; builder.BeginFigure(v); open = true; continue; } if (!open) { builder.BeginFigure(v); open = true; } if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToAbsolute) { var casted = (SvgPathSegmentLineToAbsolute)segment; v.X = casted.X; v.Y = casted.Y; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToRelative) { var casted = (SvgPathSegmentLineToRelative)segment; v.X += casted.X; v.Y += casted.Y; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicAbsolute) { var casted = (SvgPathSegmentCurveToCubicAbsolute)segment; v.X = casted.X; v.Y = casted.Y; builder.AddCubicBezier(new Vector2 { X = casted.X1, Y = casted.Y1 }, new Vector2 { X = casted.X2, Y = casted.Y2 }, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicRelative) { var casted = (SvgPathSegmentCurveToCubicRelative)segment; var c1 = v; c1.X += casted.X1; c1.Y += casted.Y1; var c2 = v; c2.X += casted.X2; c2.Y += casted.Y2; v.X += casted.X; v.Y += casted.Y; builder.AddCubicBezier(c1, c2, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticAbsolute) { var casted = (SvgPathSegmentCurveToQuadraticAbsolute)segment; v.X = casted.X; v.Y = casted.Y; builder.AddQuadraticBezier(new Vector2 { X = casted.X1, Y = casted.Y1 }, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticRelative) { var casted = (SvgPathSegmentCurveToQuadraticRelative)segment; var c1 = v; c1.X += casted.X1; c1.Y += casted.Y1; v.X += casted.X; v.Y += casted.Y; builder.AddQuadraticBezier(c1, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ArcAbsolute) { var casted = (SvgPathSegmentArcAbsolute)segment; var size = casted.LargeArcFlag ? CanvasArcSize.Large : CanvasArcSize.Small; var sweepDirection = casted.SweepFlag ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise; builder.AddArc(new Vector2 { X = casted.X, Y = casted.Y }, casted.RadiusX, casted.RadiusY, 180.0F * casted.Angle / (float)Math.PI, sweepDirection, size); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.ArcRelative) { var casted = (SvgPathSegmentArcRelative)segment; v.X += casted.X; v.Y += casted.Y; var size = casted.LargeArcFlag ? CanvasArcSize.Large : CanvasArcSize.Small; var sweepDirection = casted.SweepFlag ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise; builder.AddArc(v, casted.RadiusX, casted.RadiusY, 180.0F * casted.Angle / (float)Math.PI, sweepDirection, size); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToHorizontalAbsolute) { var casted = (SvgPathSegmentLineToHorizontalAbsolute)segment; v.X = casted.X; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToHorizontalRelative) { var casted = (SvgPathSegmentLineToHorizontalRelative)segment; v.X += casted.X; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToVerticalAbsolute) { var casted = (SvgPathSegmentLineToVerticalAbsolute)segment; v.Y = casted.Y; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.LineToVerticalRelative) { var casted = (SvgPathSegmentLineToVerticalRelative)segment; v.Y += casted.Y; builder.AddLine(v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicSmoothAbsolute) { var casted = (SvgPathSegmentCurveToCubicSmoothAbsolute)segment; var c1 = v; v.X = casted.X; v.Y = casted.Y; builder.AddCubicBezier(c1, new Vector2 { X = casted.X2, Y = casted.Y2 }, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToCubicSmoothRelative) { var casted = (SvgPathSegmentCurveToCubicSmoothRelative)segment; var c1 = v; var c2 = v; c2.X += casted.X2; c2.Y += casted.Y2; v.X += casted.X; v.Y += casted.Y; builder.AddCubicBezier(c1, c2, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticSmoothAbsolute) { var casted = (SvgPathSegmentCurveToQuadraticSmoothAbsolute)segment; var c1 = v; v.X = casted.X; v.Y = casted.Y; builder.AddQuadraticBezier(c1, v); } else if (segment.PathSegmentType == SvgPathSegment.SvgPathSegmentType.CurveToQuadraticSmoothRelative) { var casted = (SvgPathSegmentCurveToQuadraticSmoothRelative)segment; var c1 = v; v.X += casted.X; v.Y += casted.Y; builder.AddQuadraticBezier(c1, v); } } if (open) { builder.EndFigure(CanvasFigureLoop.Open); } geometry = CanvasGeometry.CreatePath(builder); } this.DisposableObjects.Add(geometry); this.PathCache.Add(element, geometry); return(geometry); }
/// <summary> /// Adds a line in the form of a cubic bezier. The control point of the quadratic bezier will be the endpoint of the line itself. /// </summary> /// <param name="pathBuilder"><see cref="CanvasPathBuilder"/></param> /// <param name="end">Ending location of the line segment.</param> public static void AddLineAsQuadraticBezier(this CanvasPathBuilder pathBuilder, Vector2 end) { pathBuilder.AddQuadraticBezier(end, end); }
public void AddQuadCurveToPoint(Vector2 endPoint, Vector2 controlPoint) { mBuilder.AddQuadraticBezier(controlPoint, endPoint); }
/*public override object Clone() { SVGPath clone = new SVGPath(); clone._gp = (GraphicsPath)_gp.Clone(); clone._ID = _ID; clone._strPath = (String)_strPath.Clone(); return clone; }*/ private void parsePath(CanvasPathBuilder pb, String path) { char[] delimiter = { ' ' }; string[] commands = Regex.Split(path, _regex1); string[] values = null; float[] points = new float[7]; Vector2[] Vector2s = new Vector2[4]; Vector2 lastPoint = new Vector2(0, 0); Vector2 lastControlPoint = new Vector2(0, 0); //Vector2 firstPoint = new Vector2(0, 0); //Vector2 firstPoint = new Vector2(0, 0); try { for (int i = 0; i < commands.Length; i++) { String strCommand = commands[i]; char action = (strCommand != null && strCommand.Length > 0) ? strCommand[0] : ' '; values = strCommand.Split(delimiter); if (action == 'M') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); lastPoint = new Vector2(points[0], points[1]); //firstPoint = new Vector2(points[0], points[1]); pb.BeginFigure(lastPoint); } else if (action == 'm') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; pb.BeginFigure(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; pb.BeginFigure(lastPoint); } else if (action == 'L')//capital letter is absolute location { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); pb.AddLine(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; } else if (action == 'l')//lowercase letter is relative location { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; pb.AddLine(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; } else if (action == 'H') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); pb.AddLine(points[0], lastPoint.Y); lastPoint.X = points[0]; } else if (action == 'h') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; pb.AddLine(points[0], lastPoint.Y); lastPoint.X = points[0]; } else if (action == 'V') { points[0] = -(float)Convert.ToDouble(values[0].Substring(1)); pb.AddLine(lastPoint.X, points[0]); lastPoint.Y = points[0]; } else if (action == 'v') { points[0] = -(float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.Y; pb.AddLine(lastPoint.X, points[0]); lastPoint.Y = points[0]; } else if (action == 'C')//cubic bezier, 2 control points { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); points[4] = (float)Convert.ToDouble(values[4]); points[5] = -(float)Convert.ToDouble(values[5]); Vector2s[0] = lastPoint; Vector2s[1] = new Vector2(points[0], points[1]); Vector2s[2] = new Vector2(points[2], points[3]); Vector2s[3] = new Vector2(points[4], points[5]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'c') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; points[4] = (float)Convert.ToDouble(values[4]) + lastPoint.X; points[5] = -(float)Convert.ToDouble(values[5]) + lastPoint.Y; Vector2s[0] = lastPoint; Vector2s[1] = new Vector2(points[0], points[1]); Vector2s[2] = new Vector2(points[2], points[3]); Vector2s[3] = new Vector2(points[4], points[5]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'S') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); Vector2s[0] = lastPoint; Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint); Vector2s[2] = new Vector2(points[0], points[1]); Vector2s[3] = new Vector2(points[2], points[3]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 's') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; Vector2s[0] = lastPoint; Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint); Vector2s[2] = new Vector2(points[0], points[1]); Vector2s[3] = new Vector2(points[2], points[3]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'Q')//quadratic bezier, 1 control point { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); //convert quadratic to cubic bezier Vector2 QP0 = lastPoint; Vector2 QP1 = new Vector2(points[0], points[1]); Vector2 QP2 = new Vector2(points[2], points[3]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //old //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //new Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'q') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; //convert quadratic to cubic bezier Vector2 QP0 = lastPoint; Vector2 QP1 = new Vector2(points[0], points[1]); Vector2 QP2 = new Vector2(points[2], points[3]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //old //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //new //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'T') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); //convert quadratic to bezier Vector2 QP0 = lastPoint; Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0); Vector2 QP2 = new Vector2(points[0], points[1]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 't') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; //convert quadratic to bezier Vector2 QP0 = lastPoint; Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0); Vector2 QP2 = new Vector2(points[0], points[1]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'A') { points[0] = (float)Convert.ToDouble(values[0].Substring(1));//radiusX points[1] = (float)Convert.ToDouble(values[1]);//radiusY points[2] = (float)Convert.ToDouble(values[2]);//angle points[3] = (float)Convert.ToDouble(values[3]);//size points[4] = (float)Convert.ToDouble(values[4]);//sweep points[5] = (float)Convert.ToDouble(values[5]);//endX points[6] = -(float)Convert.ToDouble(values[6]);//endY //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large; //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive; Vector2 endPoint = new Vector2(points[5], points[6]); //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint); //arc.AddToPath(_gp); CanvasArcSize arcSize = CanvasArcSize.Large;//if size = 1, size is large. 0 for small CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise;//if sweep == 1, sweep is clockwise or positive if(points[3]==0.0f) arcSize = CanvasArcSize.Small; if (points[4] == 0.0f) sweep = CanvasSweepDirection.CounterClockwise; pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize); //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint); lastPoint.X = points[5]; lastPoint.Y = points[6]; } else if (action == 'a') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = (float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = (float)Convert.ToDouble(values[3]); points[4] = (float)Convert.ToDouble(values[4]); points[5] = (float)Convert.ToDouble(values[5] + lastPoint.X); points[6] = -(float)Convert.ToDouble(values[6] + lastPoint.Y); //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large; //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive; Vector2 endPoint = new Vector2(points[5], points[6]); //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint); //arc.AddToPath(_gp); CanvasArcSize arcSize = CanvasArcSize.Large;//if size = 1, size is large. 0 for small CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise;//if sweep == 1, sweep is clockwise or positive if (points[3] == 0.0f) arcSize = CanvasArcSize.Small; if (points[4] == 0.0f) sweep = CanvasSweepDirection.CounterClockwise; pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize); //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint); lastPoint.X = points[5]; lastPoint.Y = points[6]; } else if (action == 'Z' || action == 'z') { pb.EndFigure(CanvasFigureLoop.Closed); } } _cg = CanvasGeometry.CreatePath(pb); } catch (Exception exc) { Debug.WriteLine(exc.Message); Debug.WriteLine(exc.StackTrace); ErrorLogger.LogException("SVGPath", "parsePath", exc); } }
public static CanvasGeometry AsPath(this PathF path, float ox, float oy, float fx, float fy, ICanvasResourceCreator creator, CanvasFilledRegionDetermination fillMode = CanvasFilledRegionDetermination.Winding) { var builder = new CanvasPathBuilder(creator); #if DEBUG try { #endif builder.SetFilledRegionDetermination(fillMode); var pointIndex = 0; var arcAngleIndex = 0; var arcClockwiseIndex = 0; var figureOpen = false; var segmentIndex = -1; var lastOperation = PathOperation.Move; foreach (var type in path.SegmentTypes) { segmentIndex++; if (type == PathOperation.Move) { if (lastOperation != PathOperation.Close && lastOperation != PathOperation.Move) { builder.EndFigure(CanvasFigureLoop.Open); } var point = path[pointIndex++]; var begin = CanvasFigureFill.Default; builder.BeginFigure(ox + point.X * fx, oy + point.Y * fy, begin); figureOpen = true; } else if (type == PathOperation.Line) { var point = path[pointIndex++]; builder.AddLine(ox + point.X * fx, oy + point.Y * fy); } else if (type == PathOperation.Quad) { var controlPoint = path[pointIndex++]; var endPoint = path[pointIndex++]; builder.AddQuadraticBezier( new Vector2(ox + controlPoint.X * fx, oy + controlPoint.Y * fy), new Vector2(ox + endPoint.X * fx, oy + endPoint.Y * fy)); } else if (type == PathOperation.Cubic) { var controlPoint1 = path[pointIndex++]; var controlPoint2 = path[pointIndex++]; var endPoint = path[pointIndex++]; builder.AddCubicBezier( new Vector2(ox + controlPoint1.X * fx, oy + controlPoint1.Y * fy), new Vector2(ox + controlPoint2.X * fx, oy + controlPoint2.Y * fy), new Vector2(ox + endPoint.X * fx, oy + endPoint.Y * fy)); } else if (type == PathOperation.Arc) { var topLeft = path[pointIndex++]; var bottomRight = path[pointIndex++]; var startAngle = path.GetArcAngle(arcAngleIndex++); var endAngle = path.GetArcAngle(arcAngleIndex++); var clockwise = path.GetArcClockwise(arcClockwiseIndex++); while (startAngle < 0) { startAngle += 360; } while (endAngle < 0) { endAngle += 360; } var rotation = Geometry.GetSweep(startAngle, endAngle, clockwise); var absRotation = Math.Abs(rotation); var rectX = ox + topLeft.X * fx; var rectY = oy + topLeft.Y * fy; var rectWidth = (ox + bottomRight.X * fx) - rectX; var rectHeight = (oy + bottomRight.Y * fy) - rectY; var startPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -startAngle); var endPoint = Geometry.EllipseAngleToPoint(rectX, rectY, rectWidth, rectHeight, -endAngle); if (!figureOpen) { var begin = CanvasFigureFill.Default; builder.BeginFigure(startPoint.X, startPoint.Y, begin); figureOpen = true; } else { builder.AddLine(startPoint.X, startPoint.Y); } builder.AddArc( new Vector2(endPoint.X, endPoint.Y), rectWidth / 2, rectHeight / 2, 0, clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise, absRotation >= 180 ? CanvasArcSize.Large : CanvasArcSize.Small ); } else if (type == PathOperation.Close) { builder.EndFigure(CanvasFigureLoop.Closed); } lastOperation = type; } if (segmentIndex >= 0 && lastOperation != PathOperation.Close) { builder.EndFigure(CanvasFigureLoop.Open); } var geometry = CanvasGeometry.CreatePath(builder); return(geometry); #if DEBUG } catch (Exception exc) { builder.Dispose(); var definition = path.ToDefinitionString(); Logger.Debug(string.Format("Unable to convert the path to a Win2D Path: {0}", definition), exc); return(null); } #endif }
/*public override object Clone() * { * SVGPath clone = new SVGPath(); * clone._gp = (GraphicsPath)_gp.Clone(); * clone._ID = _ID; * clone._strPath = (String)_strPath.Clone(); * return clone; * }*/ private void parsePath(CanvasPathBuilder pb, String path) { char[] delimiter = { ' ' }; string[] commands = Regex.Split(path, _regex1); string[] values = null; float[] points = new float[7]; Vector2[] Vector2s = new Vector2[4]; Vector2 lastPoint = new Vector2(0, 0); Vector2 lastControlPoint = new Vector2(0, 0); //Vector2 firstPoint = new Vector2(0, 0); //Vector2 firstPoint = new Vector2(0, 0); try { for (int i = 0; i < commands.Length; i++) { String strCommand = commands[i]; char action = (strCommand != null && strCommand.Length > 0) ? strCommand[0] : ' '; values = strCommand.Split(delimiter); if (action == 'M') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); lastPoint = new Vector2(points[0], points[1]); //firstPoint = new Vector2(points[0], points[1]); pb.BeginFigure(lastPoint); } else if (action == 'm') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; pb.BeginFigure(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; pb.BeginFigure(lastPoint); } else if (action == 'L')//capital letter is absolute location { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); pb.AddLine(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; } else if (action == 'l')//lowercase letter is relative location { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; pb.AddLine(points[0], points[1]); lastPoint.X = points[0]; lastPoint.Y = points[1]; } else if (action == 'H') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); pb.AddLine(points[0], lastPoint.Y); lastPoint.X = points[0]; } else if (action == 'h') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; pb.AddLine(points[0], lastPoint.Y); lastPoint.X = points[0]; } else if (action == 'V') { points[0] = -(float)Convert.ToDouble(values[0].Substring(1)); pb.AddLine(lastPoint.X, points[0]); lastPoint.Y = points[0]; } else if (action == 'v') { points[0] = -(float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.Y; pb.AddLine(lastPoint.X, points[0]); lastPoint.Y = points[0]; } else if (action == 'C')//cubic bezier, 2 control points { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); points[4] = (float)Convert.ToDouble(values[4]); points[5] = -(float)Convert.ToDouble(values[5]); Vector2s[0] = lastPoint; Vector2s[1] = new Vector2(points[0], points[1]); Vector2s[2] = new Vector2(points[2], points[3]); Vector2s[3] = new Vector2(points[4], points[5]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'c') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; points[4] = (float)Convert.ToDouble(values[4]) + lastPoint.X; points[5] = -(float)Convert.ToDouble(values[5]) + lastPoint.Y; Vector2s[0] = lastPoint; Vector2s[1] = new Vector2(points[0], points[1]); Vector2s[2] = new Vector2(points[2], points[3]); Vector2s[3] = new Vector2(points[4], points[5]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'S') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); Vector2s[0] = lastPoint; Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint); Vector2s[2] = new Vector2(points[0], points[1]); Vector2s[3] = new Vector2(points[2], points[3]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 's') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; Vector2s[0] = lastPoint; Vector2s[1] = mirrorControlPoint(lastControlPoint, lastPoint); Vector2s[2] = new Vector2(points[0], points[1]); Vector2s[3] = new Vector2(points[2], points[3]); //_gp.AddBezier(Vector2s[0], Vector2s[1], Vector2s[2], Vector2s[3]); pb.AddCubicBezier(Vector2s[1], Vector2s[2], Vector2s[3]); lastPoint = Vector2s[3]; lastControlPoint = Vector2s[2]; } else if (action == 'Q')//quadratic bezier, 1 control point { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = -(float)Convert.ToDouble(values[3]); //convert quadratic to cubic bezier Vector2 QP0 = lastPoint; Vector2 QP1 = new Vector2(points[0], points[1]); Vector2 QP2 = new Vector2(points[2], points[3]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //old //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //new Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'q') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; points[2] = (float)Convert.ToDouble(values[2]) + lastPoint.X; points[3] = -(float)Convert.ToDouble(values[3]) + lastPoint.Y; //convert quadratic to cubic bezier Vector2 QP0 = lastPoint; Vector2 QP1 = new Vector2(points[0], points[1]); Vector2 QP2 = new Vector2(points[2], points[3]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //old //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //new //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'T') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = -(float)Convert.ToDouble(values[1]); //convert quadratic to bezier Vector2 QP0 = lastPoint; Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0); Vector2 QP2 = new Vector2(points[0], points[1]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 't') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)) + lastPoint.X; points[1] = -(float)Convert.ToDouble(values[1]) + lastPoint.Y; //convert quadratic to bezier Vector2 QP0 = lastPoint; Vector2 QP1 = mirrorControlPoint(lastControlPoint, QP0); Vector2 QP2 = new Vector2(points[0], points[1]); Vector2 CP0 = QP0; Vector2 CP3 = QP2; //Vector2 CP1 = new Vector2((QP0.X + 2.0f * QP1.X) / 3.0f, (QP0.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP2 = new Vector2((QP2.X + 2.0f * QP1.X) / 3.0f, (QP2.Y + 2.0f * QP1.Y) / 3.0f); //Vector2 CP1 = new Vector2(QP0.X + 2.0f / 3.0f * (QP1.X - QP0.X), QP0.Y + 2.0f / 3.0f * (QP1.Y - QP0.Y)); //Vector2 CP2 = new Vector2(QP2.X + 2.0f / 3.0f * (QP1.X - QP2.X), QP2.Y + 2.0f / 3.0f * (QP1.Y - QP2.Y)); //_gp.AddBezier(CP0, CP1, CP2, CP3); //pb.AddCubicBezier(CP1, CP2, QP2); pb.AddQuadraticBezier(QP1, QP2); lastPoint = QP2; lastControlPoint = QP1; } else if (action == 'A') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); //radiusX points[1] = (float)Convert.ToDouble(values[1]); //radiusY points[2] = (float)Convert.ToDouble(values[2]); //angle points[3] = (float)Convert.ToDouble(values[3]); //size points[4] = (float)Convert.ToDouble(values[4]); //sweep points[5] = (float)Convert.ToDouble(values[5]); //endX points[6] = -(float)Convert.ToDouble(values[6]); //endY //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large; //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive; Vector2 endPoint = new Vector2(points[5], points[6]); //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint); //arc.AddToPath(_gp); CanvasArcSize arcSize = CanvasArcSize.Large; //if size = 1, size is large. 0 for small CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise; //if sweep == 1, sweep is clockwise or positive if (points[3] == 0.0f) { arcSize = CanvasArcSize.Small; } if (points[4] == 0.0f) { sweep = CanvasSweepDirection.CounterClockwise; } pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize); //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint); lastPoint.X = points[5]; lastPoint.Y = points[6]; } else if (action == 'a') { points[0] = (float)Convert.ToDouble(values[0].Substring(1)); points[1] = (float)Convert.ToDouble(values[1]); points[2] = (float)Convert.ToDouble(values[2]); points[3] = (float)Convert.ToDouble(values[3]); points[4] = (float)Convert.ToDouble(values[4]); points[5] = (float)Convert.ToDouble(values[5] + lastPoint.X); points[6] = -(float)Convert.ToDouble(values[6] + lastPoint.Y); //SvgArcSize sas = points[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large; //SvgArcSweep sasw = points[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive; Vector2 endPoint = new Vector2(points[5], points[6]); //SvgArcSegment arc = new SvgArcSegment(lastPoint, points[0], points[1], points[2], sas, sasw, endPoint); //arc.AddToPath(_gp); CanvasArcSize arcSize = CanvasArcSize.Large; //if size = 1, size is large. 0 for small CanvasSweepDirection sweep = CanvasSweepDirection.Clockwise; //if sweep == 1, sweep is clockwise or positive if (points[3] == 0.0f) { arcSize = CanvasArcSize.Small; } if (points[4] == 0.0f) { sweep = CanvasSweepDirection.CounterClockwise; } pb.AddArc(new Vector2(points[5], points[6]), points[0], points[1], points[2], sweep, arcSize); //AddArcToPath(_gp, lastPoint, points[0], points[1], points[2], (int)points[3], (int)points[4], endPoint); lastPoint.X = points[5]; lastPoint.Y = points[6]; } else if (action == 'Z' || action == 'z') { pb.EndFigure(CanvasFigureLoop.Closed); } } _cg = CanvasGeometry.CreatePath(pb); } catch (Exception exc) { Debug.WriteLine(exc.Message); Debug.WriteLine(exc.StackTrace); ErrorLogger.LogException("SVGPath", "parsePath", exc); } }
public static CanvasGeometry ToCanvasGeometry(this XPathGeometry pg, CanvasDrawingSession ds) { CanvasGeometry g; using (var builder = new CanvasPathBuilder(ds)) { if (pg.FillRule == XFillRule.EvenOdd) builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate); else builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); foreach (var pf in pg.Figures) { builder.BeginFigure( (float)pf.StartPoint.X, (float)pf.StartPoint.Y, pf.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills); foreach (var segment in pf.Segments) { var options = CanvasFigureSegmentOptions.None; if (!segment.IsStroked) options |= CanvasFigureSegmentOptions.ForceUnstroked; if (segment.IsSmoothJoin) options |= CanvasFigureSegmentOptions.ForceRoundLineJoin; builder.SetSegmentOptions(options); if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; builder.AddArc( new N.Vector2( (float)arcSegment.Point.X, (float)arcSegment.Point.Y), (float)(arcSegment.Size.Width / 2.0), (float)(arcSegment.Size.Height / 2.0), (float)arcSegment.RotationAngle, arcSegment.SweepDirection == XSweepDirection.Clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise, arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small); } else if (segment is XBezierSegment) { var bezierSegment = segment as XBezierSegment; builder.AddCubicBezier( new N.Vector2( (float)bezierSegment.Point1.X, (float)bezierSegment.Point1.Y), new N.Vector2( (float)bezierSegment.Point2.X, (float)bezierSegment.Point2.Y), new N.Vector2( (float)bezierSegment.Point3.X, (float)bezierSegment.Point3.Y)); } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; builder.AddLine( new N.Vector2( (float)lineSegment.Point.X, (float)lineSegment.Point.Y)); } else if (segment is XPolyBezierSegment) { var polyBezierSegment = segment as XPolyBezierSegment; if (polyBezierSegment.Points.Count >= 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[0].X, (float)polyBezierSegment.Points[0].Y), new N.Vector2( (float)polyBezierSegment.Points[1].X, (float)polyBezierSegment.Points[1].Y), new N.Vector2( (float)polyBezierSegment.Points[2].X, (float)polyBezierSegment.Points[2].Y)); } if (polyBezierSegment.Points.Count > 3 && polyBezierSegment.Points.Count % 3 == 0) { for (int i = 3; i < polyBezierSegment.Points.Count; i += 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[i].X, (float)polyBezierSegment.Points[i].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 1].X, (float)polyBezierSegment.Points[i + 1].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 2].X, (float)polyBezierSegment.Points[i + 2].Y)); } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Count >= 1) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[0].X, (float)polyLineSegment.Points[0].Y)); } if (polyLineSegment.Points.Count > 1) { for (int i = 1; i < polyLineSegment.Points.Count; i++) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[i].X, (float)polyLineSegment.Points[i].Y)); } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Count >= 2) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[0].X, (float)polyQuadraticSegment.Points[0].Y), new N.Vector2( (float)polyQuadraticSegment.Points[1].X, (float)polyQuadraticSegment.Points[1].Y)); } if (polyQuadraticSegment.Points.Count > 2 && polyQuadraticSegment.Points.Count % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[i].X, (float)polyQuadraticSegment.Points[i].Y), new N.Vector2( (float)polyQuadraticSegment.Points[i + 1].X, (float)polyQuadraticSegment.Points[i + 1].Y)); } } } else if (segment is XQuadraticBezierSegment) { var qbezierSegment = segment as XQuadraticBezierSegment; builder.AddQuadraticBezier( new N.Vector2( (float)qbezierSegment.Point1.X, (float)qbezierSegment.Point1.Y), new N.Vector2( (float)qbezierSegment.Point2.X, (float)qbezierSegment.Point2.Y)); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } builder.EndFigure(pf.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open); } g = CanvasGeometry.CreatePath(builder); } return g; }
public void Draw(object ds, XQBezier qbezier, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _ds = ds as CanvasDrawingSession; double thickness = qbezier.Style.Thickness / _state.Zoom; var brush = ToColor(qbezier.Style.Fill); var pen = ToColor(qbezier.Style.Stroke); var ss = CreateStrokeStyle(qbezier.Style); CanvasGeometry g; using (var builder = new CanvasPathBuilder(_ds)) { builder.BeginFigure((float)qbezier.Point1.X, (float)qbezier.Point1.Y); builder.AddQuadraticBezier( new N.Vector2( (float)qbezier.Point2.X, (float)qbezier.Point2.Y), new N.Vector2( (float)qbezier.Point3.X, (float)qbezier.Point3.Y)); builder.EndFigure(CanvasFigureLoop.Open); g = CanvasGeometry.CreatePath(builder); } if (qbezier.IsFilled) { _ds.FillGeometry(g, brush); } if (qbezier.IsStroked) { _ds.DrawGeometry(g, pen, (float)thickness, ss); } g.Dispose(); ss.Dispose(); }
public static CanvasGeometry ToCanvasGeometry(this XPathGeometry pg, CanvasDrawingSession ds) { CanvasGeometry g; using (var builder = new CanvasPathBuilder(ds)) { if (pg.FillRule == XFillRule.EvenOdd) { builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate); } else { builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); } foreach (var pf in pg.Figures) { builder.BeginFigure( (float)pf.StartPoint.X, (float)pf.StartPoint.Y, pf.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills); foreach (var segment in pf.Segments) { var options = CanvasFigureSegmentOptions.None; if (!segment.IsStroked) { options |= CanvasFigureSegmentOptions.ForceUnstroked; } if (segment.IsSmoothJoin) { options |= CanvasFigureSegmentOptions.ForceRoundLineJoin; } builder.SetSegmentOptions(options); if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; builder.AddArc( new N.Vector2( (float)arcSegment.Point.X, (float)arcSegment.Point.Y), (float)(arcSegment.Size.Width / 2.0), (float)(arcSegment.Size.Height / 2.0), (float)arcSegment.RotationAngle, arcSegment.SweepDirection == XSweepDirection.Clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise, arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small); } else if (segment is XBezierSegment) { var bezierSegment = segment as XBezierSegment; builder.AddCubicBezier( new N.Vector2( (float)bezierSegment.Point1.X, (float)bezierSegment.Point1.Y), new N.Vector2( (float)bezierSegment.Point2.X, (float)bezierSegment.Point2.Y), new N.Vector2( (float)bezierSegment.Point3.X, (float)bezierSegment.Point3.Y)); } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; builder.AddLine( new N.Vector2( (float)lineSegment.Point.X, (float)lineSegment.Point.Y)); } else if (segment is XPolyBezierSegment) { var polyBezierSegment = segment as XPolyBezierSegment; if (polyBezierSegment.Points.Count >= 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[0].X, (float)polyBezierSegment.Points[0].Y), new N.Vector2( (float)polyBezierSegment.Points[1].X, (float)polyBezierSegment.Points[1].Y), new N.Vector2( (float)polyBezierSegment.Points[2].X, (float)polyBezierSegment.Points[2].Y)); } if (polyBezierSegment.Points.Count > 3 && polyBezierSegment.Points.Count % 3 == 0) { for (int i = 3; i < polyBezierSegment.Points.Count; i += 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[i].X, (float)polyBezierSegment.Points[i].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 1].X, (float)polyBezierSegment.Points[i + 1].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 2].X, (float)polyBezierSegment.Points[i + 2].Y)); } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Count >= 1) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[0].X, (float)polyLineSegment.Points[0].Y)); } if (polyLineSegment.Points.Count > 1) { for (int i = 1; i < polyLineSegment.Points.Count; i++) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[i].X, (float)polyLineSegment.Points[i].Y)); } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Count >= 2) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[0].X, (float)polyQuadraticSegment.Points[0].Y), new N.Vector2( (float)polyQuadraticSegment.Points[1].X, (float)polyQuadraticSegment.Points[1].Y)); } if (polyQuadraticSegment.Points.Count > 2 && polyQuadraticSegment.Points.Count % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[i].X, (float)polyQuadraticSegment.Points[i].Y), new N.Vector2( (float)polyQuadraticSegment.Points[i + 1].X, (float)polyQuadraticSegment.Points[i + 1].Y)); } } } else if (segment is XQuadraticBezierSegment) { var qbezierSegment = segment as XQuadraticBezierSegment; builder.AddQuadraticBezier( new N.Vector2( (float)qbezierSegment.Point1.X, (float)qbezierSegment.Point1.Y), new N.Vector2( (float)qbezierSegment.Point2.X, (float)qbezierSegment.Point2.Y)); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } builder.EndFigure(pf.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open); } g = CanvasGeometry.CreatePath(builder); } return(g); }
CanvasGeometry BuildGeometry(ICanvasResourceCreator resourceCreator, Geometry geometry) { CanvasGeometry canvasGeometry = null; // Determine what type of geometry we're dealing with. if (geometry is RectangleGeometry) { Rect xamRect = (geometry as RectangleGeometry).Rect; winFound.Rect winRect = new winFound.Rect(xamRect.X, xamRect.Y, xamRect.Width, xamRect.Height); canvasGeometry = CanvasGeometry.CreateRectangle(resourceCreator, winRect); } else if (geometry is EllipseGeometry) { EllipseGeometry ellipseGeometry = geometry as EllipseGeometry; Vector2 center = ConvertPoint(ellipseGeometry.Center); canvasGeometry = CanvasGeometry.CreateEllipse(resourceCreator, center, (float)ellipseGeometry.RadiusX, (float)ellipseGeometry.RadiusY); } else if (geometry is GeometryGroup) { GeometryGroup geometryGroup = geometry as GeometryGroup; List <CanvasGeometry> geometries = new List <CanvasGeometry>(); foreach (Geometry geometryChild in geometryGroup.Children) { geometries.Add(BuildGeometry(resourceCreator, geometryChild)); } canvasGeometry = CanvasGeometry.CreateGroup(resourceCreator, geometries.ToArray(), (CanvasFilledRegionDetermination)(int)geometryGroup.FillRule); } else { using (CanvasPathBuilder pathBuilder = new CanvasPathBuilder(resourceCreator)) { // Determine what type of geometry we're dealing with. if (geometry is LineGeometry) { LineGeometry lineGeometry = geometry as LineGeometry; pathBuilder.BeginFigure(ConvertPoint(lineGeometry.StartPoint), CanvasFigureFill.Default); pathBuilder.AddLine(ConvertPoint(lineGeometry.EndPoint)); pathBuilder.EndFigure(CanvasFigureLoop.Open); } else if (geometry is PathGeometry) { PathGeometry pathGeometry = geometry as PathGeometry; pathBuilder.SetFilledRegionDetermination((CanvasFilledRegionDetermination)(int)pathGeometry.FillRule); foreach (PathFigure pathFigure in pathGeometry.Figures) { // TODO: Check this logic! pathBuilder.BeginFigure(ConvertPoint(pathFigure.StartPoint), pathFigure.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills); foreach (PathSegment pathSegment in pathFigure.Segments) { // LineSegment if (pathSegment is LineSegment) { pathBuilder.AddLine(ConvertPoint((pathSegment as LineSegment).Point)); } // PolylineSegment else if (pathSegment is PolyLineSegment) { foreach (Point point in (pathSegment as PolyLineSegment).Points) { pathBuilder.AddLine(ConvertPoint(point)); } } // BezierSegment else if (pathSegment is BezierSegment) { BezierSegment bezierSegment = pathSegment as BezierSegment; pathBuilder.AddCubicBezier(ConvertPoint(bezierSegment.Point1), ConvertPoint(bezierSegment.Point2), ConvertPoint(bezierSegment.Point3)); } // PolyBezierSegment else if (pathSegment is PolyBezierSegment) { PointCollection points = (pathSegment as PolyBezierSegment).Points; for (int i = 0; i < points.Count; i += 3) { pathBuilder.AddCubicBezier(ConvertPoint(points[i + 0]), ConvertPoint(points[i + 1]), ConvertPoint(points[i + 2])); } } // QuadraticBezierSegment else if (pathSegment is QuadraticBezierSegment) { QuadraticBezierSegment quadSegment = pathSegment as QuadraticBezierSegment; pathBuilder.AddQuadraticBezier(ConvertPoint(quadSegment.Point1), ConvertPoint(quadSegment.Point2)); } // PolyQuadraticBezierSegment else if (pathSegment is PolyQuadraticBezierSegment) { PointCollection points = (pathSegment as PolyQuadraticBezierSegment).Points; for (int i = 0; i < points.Count; i += 2) { pathBuilder.AddQuadraticBezier(ConvertPoint(points[i + 0]), ConvertPoint(points[i + 1])); } } // ArcSegment else if (pathSegment is ArcSegment) { ArcSegment arcSegment = pathSegment as ArcSegment; pathBuilder.AddArc(ConvertPoint(arcSegment.Point), (float)arcSegment.Size.Width, (float)arcSegment.Size.Height, (float)arcSegment.RotationAngle, (CanvasSweepDirection)(int)arcSegment.SweepDirection, arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small); } } pathBuilder.EndFigure(pathFigure.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open); } } else { return(null); } canvasGeometry = CanvasGeometry.CreatePath(pathBuilder); } } // Set transform if (geometry.Transform != null) { canvasGeometry = canvasGeometry.Transform((Matrix3x2)geometry.Transform.GetNativeObject()); } return(canvasGeometry); }