I wrote class for converting SVG path description to CorelDraw Curve
Maybe it can be useful for someone
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Corel.Interop.VGCore; using corel = Corel.Interop.VGCore; using System.Text.RegularExpressions; namespace CorelSchemaEditor { public class PathProcessor { private Application app; private static PathProcessor instance; public PathProcessor(Application App) { app = App; } public static PathProcessor getProcessor(Application App) { if (instance != null) { return instance; } instance = new PathProcessor(App); return instance; } private void process_M(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double x = Double.Parse(arg1.Replace('.', ',')); double y = ph - Double.Parse(arg2.Replace('.', ',')); startPoint.x = x; startPoint.y = y; currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = x; lastControlPoint.y = y; } private void process_m(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double dx = Double.Parse(arg1.Replace('.', ',')); double dy = Double.Parse(arg2.Replace('.', ',')); currentPoint.x += dx; currentPoint.y -= dy; startPoint.x = currentPoint.x; startPoint.y = currentPoint.y; lastControlPoint.x = currentPoint.x; lastControlPoint.y = currentPoint.y; } private void process_L(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double x = Double.Parse(arg1.Replace('.', ',')); double y = ph - Double.Parse(arg2.Replace('.', ',')); path.AppendLineSegment(x, y); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = x; lastControlPoint.y = y; } private void process_l(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double dx = Double.Parse(arg1.Replace('.', ',')); double dy = Double.Parse(arg2.Replace('.', ',')); currentPoint.x += dx; currentPoint.y -= dy; path.AppendLineSegment(currentPoint.x, currentPoint.y); lastControlPoint.x = currentPoint.x; lastControlPoint.y = currentPoint.y; } private void process_H(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); double x = Double.Parse(arg1.Replace('.', ',')); path.AppendLineSegment(x, currentPoint.y); currentPoint.x = x; lastControlPoint.x = x; } private void process_h(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); double dx = Double.Parse(arg1.Replace('.', ',')); currentPoint.x += dx; path.AppendLineSegment(currentPoint.x, currentPoint.y); lastControlPoint.x = currentPoint.x; } private void process_V(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); double y = ph - Double.Parse(arg1.Replace('.', ',')); path.AppendLineSegment(currentPoint.x, y); currentPoint.y = y; lastControlPoint.y = y; } private void process_v(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); double dy = Double.Parse(arg1.Replace('.', ',')); currentPoint.y -= dy; path.AppendLineSegment(currentPoint.x, currentPoint.y); lastControlPoint.y = currentPoint.y; } private void process_C(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); string arg5 = tokens.First(); tokens.RemoveAt(0); string arg6 = tokens.First(); tokens.RemoveAt(0); double x1 = Double.Parse(arg1.Replace('.', ',')); double y1 = ph - Double.Parse(arg2.Replace('.', ',')); double x2 = Double.Parse(arg3.Replace('.', ',')); double y2 = ph - Double.Parse(arg4.Replace('.', ',')); double x = Double.Parse(arg5.Replace('.', ',')); double y = ph - Double.Parse(arg6.Replace('.', ',')); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = x2; lastControlPoint.y = y2; } private void process_c(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); string arg5 = tokens.First(); tokens.RemoveAt(0); string arg6 = tokens.First(); tokens.RemoveAt(0); double x1 = currentPoint.x + Double.Parse(arg1.Replace('.', ',')); double y1 = currentPoint.y - Double.Parse(arg2.Replace('.', ',')); double x2 = currentPoint.x + Double.Parse(arg3.Replace('.', ',')); double y2 = currentPoint.y - Double.Parse(arg4.Replace('.', ',')); double x = currentPoint.x + Double.Parse(arg5.Replace('.', ',')); double y = currentPoint.y - Double.Parse(arg6.Replace('.', ',')); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); lastControlPoint.x = x2; lastControlPoint.y = y2; currentPoint.x = x; currentPoint.y = y; } private void process_S(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, string prevCommand, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); double x2 = Double.Parse(arg1.Replace('.', ',')); double y2 = ph - Double.Parse(arg2.Replace('.', ',')); double x = Double.Parse(arg3.Replace('.', ',')); double y = ph - Double.Parse(arg4.Replace('.', ',')); double x1 = x2; double y1 = y2; if (prevCommand == "S" || prevCommand == "s" || prevCommand == "C" || prevCommand == "c") { x1 = lastControlPoint.x + ((currentPoint.x - lastControlPoint.x) * 2); y1 = lastControlPoint.y + ((currentPoint.y - lastControlPoint.y) * 2); } path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = x2; lastControlPoint.y = y2; } private void process_s(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, string prevCommand) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); double x2 = currentPoint.x + Double.Parse(arg1.Replace('.', ',')); double y2 = currentPoint.y - Double.Parse(arg2.Replace('.', ',')); double x = currentPoint.x + Double.Parse(arg3.Replace('.', ',')); double y = currentPoint.y - Double.Parse(arg4.Replace('.', ',')); double x1 = x2; double y1 = y2; if (prevCommand == "S" || prevCommand == "s" || prevCommand == "C" || prevCommand == "c") { x1 = lastControlPoint.x + ((currentPoint.x - lastControlPoint.x) * 2); y1 = lastControlPoint.y + ((currentPoint.y - lastControlPoint.y) * 2); } path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = x2; lastControlPoint.y = y2; } private void process_Q(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); double xc = Double.Parse(arg1.Replace('.', ',')); double yc = ph - Double.Parse(arg2.Replace('.', ',')); double x = Double.Parse(arg3.Replace('.', ',')); double y = ph - Double.Parse(arg4.Replace('.', ',')); double x1 = currentPoint.x + (2.0 / 3.0) * (xc - currentPoint.x); double y1 = currentPoint.y + (2.0 / 3.0) * (yc - currentPoint.y); double x2 = x + (2.0 / 3.0) * (xc - x); double y2 = y + (2.0 / 3.0) * (yc - y); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = xc; lastControlPoint.y = yc; } private void process_q(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); double xc = currentPoint.x + Double.Parse(arg1.Replace('.', ',')); double yc = currentPoint.y - Double.Parse(arg2.Replace('.', ',')); double x = currentPoint.x + Double.Parse(arg3.Replace('.', ',')); double y = currentPoint.y - Double.Parse(arg4.Replace('.', ',')); double x1 = currentPoint.x + (2.0 / 3.0) * (xc - currentPoint.x); double y1 = currentPoint.y + (2.0 / 3.0) * (yc - currentPoint.y); double x2 = x + (2.0 / 3.0) * (xc - x); double y2 = y + (2.0 / 3.0) * (yc - y); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = xc; lastControlPoint.y = yc; } private void process_T(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, string prevCommand, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double x = Double.Parse(arg1.Replace('.', ',')); double y = ph - Double.Parse(arg2.Replace('.', ',')); double xc = currentPoint.x; double yc = currentPoint.y; if (prevCommand == "Q" || prevCommand == "q" || prevCommand == "T" || prevCommand == "t") { xc = lastControlPoint.x + ((currentPoint.x - lastControlPoint.x) * 2); yc = lastControlPoint.y + ((currentPoint.y - lastControlPoint.y) * 2); } double x1 = currentPoint.x + (2.0 / 3.0) * (xc - currentPoint.x); double y1 = currentPoint.y + (2.0 / 3.0) * (yc - currentPoint.y); double x2 = x + (2.0 / 3.0) * (xc - x); double y2 = y + (2.0 / 3.0) * (yc - y); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = xc; lastControlPoint.y = yc; } private void process_t(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, string prevCommand) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); double x = currentPoint.x + Double.Parse(arg1.Replace('.', ',')); double y = currentPoint.x - Double.Parse(arg2.Replace('.', ',')); double xc = currentPoint.x; double yc = currentPoint.y; if (prevCommand == "Q" || prevCommand == "q" || prevCommand == "T" || prevCommand == "t") { xc = lastControlPoint.x + ((currentPoint.x - lastControlPoint.x) * 2); yc = lastControlPoint.y + ((currentPoint.y - lastControlPoint.y) * 2); } double x1 = currentPoint.x + (2.0 / 3.0) * (xc - currentPoint.x); double y1 = currentPoint.y + (2.0 / 3.0) * (yc - currentPoint.y); double x2 = x + (2.0 / 3.0) * (xc - x); double y2 = y + (2.0 / 3.0) * (yc - y); path.AppendCurveSegment2(x, y, x1, y1, x2, y2); currentPoint.x = x; currentPoint.y = y; lastControlPoint.x = xc; lastControlPoint.y = yc; } private void process_A(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); string arg5 = tokens.First(); tokens.RemoveAt(0); string arg6 = tokens.First(); tokens.RemoveAt(0); string arg7 = tokens.First(); tokens.RemoveAt(0); double rx = Double.Parse(arg1.Replace('.', ',')); double ry = Double.Parse(arg2.Replace('.', ',')); double angle = Double.Parse(arg3.Replace('.', ',')); bool largeArc = arg4 == "1"; bool sweep = arg5 == "1"; double x1 = currentPoint.x; double y1 = currentPoint.y; double x2 = Double.Parse(arg6.Replace('.', ',')); double y2 = ph - Double.Parse(arg7.Replace('.', ',')); double _cos_fi = Math.Cos(angle / 180 * Math.PI); double _sin_fi = Math.Sin(angle / 180 * Math.PI); double _delta_x = (x1 - x2) / 2; double _delta_y = (y1 - y2) / 2; // Go to stright coords removing ellipse axis inclination double _stroke_x = (_cos_fi * _delta_x) + (_sin_fi * _delta_y); double _stroke_y = (-_sin_fi * _delta_x) + (_cos_fi * _delta_y); // Check and reduce radius in case it's too small for determined start/end points of arc double _radii_k = (Math.Pow(_stroke_x, 2) / Math.Pow(rx, 2)) + (Math.Pow(_stroke_y, 2) / Math.Pow(ry, 2)); if (_radii_k > 1) { rx = Math.Sqrt(_radii_k) * rx + 0.00000001; ry = Math.Sqrt(_radii_k) * ry + 0.00000001; } double _rx2 = rx * rx; double _ry2 = ry * ry; double _stroke_x2 = _stroke_x * _stroke_x; double _stroke_y2 = _stroke_y * _stroke_y; double _sign = (largeArc == sweep) ? -1 : 1; // Calc ellipse center coords double _root = Math.Sqrt(((_rx2 * _ry2) - (_rx2 * _stroke_y2) - (_ry2 * _stroke_x2)) / ((_rx2 * _stroke_y2) + (_ry2 * _stroke_x2))); double _matrix1 = rx * _stroke_y / ry; double _matrix2 = -1 * ry * _stroke_x / rx; double _stroke_cx = _sign * _root * _matrix1 * -1; double _stroke_cy = -_sign * _root * _matrix2; double _mid_x = (x1 + x2) / 2; double _mid_y = (y1 + y2) / 2; // Convert coords adding inclination double cx = (_cos_fi * _stroke_cx) + (-1 * _sin_fi * _stroke_cy) + _mid_x; double cy = (_sin_fi * _stroke_cx) + (_cos_fi * _stroke_cy) + _mid_y; Shape ellipse = app.ActiveLayer.CreateEllipse2(cx, cy, rx, ry); ellipse.Rotate(-angle); ellipse.ConvertToCurves(); SubPath pathEllipse = ellipse.Curve.SubPaths.First; double offset1; Segment seg1 = pathEllipse.FindClosestSegment(x1, y1, out offset1); Point pStart = seg1.GetPointAt(offset1, cdrSegmentOffsetType.cdrParamSegmentOffset); Node testNode = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); if (testNode == null) { seg1.AddNodeAt(offset1, cdrSegmentOffsetType.cdrParamSegmentOffset); } double offset2; Segment seg2 = pathEllipse.FindClosestSegment(x2, y2, out offset2); Point pEnd = seg2.GetPointAt(offset2, cdrSegmentOffsetType.cdrParamSegmentOffset); Node testNode2 = pathEllipse.FindNodeAtPoint(pEnd.x, pEnd.y, 0.0001); if (testNode2 == null) { seg2.AddNodeAt(offset2, cdrSegmentOffsetType.cdrParamSegmentOffset); } Node nodeStart = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); nodeStart.BreakApart(); nodeStart = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); Node nodeEnd = pathEllipse.FindNodeAtPoint(pEnd.x, pEnd.y, 0.0001); if (!sweep) { Segment seg = pathEllipse.Segments.First; while (seg.EndNode.PositionX != nodeEnd.PositionX && seg.EndNode.PositionY != nodeEnd.PositionY) { path.AppendCurveSegment2(seg.EndNode.PositionX, seg.EndNode.PositionY, seg.StartingControlPointX, seg.StartingControlPointY, seg.EndingControlPointX, seg.EndingControlPointY); seg = seg.Next(); } path.AppendCurveSegment2(seg.EndNode.PositionX, seg.EndNode.PositionY, seg.StartingControlPointX, seg.StartingControlPointY, seg.EndingControlPointX, seg.EndingControlPointY); } else { Segment seg = pathEllipse.Segments.Last; while (seg.StartNode.PositionX != nodeEnd.PositionX && seg.StartNode.PositionY != nodeEnd.PositionY) { path.AppendCurveSegment2(seg.StartNode.PositionX, seg.StartNode.PositionY, seg.EndingControlPointX, seg.EndingControlPointY, seg.StartingControlPointX, seg.StartingControlPointY); seg = seg.Previous(); } path.AppendCurveSegment2(seg.StartNode.PositionX, seg.StartNode.PositionY, seg.EndingControlPointX, seg.EndingControlPointY, seg.StartingControlPointX, seg.StartingControlPointY); } ellipse.Delete(); currentPoint.x = pEnd.x; currentPoint.y = pEnd.y; lastControlPoint.x = currentPoint.x; lastControlPoint.y = currentPoint.y; } private void process_a(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path, double ph) { string arg1 = tokens.First(); tokens.RemoveAt(0); string arg2 = tokens.First(); tokens.RemoveAt(0); string arg3 = tokens.First(); tokens.RemoveAt(0); string arg4 = tokens.First(); tokens.RemoveAt(0); string arg5 = tokens.First(); tokens.RemoveAt(0); string arg6 = tokens.First(); tokens.RemoveAt(0); string arg7 = tokens.First(); tokens.RemoveAt(0); double rx = Double.Parse(arg1.Replace('.', ',')); double ry = Double.Parse(arg2.Replace('.', ',')); double angle = Double.Parse(arg3.Replace('.', ',')); bool largeArc = arg4 == "1"; bool sweep = arg5 == "1"; double x1 = currentPoint.x; double y1 = currentPoint.y; double x2 = currentPoint.x + Double.Parse(arg6.Replace('.', ',')); double y2 = currentPoint.y - Double.Parse(arg7.Replace('.', ',')); double _cos_fi = Math.Cos(angle / 180 * Math.PI); double _sin_fi = Math.Sin(angle / 180 * Math.PI); double _delta_x = (x1 - x2) / 2; double _delta_y = (y1 - y2) / 2; // Go to stright coords removind inclination of ellipse axis double _stroke_x = (_cos_fi * _delta_x) + (_sin_fi * _delta_y); double _stroke_y = (-_sin_fi * _delta_x) + (_cos_fi * _delta_y); // Check and reduce radius in case it's too small for determined start/end points of arc double _radii_k = (Math.Pow(_stroke_x, 2) / Math.Pow(rx, 2)) + (Math.Pow(_stroke_y, 2) / Math.Pow(ry, 2)); if (_radii_k > 1) { rx = Math.Sqrt(_radii_k) * rx + 0.00000001; ry = Math.Sqrt(_radii_k) * ry + 0.00000001; } double _rx2 = rx * rx; double _ry2 = ry * ry; double _stroke_x2 = _stroke_x * _stroke_x; double _stroke_y2 = _stroke_y * _stroke_y; double _sign = (largeArc == sweep) ? -1 : 1; // Calc coords of ellipse center double _root = Math.Sqrt(((_rx2 * _ry2) - (_rx2 * _stroke_y2) - (_ry2 * _stroke_x2)) / ((_rx2 * _stroke_y2) + (_ry2 * _stroke_x2))); double _matrix1 = rx * _stroke_y / ry; double _matrix2 = -1 * ry * _stroke_x / rx; double _stroke_cx = _sign * _root * _matrix1; double _stroke_cy = -_sign * _root * _matrix2; double _mid_x = (x1 + x2) / 2; double _mid_y = (y1 + y2) / 2; // Convert coords of ellipse adding inclination double cx = (_cos_fi * _stroke_cx) + (-1 * _sin_fi * _stroke_cy) + _mid_x; double cy = (_sin_fi * _stroke_cx) + (_cos_fi * _stroke_cy) + _mid_y; Shape ellipse = app.ActiveLayer.CreateEllipse2(cx, cy, rx, ry); ellipse.Rotate(-angle); ellipse.ConvertToCurves(); SubPath pathEllipse = ellipse.Curve.SubPaths.First; double offset1; Segment seg1 = pathEllipse.FindClosestSegment(x1, y1, out offset1); Point pStart = seg1.GetPointAt(offset1, cdrSegmentOffsetType.cdrParamSegmentOffset); Node testNode = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); if (testNode == null) { seg1.AddNodeAt(offset1, cdrSegmentOffsetType.cdrParamSegmentOffset); } double offset2; Segment seg2 = pathEllipse.FindClosestSegment(x2, y2, out offset2); Point pEnd = seg2.GetPointAt(offset2, cdrSegmentOffsetType.cdrParamSegmentOffset); Node testNode2 = pathEllipse.FindNodeAtPoint(pEnd.x, pEnd.y, 0.0001); if (testNode2 == null) { seg2.AddNodeAt(offset2, cdrSegmentOffsetType.cdrParamSegmentOffset); } Node nodeStart = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); nodeStart.BreakApart(); nodeStart = pathEllipse.FindNodeAtPoint(pStart.x, pStart.y, 0.0001); Node nodeEnd = pathEllipse.FindNodeAtPoint(pEnd.x, pEnd.y, 0.0001); if (!sweep) { Segment seg = pathEllipse.Segments.First; while (seg.EndNode.PositionX != nodeEnd.PositionX && seg.EndNode.PositionY != nodeEnd.PositionY) { path.AppendCurveSegment2(seg.EndNode.PositionX, seg.EndNode.PositionY, seg.StartingControlPointX, seg.StartingControlPointY, seg.EndingControlPointX, seg.EndingControlPointY); seg = seg.Next(); } path.AppendCurveSegment2(seg.EndNode.PositionX, seg.EndNode.PositionY, seg.StartingControlPointX, seg.StartingControlPointY, seg.EndingControlPointX, seg.EndingControlPointY); } else { Segment seg = pathEllipse.Segments.Last; while (seg.StartNode.PositionX != nodeEnd.PositionX && seg.StartNode.PositionY != nodeEnd.PositionY) { path.AppendCurveSegment2(seg.StartNode.PositionX, seg.StartNode.PositionY, seg.EndingControlPointX, seg.EndingControlPointY, seg.StartingControlPointX, seg.StartingControlPointY); seg = seg.Previous(); } path.AppendCurveSegment2(seg.StartNode.PositionX, seg.StartNode.PositionY, seg.EndingControlPointX, seg.EndingControlPointY, seg.StartingControlPointX, seg.StartingControlPointY); } ellipse.Delete(); currentPoint.x = pEnd.x; currentPoint.y = pEnd.y; lastControlPoint.x = currentPoint.x; lastControlPoint.y = currentPoint.y; } private void process_Z(List tokens, Point startPoint, Point currentPoint, Point lastControlPoint, SubPath path) { currentPoint.x = startPoint.x; currentPoint.y = startPoint.y; lastControlPoint.x = currentPoint.x; lastControlPoint.y = currentPoint.y; path.Closed = true; } // Main method public Shape processPath(string path) { double ph = app.ActivePage.SizeHeight; Layer layer = app.ActivePage.Layers["Objects"]; // Remove double space chars path = path.Replace("M", " M ") .Replace("m", " m ") .Replace("L", " L ") .Replace("l", " l ") .Replace("H", " H ") .Replace("h", " h ") .Replace("V", " V ") .Replace("v", " v ") .Replace("C", " C ") .Replace("c", " c ") .Replace("S", " S ") .Replace("s", " s ") .Replace("Q", " Q ") .Replace("q", " q ") .Replace("T", " T ") .Replace("t", " t ") .Replace("A", " A ") .Replace("a", " a ") .Replace("Z", " Z ") .Replace("z", " z "); path = Regex.Replace(path, "\\s{2,}", " "); List tokens = new List(); tokens.AddRange(path.Split(new[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries)); Point startPoint = app.Math.CreatePoint(0, ph); Point currentPoint = app.Math.CreatePoint(0, ph); Point lastControlPoint = app.Math.CreatePoint(0, ph); Curve curve = app.CreateCurve(); SubPath currentPath = curve.CreateSubPath(0, ph); string prevCommand = ""; while (tokens.Count > 0) { string command = tokens.First(); tokens.RemoveAt(0); switch (command) { case "M": process_M(tokens, startPoint, currentPoint, lastControlPoint, ph); currentPath = curve.CreateSubPath(currentPoint.x, currentPoint.y); prevCommand = "M"; break; case "m": process_m(tokens, startPoint, currentPoint, lastControlPoint); currentPath = curve.CreateSubPath(currentPoint.x, currentPoint.y); prevCommand = "m"; break; case "L": process_L(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "L"; break; case "l": process_l(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "l"; break; case "H": process_H(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "H"; break; case "h": process_h(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "h"; break; case "V": process_V(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "V"; break; case "v": process_v(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "v"; break; case "Z": process_Z(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "Z"; break; case "z": process_Z(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "z"; break; case "C": process_C(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "C"; break; case "c": process_c(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "c"; break; case "S": process_S(tokens, startPoint, currentPoint, lastControlPoint, currentPath, prevCommand, ph); prevCommand = "S"; break; case "s": process_s(tokens, startPoint, currentPoint, lastControlPoint, currentPath, prevCommand); prevCommand = "s"; break; case "Q": process_Q(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "Q"; break; case "q": process_q(tokens, startPoint, currentPoint, lastControlPoint, currentPath); prevCommand = "q"; break; case "T": process_T(tokens, startPoint, currentPoint, lastControlPoint, currentPath, prevCommand, ph); prevCommand = "T"; break; case "t": process_t(tokens, startPoint, currentPoint, lastControlPoint, currentPath, prevCommand); prevCommand = "t"; break; case "A": process_A(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "A"; break; case "a": process_a(tokens, startPoint, currentPoint, lastControlPoint, currentPath, ph); prevCommand = "a"; break; default: throw new Exception("Unknown command in path: " + command); } } return layer.CreateCurve(curve); } } }
Very cool, if only my C# skills where so sharp. ;-)