private void CreateHatchBoundsAndEntitiess(Core2D.Path.XPathGeometry pg, double dx, double dy, out IList <HatchBoundaryPath> bounds, out ICollection <EntityObject> entities) { bounds = new List <HatchBoundaryPath>(); entities = new List <EntityObject>(); // TODO: FillMode = pg.FillRule == XFillRule.EvenOdd ? FillMode.Alternate : FillMode.Winding; foreach (var pf in pg.Figures) { var edges = new List <EntityObject>(); var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is Core2D.Path.Segments.XArcSegment) { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); //var arcSegment = segment as XArcSegment; // TODO: Convert WPF/SVG elliptical arc segment format to DXF ellipse arc. //startPoint = arcSegment.Point; } else if (segment is Core2D.Path.Segments.XCubicBezierSegment) { var cubicBezierSegment = segment as Core2D.Path.Segments.XCubicBezierSegment; var dxfSpline = CreateCubicSpline( startPoint.X + dx, startPoint.Y + dy, cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy, cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy, cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); startPoint = cubicBezierSegment.Point3; } else if (segment is Core2D.Path.Segments.XLineSegment) { var lineSegment = segment as Core2D.Path.Segments.XLineSegment; var dxfLine = CreateLine( startPoint.X + dx, startPoint.Y + dy, lineSegment.Point.X + dx, lineSegment.Point.Y + dy); edges.Add(dxfLine); entities.Add((Line)dxfLine.Clone()); startPoint = lineSegment.Point; } else if (segment is Core2D.Path.Segments.XPolyCubicBezierSegment) { var polyCubicBezierSegment = segment as Core2D.Path.Segments.XPolyCubicBezierSegment; if (polyCubicBezierSegment.Points.Length >= 3) { var dxfSpline = CreateCubicSpline( startPoint.X + dx, startPoint.Y + dy, polyCubicBezierSegment.Points[0].X + dx, polyCubicBezierSegment.Points[0].Y + dy, polyCubicBezierSegment.Points[1].X + dx, polyCubicBezierSegment.Points[1].Y + dy, polyCubicBezierSegment.Points[2].X + dx, polyCubicBezierSegment.Points[2].Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { var dxfSpline = CreateCubicSpline( polyCubicBezierSegment.Points[i - 1].X + dx, polyCubicBezierSegment.Points[i - 1].Y + dy, polyCubicBezierSegment.Points[i].X + dx, polyCubicBezierSegment.Points[i].Y + dy, polyCubicBezierSegment.Points[i + 1].X + dx, polyCubicBezierSegment.Points[i + 1].Y + dy, polyCubicBezierSegment.Points[i + 2].X + dx, polyCubicBezierSegment.Points[i + 2].Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); } } startPoint = polyCubicBezierSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XPolyLineSegment) { var polyLineSegment = segment as Core2D.Path.Segments.XPolyLineSegment; if (polyLineSegment.Points.Length >= 1) { var dxfLine = CreateLine( startPoint.X + dx, startPoint.Y + dy, polyLineSegment.Points[0].X + dx, polyLineSegment.Points[0].Y + dy); edges.Add(dxfLine); entities.Add((Line)dxfLine.Clone()); } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { var dxfLine = CreateLine( polyLineSegment.Points[i - 1].X + dx, polyLineSegment.Points[i - 1].Y + dy, polyLineSegment.Points[i].X + dx, polyLineSegment.Points[i].Y + dy); edges.Add(dxfLine); entities.Add((Line)dxfLine.Clone()); } } startPoint = polyLineSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as Core2D.Path.Segments.XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Length >= 2) { var dxfSpline = CreateQuadraticSpline( startPoint.X + dx, startPoint.Y + dy, polyQuadraticSegment.Points[0].X + dx, polyQuadraticSegment.Points[0].Y + dy, polyQuadraticSegment.Points[1].X + dx, polyQuadraticSegment.Points[1].Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { var dxfSpline = CreateQuadraticSpline( polyQuadraticSegment.Points[i - 1].X + dx, polyQuadraticSegment.Points[i - 1].Y + dy, polyQuadraticSegment.Points[i].X + dx, polyQuadraticSegment.Points[i].Y + dy, polyQuadraticSegment.Points[i + 1].X + dx, polyQuadraticSegment.Points[i + 1].Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); } } startPoint = polyQuadraticSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XQuadraticBezierSegment) { var quadraticBezierSegment = segment as Core2D.Path.Segments.XQuadraticBezierSegment; var dxfSpline = CreateQuadraticSpline( startPoint.X + dx, startPoint.Y + dy, quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy, quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy); edges.Add(dxfSpline); entities.Add((Spline)dxfSpline.Clone()); startPoint = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } // TODO: Add support for pf.IsClosed var path = new HatchBoundaryPath(edges); bounds.Add(path); } }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static XGraphicsPath ToXGraphicsPath(this Core2D.Path.XPathGeometry pg, double dx, double dy, Func <double, double> scale) { var gp = new XGraphicsPath(); gp.FillMode = pg.FillRule == Core2D.Path.XFillRule.EvenOdd ? XFillMode.Alternate : XFillMode.Winding; foreach (var pf in pg.Figures) { var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is Core2D.Path.Segments.XArcSegment) { #if CORE //var arcSegment = segment as Core2D.XArcSegment; // TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves. //startPoint = arcSegment.Point; #endif #if WPF var arcSegment = segment as Core2D.Path.Segments.XArcSegment; var point1 = new XPoint( scale(startPoint.X + dx), scale(startPoint.Y + dy)); var point2 = new XPoint( scale(arcSegment.Point.X + dx), scale(arcSegment.Point.Y + dy)); var size = new XSize( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height)); gp.AddArc( point1, point2, size, arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == Core2D.Path.XSweepDirection.Clockwise ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise); startPoint = arcSegment.Point; #endif } else if (segment is Core2D.Path.Segments.XCubicBezierSegment) { var cubicBezierSegment = segment as Core2D.Path.Segments.XCubicBezierSegment; gp.AddBezier( scale(startPoint.X + dx), scale(startPoint.Y + dy), scale(cubicBezierSegment.Point1.X + dx), scale(cubicBezierSegment.Point1.Y + dy), scale(cubicBezierSegment.Point2.X + dx), scale(cubicBezierSegment.Point2.Y + dy), scale(cubicBezierSegment.Point3.X + dx), scale(cubicBezierSegment.Point3.Y + dy)); startPoint = cubicBezierSegment.Point3; } else if (segment is Core2D.Path.Segments.XLineSegment) { var lineSegment = segment as Core2D.Path.Segments.XLineSegment; gp.AddLine( scale(startPoint.X + dx), scale(startPoint.Y + dy), scale(lineSegment.Point.X + dx), scale(lineSegment.Point.Y + dy)); startPoint = lineSegment.Point; } else if (segment is Core2D.Path.Segments.XPolyCubicBezierSegment) { var polyCubicBezierSegment = segment as Core2D.Path.Segments.XPolyCubicBezierSegment; if (polyCubicBezierSegment.Points.Length >= 3) { gp.AddBezier( scale(startPoint.X + dx), scale(startPoint.Y + dy), scale(polyCubicBezierSegment.Points[0].X + dx), scale(polyCubicBezierSegment.Points[0].Y + dy), scale(polyCubicBezierSegment.Points[1].X + dx), scale(polyCubicBezierSegment.Points[1].Y + dy), scale(polyCubicBezierSegment.Points[2].X + dx), scale(polyCubicBezierSegment.Points[2].Y + dy)); } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { gp.AddBezier( scale(polyCubicBezierSegment.Points[i - 1].X + dx), scale(polyCubicBezierSegment.Points[i - 1].Y + dy), scale(polyCubicBezierSegment.Points[i].X + dx), scale(polyCubicBezierSegment.Points[i].Y + dy), scale(polyCubicBezierSegment.Points[i + 1].X + dx), scale(polyCubicBezierSegment.Points[i + 1].Y + dy), scale(polyCubicBezierSegment.Points[i + 2].X + dx), scale(polyCubicBezierSegment.Points[i + 2].Y + dy)); } } startPoint = polyCubicBezierSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XPolyLineSegment) { var polyLineSegment = segment as Core2D.Path.Segments.XPolyLineSegment; if (polyLineSegment.Points.Length >= 1) { gp.AddLine( scale(startPoint.X + dx), scale(startPoint.Y + dy), scale(polyLineSegment.Points[0].X + dx), scale(polyLineSegment.Points[0].Y + dy)); } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { gp.AddLine( scale(polyLineSegment.Points[i - 1].X + dx), scale(polyLineSegment.Points[i - 1].Y + dy), scale(polyLineSegment.Points[i].X + dx), scale(polyLineSegment.Points[i].Y + dy)); } } startPoint = polyLineSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as Core2D.Path.Segments.XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Length >= 2) { var p1 = startPoint; var p2 = polyQuadraticSegment.Points[0]; var p3 = polyQuadraticSegment.Points[1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( scale(x1 + dx), scale(y1 + dy), scale(x2 + dx), scale(y2 + dy), scale(x3 + dx), scale(y3 + dy), scale(x4 + dx), scale(y4 + dy)); } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { var p1 = polyQuadraticSegment.Points[i - 1]; var p2 = polyQuadraticSegment.Points[i]; var p3 = polyQuadraticSegment.Points[i + 1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( scale(x1 + dx), scale(y1 + dy), scale(x2 + dx), scale(y2 + dy), scale(x3 + dx), scale(y3 + dy), scale(x4 + dx), scale(y4 + dy)); } } startPoint = polyQuadraticSegment.Points.Last(); } else if (segment is Core2D.Path.Segments.XQuadraticBezierSegment) { var quadraticBezierSegment = segment as Core2D.Path.Segments.XQuadraticBezierSegment; var p1 = startPoint; var p2 = quadraticBezierSegment.Point1; var p3 = quadraticBezierSegment.Point2; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( scale(x1 + dx), scale(y1 + dy), scale(x2 + dx), scale(y2 + dy), scale(x3 + dx), scale(y3 + dy), scale(x4 + dx), scale(y4 + dy)); startPoint = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (pf.IsClosed) { gp.CloseFigure(); } else { gp.StartFigure(); } } return(gp); }