private SKPath PathGeometryToSkiaPath(IPathGeometry pathGeometry, bool onlyIncludeFilledFigures = false) { // TODO: Decide how (or if) to support geometry.StandardFlatteningTolerance SKPath skPath = new SKPath(); skPath.FillType = FillRuleToSkiaPathFillType(pathGeometry.FillRule); foreach (IPathFigure pathFigure in pathGeometry.Figures) { if (onlyIncludeFilledFigures && !pathFigure.IsFilled) { continue; } Point startPoint = pathFigure.StartPoint; skPath.MoveTo((float)startPoint.X, (float)startPoint.Y); foreach (IPathSegment pathSegment in pathFigure.Segments) { AddPathSegmentToSkiaPath(skPath, pathSegment); } if (pathFigure.IsClosed) { skPath.Close(); } } return(skPath); }
protected ShapeNode(FabricStyle fabricStyle, IPathGeometry pathGeometry) : base(pathGeometry) { if (pathGeometry == null) { throw new ArgumentNullException(nameof(pathGeometry)); } m_fabricStyle = fabricStyle ?? throw new ArgumentNullException(nameof(fabricStyle)); }
protected Node(IPathGeometry pathGeometry) { if (pathGeometry == null) { throw new ArgumentNullException(nameof(pathGeometry)); } m_path = pathGeometry.Prototype.Clone(); m_visible = true; }
protected Path(Path prototype) { if (prototype == null) { throw new ArgumentNullException(nameof(prototype)); } m_pathGeometry = prototype.m_pathGeometry; m_segments = prototype.m_segments.Clone(); }
public Path(JToken json) { if (json == null) { throw new ArgumentNullException(nameof(json)); } m_pathGeometry = PathGeometryFactory.Create(json[JsonNames.PathGeometry]); m_segments = new PathSegmentList(json[JsonNames.Segments]); }
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueObject) { if (!(valueObject is string value)) { throw new InvalidOperationException($"Cannot convert from type {valueObject.GetType()}"); } IPathGeometry pathGeometry = PathConverter.ParsePathGeometry(value, GeometryFactory.Instance); return(pathGeometry); }
private void Add(IPathGeometry geometry) { if (geometry == null) { return; } geometry.PropertyChanged += ObserveShape; if (geometry.Figures != null) { Add(geometry.Figures); } }
public LayoutSite(LayoutNode parent, IPathGeometry pathGeometry) { if (pathGeometry == null) { throw new ArgumentNullException(nameof(pathGeometry)); } m_parent = parent ?? throw new ArgumentNullException(nameof(parent)); m_path = pathGeometry.Prototype.Clone(); m_style = null; m_pathOrientation = PathOrientation.CreateDefault(); m_node = null; }
private void Remove(IPathGeometry geometry) { if (geometry == null) { return; } geometry.PropertyChanged -= ObserveShape; if (geometry.Figures != null) { Remove(geometry.Figures); } }
/// <inheritdoc/> IPathShape IShapeFactory.Path(IPathGeometry geometry, bool isStroked, bool isFilled) { var factory = _serviceProvider.GetService <IFactory>(); var editor = _serviceProvider.GetService <IProjectEditor>(); var project = editor.Project; var style = project.CurrentStyleLibrary.Selected; var path = factory.CreatePathShape( "", project.Options.CloneStyle ? (IShapeStyle)style.Copy(null) : style, geometry, isStroked, isFilled); project.AddShape(project.CurrentContainer.CurrentLayer, path); return(path); }
/// <inheritdoc/> IPathShape IShapeFactory.Path(IPathGeometry geometry, bool isStroked, bool isFilled) { var factory = _serviceProvider.GetService <IFactory>(); var editor = _serviceProvider.GetService <IProjectEditor>(); var project = editor.Project; var style = project.CurrentStyleLibrary?.Selected != null ? project.CurrentStyleLibrary.Selected : factory.CreateShapeStyle(ProjectEditorConfiguration.DefaulStyleName); var path = factory.CreatePathShape( "", (IShapeStyle)style.Copy(null), geometry, isStroked, isFilled); project.AddShape(project.CurrentContainer.CurrentLayer, path); return(path); }
///<inheritdoc/> public virtual IEnumerable <ILabelModelParameter> GetParameters(ILabel label, ILabelModel model) { SliderEdgeLabelModel sliderEdgeLabelModel = (SliderEdgeLabelModel)model; List <ILabelModelParameter> result = new List <ILabelModelParameter>(); IEdge edge = (IEdge)label.Owner; IPathGeometry geometry = GetPathGeometry(edge); if (geometry != null) { int count = geometry.GetSegmentCount(); for (int i = 0; i < count; i++) { result.Add(sliderEdgeLabelModel.CreateParameterFromSource(i, 0)); result.Add(sliderEdgeLabelModel.CreateParameterFromSource(i, 0.5)); result.Add(sliderEdgeLabelModel.CreateParameterFromSource(i, 1)); } } return(result); }
public void SetAnchor(SliderEdgeLabelModel labelModel, IEdge edge, OrientedRectangle geometry) { IPathGeometry pathGeometry = GetPathGeometry(edge); if (pathGeometry != null) { int count = pathGeometry.GetSegmentCount(); int index = segmentIndex; if (index >= count) { index = count - 1; } if (index < 0) { index = count + index; } if (index < 0) { index = 0; } else if (index >= count) { index = count - 1; } double thisRatio = ratio; var validTangent = pathGeometry.GetTangent(index, thisRatio); if (validTangent.HasValue) { var p = validTangent.Value.Point; var t = validTangent.Value.Vector; AnchorGeometry(geometry, labelModel.EdgeRelativeDistance, labelModel.Distance, p.X, p.Y, thisRatio, t.X, t.Y); return; } } geometry.Width = -1; geometry.Height = -1; }
private List <SkiaPathFigure> PathGeometryToSkiaPathFigures(IPathGeometry pathGeometry) { SKPathFillType fillType = pathGeometry.FillRule switch { FillRule.EvenOdd => SKPathFillType.EvenOdd, FillRule.Nonzero => SKPathFillType.Winding, _ => throw new InvalidOperationException($"Unknown fillRule value {pathGeometry.FillRule}") }; List <SkiaPathFigure> skiaPathFigures = new List <SkiaPathFigure>(); // TODO: Decide how (or if) to support geometry.StandardFlatteningTolerance foreach (IPathFigure pathFigure in pathGeometry.Figures) { Point startPoint = pathFigure.StartPoint; SKPath skPath = new SKPath(); skPath.FillType = fillType; skPath.MoveTo((float)startPoint.X, (float)startPoint.Y); foreach (IPathSegment pathSegment in pathFigure.Segments) { AddPathSegmentToSkiaPath(skPath, pathSegment); } if (pathFigure.IsClosed) { skPath.LineTo((float)startPoint.X, (float)startPoint.Y); } skiaPathFigures.Add(new SkiaPathFigure(skPath, pathFigure.IsFilled)); } return(skiaPathFigures); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public WM.StreamGeometry ToStreamGeometry(IPathGeometry xpg, double dx, double dy) { var sg = new WM.StreamGeometry(); using (var sgc = sg.Open()) { foreach (var xpf in xpg.Figures) { sgc.BeginFigure( new W.Point(xpf.StartPoint.X, xpf.StartPoint.Y), xpf.IsFilled, xpf.IsClosed); foreach (var segment in xpf.Segments) { if (segment is IArcSegment arcSegment) { sgc.ArcTo( new W.Point(arcSegment.Point.X + dx, arcSegment.Point.Y + dy), new W.Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? WM.SweepDirection.Clockwise : WM.SweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is ICubicBezierSegment cubicBezierSegment) { sgc.BezierTo( new W.Point(cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy), new W.Point(cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy), new W.Point(cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy), cubicBezierSegment.IsStroked, cubicBezierSegment.IsSmoothJoin); } else if (segment is ILineSegment lineSegment) { sgc.LineTo( new W.Point(lineSegment.Point.X + dx, lineSegment.Point.Y + dy), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is IPolyCubicBezierSegment polyCubicBezierSegment) { sgc.PolyBezierTo( ToPoints(polyCubicBezierSegment.Points, dx, dy), polyCubicBezierSegment.IsStroked, polyCubicBezierSegment.IsSmoothJoin); } else if (segment is IPolyLineSegment polyLineSegment) { sgc.PolyLineTo( ToPoints(polyLineSegment.Points, dx, dy), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is IPolyQuadraticBezierSegment polyQuadraticSegment) { sgc.PolyQuadraticBezierTo( ToPoints(polyQuadraticSegment.Points, dx, dy), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is IQuadraticBezierSegment quadraticBezierSegment) { sgc.QuadraticBezierTo( new W.Point(quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy), new W.Point(quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy), quadraticBezierSegment.IsStroked, quadraticBezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } } sg.FillRule = xpg.FillRule == FillRule.Nonzero ? WM.FillRule.Nonzero : WM.FillRule.EvenOdd; sg.Freeze(); return(sg); }
/// <summary> /// Initializes a new instance of the <see cref="PathGeometryContext"/> class. /// </summary> /// <param name="factory">The factory instance.</param> /// <param name="geometry">The path geometry.</param> public PathGeometryContext(IFactory factory, IPathGeometry geometry) { _factory = factory; _geometry = geometry ?? throw new ArgumentNullException(nameof(geometry)); }
public override object ConvertFromInvariantString(string value) { IPathGeometry pathGeometry = PathConverter.ParsePathGeometry(value, GeometryFactory.Instance); return(pathGeometry); }
private bool FindAnchorTangent(IEdge edge, out double upX, out double upY, out double cx, out double cy) { IEdgeStyle style = edge.Style; if (style != null) { IEdgeStyleRenderer renderer = style.Renderer; IPathGeometry geometry = renderer.GetPathGeometry(edge, style); if (geometry != null) { var t = geometry.GetTangent(ratio); if (t != null) { var tangent = t.Value; upX = -tangent.Vector.Y; upY = tangent.Vector.X; cx = tangent.Point.X; cy = tangent.Point.Y; return(true); } } } double l = 0; var spl = edge.SourcePort.GetLocation(); double x1 = spl.X; double y1 = spl.Y; var tpl = edge.TargetPort.GetLocation(); double x2 = tpl.X; double y2 = tpl.Y; { double lx = x1; double ly = y1; var bends = edge.Bends; for (int i = 0; i < bends.Count; i++) { IBend bend = bends[i]; double bx = bend.Location.X; double by = bend.Location.Y; double dx = bx - lx; double dy = by - ly; l += Math.Sqrt(dx * dx + dy * dy); lx = bx; ly = by; } { double dx = x2 - lx; double dy = y2 - ly; l += Math.Sqrt(dx * dx + dy * dy); } } double tl = ratio * l; if (l == 0) { // no length, no path, no label upX = 0; upY = -1; cx = x1; cy = y1; return(false); } l = 0; { double lx = x1; double ly = y1; var bends = edge.Bends; for (int i = 0; i < bends.Count; i++) { IBend bend = bends[i]; double bx = bend.Location.X; double by = bend.Location.Y; double dx = bx - lx; double dy = by - ly; double sl = Math.Sqrt(dx * dx + dy * dy); if (sl > 0 && l + sl >= tl) { tl -= l; cx = lx + tl * dx / sl; cy = ly + tl * dy / sl; upX = -dy; upY = dx; return(true); } l += sl; lx = bx; ly = by; } { double dx = x2 - lx; double dy = y2 - ly; double sl = Math.Sqrt(dx * dx + dy * dy); if (sl > 0) { tl -= l; cx = lx + tl * dx / sl; cy = ly + tl * dy / sl; upX = -dy; upY = dx; return(true); } else { upX = 0; upY = -1; cx = x1; cy = y1; return(false); } } } }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static D2D.GraphicsPath ToGraphicsPath(this IPathGeometry pg, double dx, double dy, Func <double, float> scale) { var gp = new D2D.GraphicsPath { FillMode = pg.FillRule == FillRule.EvenOdd ? D2D.FillMode.Alternate : D2D.FillMode.Winding }; foreach (var pf in pg.Figures) { var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is IArcSegment arcSegment) { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); // TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves. //startPoint = arcSegment.Point; } else if (segment is ICubicBezierSegment cubicBezierSegment) { 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 ILineSegment lineSegment) { 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 IPolyCubicBezierSegment polyCubicBezierSegment) { 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 IPolyLineSegment polyLineSegment) { 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 IPolyQuadraticBezierSegment polyQuadraticSegment) { 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 IQuadraticBezierSegment quadraticBezierSegment) { 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); }
public static IPathGeometry CreateRef(this IPathGeometry objectRef) => ((IPathGeometry)objectRef.CreateRef(typeof(IPathGeometry)));
public static PDF.XGraphicsPath ToXGraphicsPath(this IPathGeometry pg, Func <double, double> scale) { var gp = new PDF.XGraphicsPath() { FillMode = pg.FillRule == FillRule.EvenOdd ? PDF.XFillMode.Alternate : PDF.XFillMode.Winding }; foreach (var pf in pg.Figures) { var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is IArcSegment arcSegment) { #if WPF var point1 = new PDF.XPoint( scale(startPoint.X), scale(startPoint.Y)); var point2 = new PDF.XPoint( scale(arcSegment.Point.X), scale(arcSegment.Point.Y)); var size = new PDF.XSize( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height)); gp.AddArc( point1, point2, size, arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? PDF.XSweepDirection.Clockwise : PDF.XSweepDirection.Counterclockwise); startPoint = arcSegment.Point; #else // TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves. startPoint = arcSegment.Point; #endif } else if (segment is ICubicBezierSegment cubicBezierSegment) { gp.AddBezier( scale(startPoint.X), scale(startPoint.Y), scale(cubicBezierSegment.Point1.X), scale(cubicBezierSegment.Point1.Y), scale(cubicBezierSegment.Point2.X), scale(cubicBezierSegment.Point2.Y), scale(cubicBezierSegment.Point3.X), scale(cubicBezierSegment.Point3.Y)); startPoint = cubicBezierSegment.Point3; } else if (segment is ILineSegment) { var lineSegment = segment as ILineSegment; gp.AddLine( scale(startPoint.X), scale(startPoint.Y), scale(lineSegment.Point.X), scale(lineSegment.Point.Y)); startPoint = lineSegment.Point; } else if (segment is IQuadraticBezierSegment quadraticBezierSegment) { 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), scale(y1), scale(x2), scale(y2), scale(x3), scale(y3), scale(x4), scale(y4)); startPoint = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (pf.IsClosed) { gp.CloseFigure(); } else { gp.StartFigure(); } } return(gp); }
public static AM.StreamGeometry ToStreamGeometry(IPathGeometry xpg) { var sg = new AM.StreamGeometry(); using (var sgc = sg.Open()) { IPointShape previous = default; sgc.SetFillRule(xpg.FillRule == FillRule.Nonzero ? AM.FillRule.NonZero : AM.FillRule.EvenOdd); foreach (var xpf in xpg.Figures) { sgc.BeginFigure(new A.Point(xpf.StartPoint.X, xpf.StartPoint.Y), false); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is IArcSegment arcSegment) { sgc.ArcTo( new A.Point(arcSegment.Point.X, arcSegment.Point.Y), new A.Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? AM.SweepDirection.Clockwise : AM.SweepDirection.CounterClockwise); previous = arcSegment.Point; } else if (segment is ICubicBezierSegment cubicBezierSegment) { sgc.CubicBezierTo( new A.Point(cubicBezierSegment.Point1.X, cubicBezierSegment.Point1.Y), new A.Point(cubicBezierSegment.Point2.X, cubicBezierSegment.Point2.Y), new A.Point(cubicBezierSegment.Point3.X, cubicBezierSegment.Point3.Y)); previous = cubicBezierSegment.Point3; } else if (segment is ILineSegment lineSegment) { sgc.LineTo( new A.Point(lineSegment.Point.X, lineSegment.Point.Y)); previous = lineSegment.Point; } else if (segment is IQuadraticBezierSegment quadraticBezierSegment) { sgc.QuadraticBezierTo( new A.Point( quadraticBezierSegment.Point1.X, quadraticBezierSegment.Point1.Y), new A.Point( quadraticBezierSegment.Point2.X, quadraticBezierSegment.Point2.Y)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } sgc.EndFigure(xpf.IsClosed); } } return(sg); }
public static string ToSource(IPathGeometry xpg) { return(ToStreamGeometry(xpg).ToString()); }
public static AM.Geometry ToGeometry(IPathGeometry xpg) { return(ToStreamGeometry(xpg)); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public WM.PathGeometry ToPathGeometry(IPathGeometry xpg, double dx, double dy) { return(WM.PathGeometry.CreateFromGeometry(ToStreamGeometry(xpg, dx, dy))); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static SKPath ToSKPath(this IPathGeometry xpg, double dx, double dy, Func <double, float> scale) { var path = new SKPath { FillType = xpg.FillRule == FillRule.EvenOdd ? SKPathFillType.EvenOdd : SKPathFillType.Winding }; foreach (var xpf in xpg.Figures) { IPointShape previous = default; // Begin new figure. path.MoveTo( scale(xpf.StartPoint.X + dx), scale(xpf.StartPoint.Y + dy)); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is ArcSegment arcSegment) { path.ArcTo( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height), (float)arcSegment.RotationAngle, arcSegment.IsLargeArc ? SKPathArcSize.Large : SKPathArcSize.Small, arcSegment.SweepDirection == SweepDirection.Clockwise ? SKPathDirection.Clockwise : SKPathDirection.CounterClockwise, scale(arcSegment.Point.X + dx), scale(arcSegment.Point.Y + dy)); previous = arcSegment.Point; } else if (segment is CubicBezierSegment cubicBezierSegment) { path.CubicTo( 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)); previous = cubicBezierSegment.Point3; } else if (segment is LineSegment lineSegment) { path.LineTo( scale(lineSegment.Point.X + dx), scale(lineSegment.Point.Y + dy)); previous = lineSegment.Point; } else if (segment is PolyCubicBezierSegment polyCubicBezierSegment) { if (polyCubicBezierSegment.Points.Length >= 3) { path.CubicTo( 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)); previous = polyCubicBezierSegment.Points[2]; } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { path.CubicTo( 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)); previous = polyCubicBezierSegment.Points[i + 2]; } } } else if (segment is PolyLineSegment polyLineSegment) { if (polyLineSegment.Points.Length >= 1) { path.LineTo( scale(polyLineSegment.Points[0].X + dx), scale(polyLineSegment.Points[0].Y + dy)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { path.LineTo( scale(polyLineSegment.Points[i].X + dx), scale(polyLineSegment.Points[i].Y + dy)); previous = polyLineSegment.Points[i]; } } } else if (segment is PolyQuadraticBezierSegment polyQuadraticSegment) { if (polyQuadraticSegment.Points.Length >= 2) { path.QuadTo( scale(polyQuadraticSegment.Points[0].X + dx), scale(polyQuadraticSegment.Points[0].Y + dy), scale(polyQuadraticSegment.Points[1].X + dx), scale(polyQuadraticSegment.Points[1].Y + dy)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { path.QuadTo( scale(polyQuadraticSegment.Points[i].X + dx), scale(polyQuadraticSegment.Points[i].Y + dy), scale(polyQuadraticSegment.Points[i + 1].X + dx), scale(polyQuadraticSegment.Points[i + 1].Y + dy)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is QuadraticBezierSegment quadraticBezierSegment) { path.QuadTo( scale(quadraticBezierSegment.Point1.X + dx), scale(quadraticBezierSegment.Point1.Y + dy), scale(quadraticBezierSegment.Point2.X + dx), scale(quadraticBezierSegment.Point2.Y + dy)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (xpf.IsClosed) { path.Close(); } } return(path); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public string ToSource(IPathGeometry xpg) { return(ToStreamGeometry(xpg, 0.0, 0.0).ToString(CultureInfo.InvariantCulture)); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public AM.StreamGeometry ToStreamGeometry(IPathGeometry xpg, double dx, double dy) { var sg = new AM.StreamGeometry(); using (var sgc = sg.Open()) { IPointShape previous = default; sgc.SetFillRule(xpg.FillRule == FillRule.Nonzero ? AM.FillRule.NonZero : AM.FillRule.EvenOdd); foreach (var xpf in xpg.Figures) { sgc.BeginFigure(new A.Point(xpf.StartPoint.X + dx, xpf.StartPoint.Y + dy), xpf.IsFilled); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is IArcSegment arcSegment) { sgc.ArcTo( new A.Point(arcSegment.Point.X + dx, arcSegment.Point.Y + dy), new A.Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? AM.SweepDirection.Clockwise : AM.SweepDirection.CounterClockwise); previous = arcSegment.Point; } else if (segment is ICubicBezierSegment cubicBezierSegment) { sgc.CubicBezierTo( new A.Point(cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy), new A.Point(cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy), new A.Point(cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy)); previous = cubicBezierSegment.Point3; } else if (segment is ILineSegment lineSegment) { sgc.LineTo( new A.Point(lineSegment.Point.X + dx, lineSegment.Point.Y + dy)); previous = lineSegment.Point; } else if (segment is IPolyCubicBezierSegment polyCubicBezierSegment) { if (polyCubicBezierSegment.Points.Length >= 3) { sgc.CubicBezierTo( new A.Point( polyCubicBezierSegment.Points[0].X + dx, polyCubicBezierSegment.Points[0].Y + dy), new A.Point( polyCubicBezierSegment.Points[1].X + dx, polyCubicBezierSegment.Points[1].Y + dy), new A.Point( polyCubicBezierSegment.Points[2].X + dx, polyCubicBezierSegment.Points[2].Y + dy)); previous = polyCubicBezierSegment.Points[2]; } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { sgc.CubicBezierTo( new A.Point( polyCubicBezierSegment.Points[i].X + dx, polyCubicBezierSegment.Points[i].Y + dy), new A.Point( polyCubicBezierSegment.Points[i + 1].X + dx, polyCubicBezierSegment.Points[i + 1].Y + dy), new A.Point( polyCubicBezierSegment.Points[i + 2].X + dx, polyCubicBezierSegment.Points[i + 2].Y + dy)); previous = polyCubicBezierSegment.Points[i + 2]; } } } else if (segment is IPolyLineSegment polyLineSegment) { if (polyLineSegment.Points.Length >= 1) { sgc.LineTo( new A.Point( polyLineSegment.Points[0].X + dx, polyLineSegment.Points[0].Y + dy)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { sgc.LineTo( new A.Point( polyLineSegment.Points[i].X + dx, polyLineSegment.Points[i].Y + dy)); previous = polyLineSegment.Points[i]; } } } else if (segment is IPolyQuadraticBezierSegment polyQuadraticSegment) { if (polyQuadraticSegment.Points.Length >= 2) { sgc.QuadraticBezierTo( new A.Point( polyQuadraticSegment.Points[0].X + dx, polyQuadraticSegment.Points[0].Y + dy), new A.Point( polyQuadraticSegment.Points[1].X + dx, polyQuadraticSegment.Points[1].Y + dy)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { sgc.QuadraticBezierTo( new A.Point( polyQuadraticSegment.Points[i].X + dx, polyQuadraticSegment.Points[i].Y + dy), new A.Point( polyQuadraticSegment.Points[i + 1].X + dx, polyQuadraticSegment.Points[i + 1].Y + dy)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is IQuadraticBezierSegment quadraticBezierSegment) { sgc.QuadraticBezierTo( new A.Point( quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy), new A.Point( quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } sgc.EndFigure(xpf.IsClosed); } } return(sg); }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static PDF.XGraphicsPath ToXGraphicsPath(this IPathGeometry pg, double dx, double dy, Func <double, double> scale) { var gp = new PDF.XGraphicsPath() { FillMode = pg.FillRule == FillRule.EvenOdd ? PDF.XFillMode.Alternate : PDF.XFillMode.Winding }; foreach (var pf in pg.Figures) { var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is IArcSegment arcSegment) { #if WPF var point1 = new PDF.XPoint( scale(startPoint.X + dx), scale(startPoint.Y + dy)); var point2 = new PDF.XPoint( scale(arcSegment.Point.X + dx), scale(arcSegment.Point.Y + dy)); var size = new PDF.XSize( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height)); gp.AddArc( point1, point2, size, arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? PDF.XSweepDirection.Clockwise : PDF.XSweepDirection.Counterclockwise); startPoint = arcSegment.Point; #else throw new NotSupportedException("Not supported segment type: " + segment.GetType()); // TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves. //startPoint = arcSegment.Point; #endif } else if (segment is ICubicBezierSegment cubicBezierSegment) { 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 ILineSegment) { var lineSegment = segment as ILineSegment; 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 IPolyCubicBezierSegment polyCubicBezierSegment) { 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 IPolyLineSegment polyLineSegment) { 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 IPolyQuadraticBezierSegment polyQuadraticSegment) { 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 IQuadraticBezierSegment quadraticBezierSegment) { 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); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public AM.Geometry ToGeometry(IPathGeometry xpg, double dx, double dy) { return(ToStreamGeometry(xpg, dx, dy)); }