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); }
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 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); }
/// <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> /// 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); }