#region PDFsharp - A .NET library for processing PDF // // Authors: // Stefan Lange // // Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany) // // http://www.PdfSharp.com // http://sourceforge.net/projects/pdfsharp // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. #endregion using System; using PdfSharpCore.Internal; namespace PdfSharpCore.Drawing { /// /// Represents a series of connected lines and curves. /// public sealed class XGraphicsPath { /// /// Initializes a new instance of the class. /// public XGraphicsPath() { _corePath = new CoreGraphicsPath(); } /// /// Clones this instance. /// public XGraphicsPath Clone() { XGraphicsPath path = (XGraphicsPath)MemberwiseClone(); _corePath = new CoreGraphicsPath(_corePath); return path; } // ----- AddLine ------------------------------------------------------------------------------ /// /// Adds a line segment to current figure. /// public void AddLine(XPoint pt1, XPoint pt2) { AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y); } public void AddMove(double x1, double y1) => _corePath.MoveTo(x1, y1); /// /// Adds a line segment to current figure. /// public void AddLine(double x1, double y1, double x2, double y2) { _corePath.MoveOrLineTo(x1, y1); _corePath.LineTo(x2, y2, false); } // ----- AddLines ----------------------------------------------------------------------------- /// /// Adds a series of connected line segments to current figure. /// public void AddLines(XPoint[] points) { if (points == null) throw new ArgumentNullException("points"); int count = points.Length; if (count == 0) return; _corePath.MoveOrLineTo(points[0].X, points[0].Y); for (int idx = 1; idx < count; idx++) _corePath.LineTo(points[idx].X, points[idx].Y, false); } // ----- AddBezier ---------------------------------------------------------------------------- /// /// Adds a cubic Bézier curve to the current figure. /// public void AddBezier(XPoint pt1, XPoint pt2, XPoint pt3, XPoint pt4) { AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); } /// /// Adds a cubic Bézier curve to the current figure. /// public void AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { _corePath.MoveOrLineTo(x1, y1); _corePath.BezierTo(x2, y2, x3, y3, x4, y4, false); } // ----- AddBeziers --------------------------------------------------------------------------- /// /// Adds a sequence of connected cubic Bézier curves to the current figure. /// public void AddBeziers(XPoint[] points) { if (points == null) throw new ArgumentNullException("points"); int count = points.Length; if (count < 4) throw new ArgumentException("At least four points required for bezier curve.", "points"); if ((count - 1) % 3 != 0) throw new ArgumentException("Invalid number of points for bezier curve. Number must fulfil 4+3n.", "points"); _corePath.MoveOrLineTo(points[0].X, points[0].Y); for (int idx = 1; idx < count; idx += 3) { _corePath.BezierTo(points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y, false); } } // ----- AddCurve ----------------------------------------------------------------------- /// /// Adds a spline curve to the current figure. /// public void AddCurve(XPoint[] points) { AddCurve(points, 0.5); } /// /// Adds a spline curve to the current figure. /// public void AddCurve(XPoint[] points, double tension) { int count = points.Length; if (count < 2) throw new ArgumentException("AddCurve requires two or more points.", "points"); _corePath.AddCurve(points, tension); } /// /// Adds a spline curve to the current figure. /// public void AddCurve(XPoint[] points, int offset, int numberOfSegments, double tension) { throw new NotImplementedException("AddCurve not yet implemented."); } // ----- AddArc ------------------------------------------------------------------------------- /// /// Adds an elliptical arc to the current figure. /// public void AddArc(XRect rect, double startAngle, double sweepAngle) { AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); } /// /// Adds an elliptical arc to the current figure. /// public void AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle) { _corePath.AddArc(x, y, width, height, startAngle, sweepAngle); } /// /// Adds an elliptical arc to the current figure. The arc is specified WPF like. /// public void AddArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArg, XSweepDirection sweepDirection) { _corePath.AddArc(point1, point2, size, rotationAngle, isLargeArg, sweepDirection); } // ----- AddRectangle ------------------------------------------------------------------------- /// /// Adds a rectangle to this path. /// public void AddRectangle(XRect rect) { _corePath.MoveTo(rect.X, rect.Y); _corePath.LineTo(rect.X + rect.Width, rect.Y, false); _corePath.LineTo(rect.X + rect.Width, rect.Y + rect.Height, false); _corePath.LineTo(rect.X, rect.Y + rect.Height, true); _corePath.CloseSubpath(); } /// /// Adds a rectangle to this path. /// public void AddRectangle(double x, double y, double width, double height) { AddRectangle(new XRect(x, y, width, height)); } // ----- AddRectangles ------------------------------------------------------------------------ /// /// Adds a series of rectangles to this path. /// public void AddRectangles(XRect[] rects) { int count = rects.Length; for (int idx = 0; idx < count; idx++) { AddRectangle(rects[idx]); } } // ----- AddRoundedRectangle ------------------------------------------------------------------ /// /// Adds a rectangle with rounded corners to this path. /// public void AddRoundedRectangle(double x, double y, double width, double height, double ellipseWidth, double ellipseHeight) { double arcWidth = ellipseWidth / 2; double arcHeight = ellipseHeight / 2; _corePath.MoveTo(x + width - arcWidth, y); _corePath.QuadrantArcTo(x + width - arcWidth, y + arcHeight, arcWidth, arcHeight, 1, true); _corePath.LineTo(x + width, y + height - arcHeight, false); _corePath.QuadrantArcTo(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, 4, true); _corePath.LineTo(x + arcWidth, y + height, false); _corePath.QuadrantArcTo(x + arcWidth, y + height - arcHeight, arcWidth, arcHeight, 3, true); _corePath.LineTo(x, y + arcHeight, false); _corePath.QuadrantArcTo(x + arcWidth, y + arcHeight, arcWidth, arcHeight, 2, true); _corePath.CloseSubpath(); } // ----- AddEllipse --------------------------------------------------------------------------- /// /// Adds an ellipse to the current path. /// public void AddEllipse(XRect rect) { AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); } /// /// Adds an ellipse to the current path. /// public void AddEllipse(double x, double y, double width, double height) { double w = width / 2; double h = height / 2; double xc = x + w; double yc = y + h; _corePath.MoveTo(x + w, y); _corePath.QuadrantArcTo(xc, yc, w, h, 1, true); _corePath.QuadrantArcTo(xc, yc, w, h, 4, true); _corePath.QuadrantArcTo(xc, yc, w, h, 3, true); _corePath.QuadrantArcTo(xc, yc, w, h, 2, true); _corePath.CloseSubpath(); } // ----- AddPolygon --------------------------------------------------------------------------- /// /// Adds a polygon to this path. /// public void AddPolygon(XPoint[] points) { int count = points.Length; if (count == 0) return; _corePath.MoveTo(points[0].X, points[0].Y); for (int idx = 0; idx < count - 1; idx++) _corePath.LineTo(points[idx].X, points[idx].Y, false); _corePath.LineTo(points[count - 1].X, points[count - 1].Y, true); _corePath.CloseSubpath(); } // ----- AddPie ------------------------------------------------------------------------------- /// /// Adds the outline of a pie shape to this path. /// public void AddPie(XRect rect, double startAngle, double sweepAngle) { AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); } /// /// Adds the outline of a pie shape to this path. /// public void AddPie(double x, double y, double width, double height, double startAngle, double sweepAngle) { DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddPie"); } // ----- AddClosedCurve ------------------------------------------------------------------------ /// /// Adds a closed curve to this path. /// public void AddClosedCurve(XPoint[] points) { AddClosedCurve(points, 0.5); } /// /// Adds a closed curve to this path. /// public void AddClosedCurve(XPoint[] points, double tension) { if (points == null) throw new ArgumentNullException("points"); int count = points.Length; if (count == 0) return; if (count < 2) throw new ArgumentException("Not enough points.", "points"); DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddClosedCurve"); } // ----- AddPath ------------------------------------------------------------------------------ /// /// Adds the specified path to this path. /// public void AddPath(XGraphicsPath path, bool connect) { DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddPath"); } // ----- AddString ---------------------------------------------------------------------------- /// /// Adds a text string to this path. /// public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XPoint origin, XStringFormat format) { try { DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddString"); } catch { throw; } } /// /// Adds a text string to this path. /// public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XRect layoutRect, XStringFormat format) { if (s == null) throw new ArgumentNullException("s"); if (family == null) throw new ArgumentNullException("family"); if (format == null) format = XStringFormats.Default; if (format.LineAlignment == XLineAlignment.BaseLine && layoutRect.Height != 0) throw new InvalidOperationException( "DrawString: With XLineAlignment.BaseLine the height of the layout rectangle must be 0."); if (s.Length == 0) return; XFont font = new XFont(family.Name, emSize, style); DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddString"); } // -------------------------------------------------------------------------------------------- /// /// Closes the current figure and starts a new figure. /// public void CloseFigure() { _corePath.CloseSubpath(); } /// /// Starts a new figure without closing the current figure. /// public void StartFigure() { // TODO: ??? } // -------------------------------------------------------------------------------------------- /// /// Gets or sets an XFillMode that determines how the interiors of shapes are filled. /// public XFillMode FillMode { get { return _fillMode; } set { _fillMode = value; // Nothing to do. } } private XFillMode _fillMode; // -------------------------------------------------------------------------------------------- /// /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. /// public void Flatten() { // Just do nothing. } /// /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. /// public void Flatten(XMatrix matrix) { // Just do nothing. } /// /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. /// public void Flatten(XMatrix matrix, double flatness) { // Just do nothing. } // -------------------------------------------------------------------------------------------- /// /// Replaces this path with curves that enclose the area that is filled when this path is drawn /// by the specified pen. /// public void Widen(XPen pen) { // Just do nothing. } /// /// Replaces this path with curves that enclose the area that is filled when this path is drawn /// by the specified pen. /// public void Widen(XPen pen, XMatrix matrix) { // Just do nothing. } /// /// Replaces this path with curves that enclose the area that is filled when this path is drawn /// by the specified pen. /// public void Widen(XPen pen, XMatrix matrix, double flatness) { // Just do nothing. } /// /// Grants access to internal objects of this class. /// public XGraphicsPathInternals Internals { get { return new XGraphicsPathInternals(this); } } /// /// Gets access to underlying Core graphics path. /// internal CoreGraphicsPath _corePath; } }