internal static IEnumerable <PathBezierCurveData> GetBezierCurvesForQuadratic(PDFPoint start, PathQuadraticCurve quad) { PathBezierCurveData[] all = new PathBezierCurveData[1]; try { double x1 = start.X.PointsValue + (quad.ControlPoint.X.PointsValue - start.X.PointsValue) * 2 / 3; double y1 = start.Y.PointsValue + (quad.ControlPoint.Y.PointsValue - start.Y.PointsValue) * 2 / 3; PDFPoint startHandle = new PDFPoint(x1, y1); double x2 = quad.ControlPoint.X.PointsValue + (quad.EndPoint.X.PointsValue - quad.ControlPoint.X.PointsValue) / 3; double y2 = quad.ControlPoint.Y.PointsValue + (quad.EndPoint.Y.PointsValue - quad.ControlPoint.Y.PointsValue) / 3; PDFPoint endHandle = new PDFPoint(x2, y2); PathBezierCurveData one = new PathBezierCurveData(quad.EndPoint, startHandle, endHandle, true, true); all[0] = one; } catch (Exception ex) { throw new PDFException(Errors.CouldNotBuildPathFromQuadratic, ex); } return(all); }
public void CubicCurveToWithHandleEnd(PDFPoint end, PDFPoint handleEnd) { PathBezierCurveData arc = new PathBezierCurveData(end, PDFPoint.Empty, handleEnd, false, true); CurrentPath.Add(arc); IncludeInBounds(end); IncludeInBounds(handleEnd); Cursor = end; LastHandle = handleEnd; }
public void CubicCurveTo(PDFPoint end, PDFPoint handleStart, PDFPoint handleEnd) { PathBezierCurveData arc = new PathBezierCurveData(end, handleStart, handleEnd, true, true); CurrentPath.Add(arc); IncludeInBounds(end); IncludeInBounds(handleStart); IncludeInBounds(handleEnd); Cursor = end; LastHandle = handleEnd; }
public void CubicCurveForWithHandleEnd(PDFPoint delta, PDFPoint deltaHandleEnd) { PDFPoint end = ConvertDeltaToActual(delta); PDFPoint handleEnd = ConvertDeltaToActual(deltaHandleEnd); PathBezierCurveData arc = new PathBezierCurveData(end, PDFPoint.Empty, handleEnd, false, true); CurrentPath.Add(arc); IncludeInBounds(end); IncludeInBounds(handleEnd); Cursor = end; LastHandle = handleEnd; }
internal static IEnumerable <PathBezierCurveData> GetBezierCurvesForArc(PDFPoint start, PathArcData arc) { List <PathBezierCurveData> all = new List <PathBezierCurveData>(); try { if (start == arc.EndPoint) { return(all); } if (arc.RadiusX == 0.0f && arc.RadiusY == 0.0f) { PathBezierCurveData data = new PathBezierCurveData(arc.EndPoint, start, arc.EndPoint, false, false); all.Add(data); return(all); } double sinPhi = Math.Sin(arc.XAxisRotation.PointsValue * PathDataHelper.RadiansPerDegree); double cosPhi = Math.Cos(arc.XAxisRotation.PointsValue * PathDataHelper.RadiansPerDegree); double x1dash = cosPhi * (start.X.PointsValue - arc.EndPoint.X.PointsValue) / 2.0 + sinPhi * (start.Y.PointsValue - arc.EndPoint.Y.PointsValue) / 2.0; double y1dash = -sinPhi * (start.X.PointsValue - arc.EndPoint.X.PointsValue) / 2.0 + cosPhi * (start.Y.PointsValue - arc.EndPoint.Y.PointsValue) / 2.0; double root; double numerator = arc.RadiusX.PointsValue * arc.RadiusX.PointsValue * arc.RadiusY.PointsValue * arc.RadiusY.PointsValue - arc.RadiusX.PointsValue * arc.RadiusX.PointsValue * y1dash * y1dash - arc.RadiusY.PointsValue * arc.RadiusY.PointsValue * x1dash * x1dash; double rx = arc.RadiusX.PointsValue; double ry = arc.RadiusY.PointsValue; if (numerator < 0.0) { double s = (double)Math.Sqrt(1.0 - numerator / (arc.RadiusX.PointsValue * arc.RadiusX.PointsValue * arc.RadiusY.PointsValue * arc.RadiusY.PointsValue)); rx *= s; ry *= s; root = 0.0; } else { root = ((arc.ArcSize == PathArcSize.Large && arc.ArcSweep == PathArcSweep.Positive) || (arc.ArcSize == PathArcSize.Small && arc.ArcSweep == PathArcSweep.Negative) ? -1.0 : 1.0) * Math.Sqrt(numerator / (arc.RadiusX.PointsValue * arc.RadiusX.PointsValue * y1dash * y1dash + arc.RadiusY.PointsValue * arc.RadiusY.PointsValue * x1dash * x1dash)); } double cxdash = root * rx * y1dash / ry; double cydash = -root * ry * x1dash / rx; double cx = cosPhi * cxdash - sinPhi * cydash + (start.X.PointsValue + arc.EndPoint.X.PointsValue) / 2.0; double cy = sinPhi * cxdash + cosPhi * cydash + (start.Y.PointsValue + arc.EndPoint.Y.PointsValue) / 2.0; double theta1 = PathDataHelper.CalculateVectorAngle(1.0, 0.0, (x1dash - cxdash) / rx, (y1dash - cydash) / ry); double dtheta = PathDataHelper.CalculateVectorAngle((x1dash - cxdash) / rx, (y1dash - cydash) / ry, (-x1dash - cxdash) / rx, (-y1dash - cydash) / ry); if (arc.ArcSweep == PathArcSweep.Negative && dtheta > 0) { dtheta -= 2.0 * Math.PI; } else if (arc.ArcSweep == PathArcSweep.Positive && dtheta < 0) { dtheta += 2.0 * Math.PI; } int segments = (int)Math.Ceiling((double)Math.Abs(dtheta / (Math.PI / 2.0))); double delta = dtheta / segments; double t = 8.0 / 3.0 * Math.Sin(delta / 4.0) * Math.Sin(delta / 4.0) / Math.Sin(delta / 2.0); double startX = start.X.PointsValue; double startY = start.Y.PointsValue; for (int i = 0; i < segments; ++i) { double cosTheta1 = Math.Cos(theta1); double sinTheta1 = Math.Sin(theta1); double theta2 = theta1 + delta; double cosTheta2 = Math.Cos(theta2); double sinTheta2 = Math.Sin(theta2); double endpointX = cosPhi * rx * cosTheta2 - sinPhi * ry * sinTheta2 + cx; double endpointY = sinPhi * rx * cosTheta2 + cosPhi * ry * sinTheta2 + cy; double dx1 = t * (-cosPhi * rx * sinTheta1 - sinPhi * ry * cosTheta1); double dy1 = t * (-sinPhi * rx * sinTheta1 + cosPhi * ry * cosTheta1); double dxe = t * (cosPhi * rx * sinTheta2 + sinPhi * ry * cosTheta2); double dye = t * (sinPhi * rx * sinTheta2 - cosPhi * ry * cosTheta2); PDFPoint endPoint = new PDFPoint(endpointX, endpointY); PDFPoint startHandle = new PDFPoint((startX + dx1), (startY + dy1)); PDFPoint endHandle = new PDFPoint((endpointX + dxe), (endpointY + dye)); PathBezierCurveData bezier = new PathBezierCurveData(endPoint, startHandle, endHandle, true, true); all.Add(bezier); theta1 = theta2; startX = (float)endpointX; startY = (float)endpointY; } } catch (Exception ex) { throw new PDFException(Errors.CouldNotBuildPathFromArc, ex); } return(all); }
private void RenderPathOp(PathData data, PDFPoint location, ref PDFPoint cursor) { switch (data.Type) { case PathDataType.Move: PathMoveData move = (PathMoveData)data; cursor = move.MoveTo; this.RenderMoveTo(move.MoveTo.X + location.X, move.MoveTo.Y + location.Y); break; case PathDataType.Line: PathLineData line = (PathLineData)data; cursor = line.LineTo; this.RenderLineTo(line.LineTo.X + location.X, line.LineTo.Y + location.Y); break; case PathDataType.Rect: PathRectData rect = (PathRectData)data; cursor = rect.Rect.Location; this.RenderRectangle(rect.Rect.X + location.X, rect.Rect.Y + location.Y, rect.Rect.Width, rect.Rect.Height); break; case PathDataType.SubPath: PathSubPathData sub = (PathSubPathData)data; this.RenderPathData(location, sub.InnerPath, ref cursor); break; case PathDataType.Bezier: PathBezierCurveData bez = (PathBezierCurveData)data; cursor = bez.EndPoint; if (bez.HasStartHandle && bez.HasEndHandle) { this.RenderBezierCurveTo(bez.EndPoint.X + location.X, bez.EndPoint.Y + location.Y, bez.StartHandle.X + location.X, bez.StartHandle.Y + location.Y, bez.EndHandle.X + location.X, bez.EndHandle.Y + location.Y); } else if (bez.HasStartHandle) { this.RenderBezierCurveToWithStartHandleOnly(bez.EndPoint.X + location.X, bez.EndPoint.Y + location.Y, bez.StartHandle.X + location.X, bez.StartHandle.Y + location.Y); } else if (bez.HasEndHandle) { this.RenderBezierCurveToWithEndHandleOnly(bez.EndPoint.X + location.X, bez.EndPoint.Y + location.Y, bez.EndHandle.X + location.X, bez.EndHandle.Y + location.Y); } else { this.RenderLineTo(bez.Points[2].X, bez.Points[2].Y); } break; case PathDataType.Arc: IEnumerable <PathBezierCurveData> segments; PathArcData arc = (PathArcData)data; segments = PathDataHelper.GetBezierCurvesForArc(cursor, arc); foreach (PathBezierCurveData segment in segments) { this.RenderBezierCurveTo(segment.EndPoint.X + location.X, segment.EndPoint.Y + location.Y, segment.StartHandle.X + location.X, segment.StartHandle.Y + location.Y, segment.EndHandle.X + location.X, segment.EndHandle.Y + location.Y); } cursor = arc.EndPoint; break; case PathDataType.Quadratic: IEnumerable <PathBezierCurveData> quadSegments; PathQuadraticCurve quad = (PathQuadraticCurve)data; quadSegments = PathDataHelper.GetBezierCurvesForQuadratic(cursor, quad); foreach (PathBezierCurveData quadSeg in quadSegments) { this.RenderBezierCurveTo(quadSeg.EndPoint.X + location.X, quadSeg.EndPoint.Y + location.Y, quadSeg.StartHandle.X + location.X, quadSeg.StartHandle.Y + location.Y, quadSeg.EndHandle.X + location.X, quadSeg.EndHandle.Y + location.Y); } cursor = quad.EndPoint; break; case PathDataType.Close: this.RenderClosePathOp(); cursor = PDFPoint.Empty; break; default: throw new ArgumentOutOfRangeException("data.Type"); } }