private static IEnumerable <IPathShape> BreakInternal(IPathShape shape, IEnumerable <double> vs) { var u = 0D; var any = false; foreach (var t in vs) { var r = Utils.Map(t, u, 1, 0, 1); var items = shape.Break(r); if (items == null) { break; } u += t; any = true; shape = items.Right; yield return(items.Left); } if (any) { yield return(shape); } }
public virtual double GetAutoOrientAngle(MarkerSvgNodeRenderer marker, bool reverse) { Object[] pathShapes = GetShapes().ToArray(); if (pathShapes.Length > 1) { Vector v = new Vector(0, 0, 0); if (SvgConstants.Attributes.MARKER_END.Equals(marker.attributesAndStyles.Get(SvgConstants.Tags.MARKER))) { // Create vector from the last two shapes IPathShape lastShape = (IPathShape)pathShapes[pathShapes.Length - 1]; IPathShape secondToLastShape = (IPathShape)pathShapes[pathShapes.Length - 2]; v = new Vector((float)(lastShape.GetEndingPoint().GetX() - secondToLastShape.GetEndingPoint().GetX()), (float )(lastShape.GetEndingPoint().GetY() - secondToLastShape.GetEndingPoint().GetY()), 0f); } else { if (SvgConstants.Attributes.MARKER_START.Equals(marker.attributesAndStyles.Get(SvgConstants.Tags.MARKER))) { // Create vector from the first two shapes IPathShape firstShape = (IPathShape)pathShapes[0]; IPathShape secondShape = (IPathShape)pathShapes[1]; v = new Vector((float)(secondShape.GetEndingPoint().GetX() - firstShape.GetEndingPoint().GetX()), (float)( secondShape.GetEndingPoint().GetY() - firstShape.GetEndingPoint().GetY()), 0f); } } // Get angle from this vector and the horizontal axis Vector xAxis = new Vector(1, 0, 0); double rotAngle = SvgCoordinateUtils.CalculateAngleBetweenTwoVectors(xAxis, v); return(v.Get(1) >= 0 && !reverse ? rotAngle : rotAngle * -1f); } return(0); }
private IList <IPathShape> AddMoveToShapes(IPathShape pathShape, String[] pathProperties) { IList <IPathShape> shapes = new List <IPathShape>(); int argumentCount = 2; String[] shapeCoordinates = GetShapeCoordinates(pathShape, null, JavaUtil.ArraysCopyOfRange(pathProperties , 1, 3)); zOperator = new ClosePath(pathShape.IsRelative()); zOperator.SetCoordinates(shapeCoordinates, currentPoint); pathShape.SetCoordinates(shapeCoordinates, currentPoint); currentPoint = pathShape.GetEndingPoint(); shapes.Add(pathShape); IPathShape previousShape = pathShape; if (pathProperties.Length > 3) { for (int index = 3; index < pathProperties.Length; index += argumentCount) { if (index + 2 > pathProperties.Length) { break; } pathShape = pathShape.IsRelative() ? SvgPathShapeFactory.CreatePathShape("l") : SvgPathShapeFactory.CreatePathShape ("L"); shapeCoordinates = GetShapeCoordinates(pathShape, previousShape, JavaUtil.ArraysCopyOfRange(pathProperties , index, index + 2)); pathShape.SetCoordinates(shapeCoordinates, previousShape.GetEndingPoint()); shapes.Add(pathShape); previousShape = pathShape; } } return(shapes); }
/// <summary> /// Initialize new instance of <see cref="ToolPathSelection"/> class. /// </summary> /// <param name="layer">The selection shapes layer.</param> /// <param name="shape">The selected shape.</param> /// <param name="style">The selection shapes style.</param> /// <param name="point">The selection point shape.</param> public ToolPathSelection(ILayerContainer layer, IPathShape shape, IShapeStyle style, IBaseShape point) { _layer = layer; _path = shape; _style = style; _point = point; }
public bool BreakPathShape(IPathShape pathShape, List <IBaseShape> result) { var factory = _serviceProvider.GetService <IFactory>(); if (pathShape.Geometry.Figures.Length == 1) { BreakPathFigure(pathShape.Geometry.Figures[0], pathShape.Style, pathShape.IsStroked, pathShape.IsFilled, result); return(true); } else if (pathShape.Geometry.Figures.Length > 1) { foreach (var pathFigure in pathShape.Geometry.Figures) { var style = pathShape.Style != null ? (IShapeStyle)pathShape.Style?.Copy(null) : factory.CreateShapeStyle(ProjectEditorConfiguration.DefaulStyleName); var convertedGeometry = factory.CreatePathGeometry(ImmutableArray.Create <IPathFigure>(), pathShape.Geometry.FillRule); convertedGeometry.Figures = convertedGeometry.Figures.Add(pathFigure); var convertedPathShape = factory.CreatePathShape( pathShape.Name, style, convertedGeometry, pathShape.IsStroked, pathShape.IsFilled); result.Add(convertedPathShape); } return(true); } return(false); }
public virtual void TestAbsoluteArcOperatorCoordinates() { PathSvgNodeRenderer path = new PathSvgNodeRenderer(); String instructions = "M 200,300 A 10 10 0 0 0 210 310"; path.SetAttribute(SvgConstants.Attributes.D, instructions); IPathShape arc = ((IList <IPathShape>)path.GetShapes())[1]; Point end = arc.GetEndingPoint(); NUnit.Framework.Assert.AreEqual(new Point(210, 310), end); }
/// <summary> /// Processes the /// <see cref="iText.Svg.SvgConstants.Attributes.D"/> /// /// <see cref="AbstractSvgNodeRenderer.attributesAndStyles"/> /// and converts them /// into one or more /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// objects to be drawn on the canvas. /// <para /> /// Each individual operator is passed to /// <see cref="ProcessPathOperator(System.String[], iText.Svg.Renderers.Path.IPathShape)"/> /// to be processed individually. /// </summary> /// <returns> /// a /// <see cref="System.Collections.ICollection{E}"/> /// of each /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// that should be drawn to represent the path. /// </returns> internal virtual ICollection <IPathShape> GetShapes() { ICollection <String> parsedResults = ParsePathOperations(); IList <IPathShape> shapes = new List <IPathShape>(); foreach (String parsedResult in parsedResults) { String[] pathProperties = iText.IO.Util.StringUtil.Split(parsedResult, " +"); IPathShape previousShape = shapes.Count == 0 ? null : shapes[shapes.Count - 1]; IList <IPathShape> operatorShapes = ProcessPathOperator(pathProperties, previousShape); shapes.AddAll(operatorShapes); } return(shapes); }
/// <summary> /// Processes an individual pathing operator and all of its arguments, converting into one or more /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// objects. /// </summary> /// <param name="pathProperties"> /// The property operator and all arguments as a /// <see>String[]</see> /// </param> /// <param name="previousShape"> /// The previous shape which can affect the positioning of the current shape. If no previous /// shape exists /// <see langword="null"/> /// is passed. /// </param> /// <returns> /// a /// <see cref="System.Collections.IList{E}"/> /// of each /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// that should be drawn to represent the operator. /// </returns> private IList <IPathShape> ProcessPathOperator(String[] pathProperties, IPathShape previousShape) { IList <IPathShape> shapes = new List <IPathShape>(); if (pathProperties.Length == 0 || pathProperties[0].Equals(SEPARATOR)) { return(shapes); } //Implements (absolute) command value only //TODO implement relative values e. C(absolute), c(relative) IPathShape pathShape = SvgPathShapeFactory.CreatePathShape(pathProperties[0]); String[] shapeCoordinates = GetShapeCoordinates(pathShape, previousShape, pathProperties); if (pathShape is ClosePath) { if (previousShape != null) { pathShape = zOperator; } else { throw new SvgProcessingException(SvgLogMessageConstant.INVALID_CLOSEPATH_OPERATOR_USE); } } else { if (pathShape is MoveTo) { zOperator = new ClosePath(pathShape.IsRelative()); if (shapeCoordinates != null && shapeCoordinates.Length != MOVETOARGUMENTNR) { LOGGER.Warn(MessageFormatUtil.Format(SvgLogMessageConstant.PATH_WRONG_NUMBER_OF_ARGUMENTS, pathProperties[ 0], shapeCoordinates.Length, MOVETOARGUMENTNR, MOVETOARGUMENTNR)); } zOperator.SetCoordinates(shapeCoordinates, currentPoint); } } if (pathShape != null) { if (shapeCoordinates != null) { // Cast will be removed when the method is introduced in the interface pathShape.SetCoordinates(shapeCoordinates, currentPoint); } currentPoint = pathShape.GetEndingPoint(); // unsupported operators are ignored. shapes.Add(pathShape); } return(shapes); }
/// <summary> /// Processes an individual pathing operator and all of its arguments, converting into one or more /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// objects. /// </summary> /// <param name="pathProperties"> /// The property operator and all arguments as a /// <see>String[]</see> /// </param> /// <param name="previousShape"> /// The previous shape which can affect the positioning of the current shape. If no previous /// shape exists /// <see langword="null"/> /// is passed. /// </param> /// <returns> /// a /// <see cref="System.Collections.IList{E}"/> /// of each /// <see cref="iText.Svg.Renderers.Path.IPathShape"/> /// that should be drawn to represent the operator. /// </returns> private IList <IPathShape> ProcessPathOperator(String[] pathProperties, IPathShape previousShape) { IList <IPathShape> shapes = new List <IPathShape>(); if (pathProperties.Length == 0 || String.IsNullOrEmpty(pathProperties[0]) || SvgPathShapeFactory.GetArgumentCount (pathProperties[0]) < 0) { return(shapes); } int argumentCount = SvgPathShapeFactory.GetArgumentCount(pathProperties[0]); if (argumentCount == 0) { // closePath operator if (previousShape == null) { throw new SvgProcessingException(SvgLogMessageConstant.INVALID_CLOSEPATH_OPERATOR_USE); } shapes.Add(zOperator); currentPoint = zOperator.GetEndingPoint(); return(shapes); } for (int index = 1; index < pathProperties.Length; index += argumentCount) { if (index + argumentCount > pathProperties.Length) { break; } IPathShape pathShape = SvgPathShapeFactory.CreatePathShape(pathProperties[0]); if (pathShape is MoveTo) { shapes.AddAll(AddMoveToShapes(pathShape, pathProperties)); return(shapes); } String[] shapeCoordinates = GetShapeCoordinates(pathShape, previousShape, JavaUtil.ArraysCopyOfRange(pathProperties , index, index + argumentCount)); if (pathShape != null) { if (shapeCoordinates != null) { pathShape.SetCoordinates(shapeCoordinates, currentPoint); } currentPoint = pathShape.GetEndingPoint(); // unsupported operators are ignored. shapes.Add(pathShape); } previousShape = pathShape; } return(shapes); }
public static SKPath ToSKPath(this IBaseShape shape, double dx, double dy, Func <double, float> scale) { return(shape switch { ILineShape lineShape => ToSKPath(lineShape, dx, dy, scale), IRectangleShape rectangleShape => ToSKPath(rectangleShape, dx, dy, scale), IEllipseShape ellipseShape => ToSKPath(ellipseShape, dx, dy, scale), IImageShape imageShape => ToSKPath(imageShape, dx, dy, scale), IArcShape arcShape => ToSKPath(arcShape, dx, dy, scale), ICubicBezierShape cubicBezierShape => ToSKPath(cubicBezierShape, dx, dy, scale), IQuadraticBezierShape quadraticBezierShape => ToSKPath(quadraticBezierShape, dx, dy, scale), ITextShape textShape => ToSKPath(textShape, dx, dy, scale), IPathShape pathShape => ToSKPath(pathShape, dx, dy, scale), IGroupShape groupShape => ToSKPath(groupShape.Shapes, dx, dy, scale), _ => null, });
public static Pair <double>[] Intersects(this IPathShape shape, IPathShape other) { if (other is Line line) { return(shape.Intersects(line)); } else if (other is Circle circle) { return(shape.Intersects(circle)); } else if (other is Arc arc) { return(shape.Intersects(arc)); } throw new ArgumentException(); }
/// <summary> /// Gets the coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// for the current shape. /// </summary> /// <param name="shape">The current shape.</param> /// <param name="previousShape">The previous shape which can affect the coordinates of the current shape.</param> /// <param name="pathProperties"> /// The operator and all arguments as a /// <see>String[]</see> /// </param> /// <returns> /// a /// <see>String[]</see> /// of coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// </returns> private String[] GetShapeCoordinates(IPathShape shape, IPathShape previousShape, String[] pathProperties) { if (shape is ClosePath) { return(null); } String[] shapeCoordinates = null; String[] operatorArgs = JavaUtil.ArraysCopyOfRange(pathProperties, 1, pathProperties.Length); if (shape is SmoothSCurveTo) { String[] startingControlPoint = new String[2]; if (previousShape != null) { Point previousEndPoint = previousShape.GetEndingPoint(); //if the previous command was a C or S use its last control point if (((previousShape is CurveTo))) { Point lastControlPoint = ((CurveTo)previousShape).GetLastControlPoint(); float reflectedX = (float)(2 * previousEndPoint.GetX() - lastControlPoint.GetX()); float reflectedY = (float)(2 * previousEndPoint.GetY() - lastControlPoint.GetY()); startingControlPoint[0] = SvgCssUtils.ConvertFloatToString(reflectedX); startingControlPoint[1] = SvgCssUtils.ConvertFloatToString(reflectedY); } else { startingControlPoint[0] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetX()); startingControlPoint[1] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetY()); } } else { // TODO RND-951 startingControlPoint[0] = pathProperties[1]; startingControlPoint[1] = pathProperties[2]; } shapeCoordinates = Concatenate(startingControlPoint, operatorArgs); } if (shapeCoordinates == null) { shapeCoordinates = operatorArgs; } return(shapeCoordinates); }
/// <summary> /// Gets the coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// for the current shape. /// </summary> /// <param name="shape">The current shape.</param> /// <param name="previousShape">The previous shape which can affect the coordinates of the current shape.</param> /// <param name="pathProperties"> /// The operator and all arguments as a /// <see>String[]</see> /// </param> /// <returns> /// a /// <see>String[]</see> /// of coordinates that shall be passed to /// <see cref="iText.Svg.Renderers.Path.IPathShape.SetCoordinates(System.String[], iText.Kernel.Geom.Point)"/> /// </returns> private String[] GetShapeCoordinates(IPathShape shape, IPathShape previousShape, String[] pathProperties) { if (shape is ClosePath) { return(null); } String[] shapeCoordinates = null; if (shape is SmoothSCurveTo || shape is QuadraticSmoothCurveTo) { String[] startingControlPoint = new String[2]; if (previousShape != null) { Point previousEndPoint = previousShape.GetEndingPoint(); //if the previous command was a Bezier curve, use its last control point if (previousShape is IControlPointCurve) { Point lastControlPoint = ((IControlPointCurve)previousShape).GetLastControlPoint(); float reflectedX = (float)(2 * previousEndPoint.GetX() - lastControlPoint.GetX()); float reflectedY = (float)(2 * previousEndPoint.GetY() - lastControlPoint.GetY()); startingControlPoint[0] = SvgCssUtils.ConvertFloatToString(reflectedX); startingControlPoint[1] = SvgCssUtils.ConvertFloatToString(reflectedY); } else { startingControlPoint[0] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetX()); startingControlPoint[1] = SvgCssUtils.ConvertDoubleToString(previousEndPoint.GetY()); } } else { // TODO RND-951 startingControlPoint[0] = pathProperties[0]; startingControlPoint[1] = pathProperties[1]; } shapeCoordinates = Concatenate(startingControlPoint, pathProperties); } if (shapeCoordinates == null) { shapeCoordinates = pathProperties; } return(shapeCoordinates); }
/** * Get the two end points of a path. * * @param pathContext The path object. * @returns Array with 2 elements: [0] is the point object corresponding to the origin, [1] is the point object corresponding to the end. */ internal static Vector2[] FromPathEnds(IPathShape pathContext, Vector2 pathOffset = default) { Vector2[] result = null; if (pathContext is Arc) { result = Point.FromArc(pathContext as Arc); } else if (pathContext is Line line) { result = new Vector2[] { line.P1, line.P2 }; } else if (pathContext is Bezier bc) { result = new Vector2[] { bc.Points[0], bc.Points.Last() }; } if (result != null) { result = result.Select(p => p + pathOffset).ToArray(); } return(result); }
public PathDrawNode(IPathShape path, IShapeStyle style) { Style = style; Path = path; UpdateGeometry(); }
public IPathDrawNode CreatePathDrawNode(IPathShape path, IShapeStyle style) { return(new PathDrawNode(path, style)); }
public static IEnumerable <IPathShape> Break(this IPathShape shape, IEnumerable <double> vs) { return(BreakInternal(shape, vs)); }
/// <inheritdoc/> public void Bind(IPathShape path, object db, object r) { }
/// <summary> /// Initialize new instance of <see cref="ToolPathSelection"/> class. /// </summary> /// <param name="layer">The selection shapes layer.</param> /// <param name="shape">The selected shape.</param> /// <param name="style">The selection shapes style.</param> public ToolPathSelection(ILayerContainer layer, IPathShape shape, IShapeStyle style) { _layer = layer; _path = shape; _style = style; }