#region PDFsharp - A .NET library for processing PDF // // Authors: // Stefan Lange // // Copyright (c) 2005-2017 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 System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; #if CORE #endif #if GDI using System.Drawing; #endif #if WPF using System.Windows; using SysPoint = System.Windows.Point; using SysSize = System.Windows.Size; #endif #if NETFX_CORE using Windows.UI.Xaml.Media; using SysPoint = Windows.Foundation.Point; using SysSize = Windows.Foundation.Size; #endif #if !EDF_CORE using PdfSharp.Internal; #else using PdfSharp.Internal; #endif #if !EDF_CORE namespace PdfSharp.Drawing #else namespace Edf.Drawing #endif { /// /// Represents a pair of floating point x- and y-coordinates that defines a point /// in a two-dimensional plane. /// [DebuggerDisplay("{DebuggerDisplay}")] [Serializable] [StructLayout(LayoutKind.Sequential)] // TypeConverter(typeof(PointConverter)), ValueSerializer(typeof(PointValueSerializer))] public struct XPoint : IFormattable { /// /// Initializes a new instance of the XPoint class with the specified coordinates. /// public XPoint(double x, double y) { _x = x; _y = y; } #if GDI /// /// Initializes a new instance of the XPoint class with the specified point. /// public XPoint(System.Drawing.Point point) { _x = point.X; _y = point.Y; } #endif #if WPF || NETFX_CORE /// /// Initializes a new instance of the XPoint class with the specified point. /// public XPoint(SysPoint point) { _x = point.X; _y = point.Y; } #endif #if GDI /// /// Initializes a new instance of the XPoint class with the specified point. /// public XPoint(PointF point) { _x = point.X; _y = point.Y; } #endif /// /// Determines whether two points are equal. /// public static bool operator ==(XPoint point1, XPoint point2) { // ReSharper disable CompareOfFloatsByEqualityOperator return point1._x == point2._x && point1._y == point2._y; // ReSharper restore CompareOfFloatsByEqualityOperator } /// /// Determines whether two points are not equal. /// public static bool operator !=(XPoint point1, XPoint point2) { return !(point1 == point2); } /// /// Indicates whether the specified points are equal. /// public static bool Equals(XPoint point1, XPoint point2) { return point1.X.Equals(point2.X) && point1.Y.Equals(point2.Y); } /// /// Indicates whether this instance and a specified object are equal. /// public override bool Equals(object o) { if (!(o is XPoint)) return false; return Equals(this, (XPoint)o); } /// /// Indicates whether this instance and a specified point are equal. /// public bool Equals(XPoint value) { return Equals(this, value); } /// /// Returns the hash code for this instance. /// public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); } /// /// Parses the point from a string. /// public static XPoint Parse(string source) { CultureInfo cultureInfo = CultureInfo.InvariantCulture; TokenizerHelper helper = new TokenizerHelper(source, cultureInfo); string str = helper.NextTokenRequired(); XPoint point = new XPoint(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo)); helper.LastTokenRequired(); return point; } /// /// Parses an array of points from a string. /// public static XPoint[] ParsePoints(string value) { if (value == null) throw new ArgumentNullException("value"); // TODO: Reflect reliabel implementation from Avalon // TODOWPF string[] values = value.Split(' '); int count = values.Length; XPoint[] points = new XPoint[count]; for (int idx = 0; idx < count; idx++) points[idx] = Parse(values[idx]); return points; } /// /// Gets the x-coordinate of this XPoint. /// public double X { get { return _x; } set { _x = value; } } double _x; /// /// Gets the x-coordinate of this XPoint. /// public double Y { get { return _y; } set { _y = value; } } double _y; #if CORE #if UseGdiObjects /// /// Converts this XPoint to a System.Drawing.Point. /// public PointF ToPointF() { return new PointF((float)_x, (float)_y); } #endif #endif #if GDI /// /// Converts this XPoint to a System.Drawing.Point. /// public PointF ToPointF() { return new PointF((float)_x, (float)_y); } #endif #if WPF || NETFX_CORE /// /// Converts this XPoint to a System.Windows.Point. /// public SysPoint ToPoint() { return new SysPoint(_x, _y); } #endif /// /// Converts this XPoint to a human readable string. /// public override string ToString() { return ConvertToString(null, null); } /// /// Converts this XPoint to a human readable string. /// public string ToString(IFormatProvider provider) { return ConvertToString(null, provider); } /// /// Converts this XPoint to a human readable string. /// string IFormattable.ToString(string format, IFormatProvider provider) { return ConvertToString(format, provider); } /// /// Implements ToString. /// internal string ConvertToString(string format, IFormatProvider provider) { char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider); provider = provider ?? CultureInfo.InvariantCulture; return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}", new object[] { numericListSeparator, _x, _y }); } /// /// Offsets the x and y value of this point. /// public void Offset(double offsetX, double offsetY) { _x += offsetX; _y += offsetY; } /// /// Adds a point and a vector. /// public static XPoint operator +(XPoint point, XVector vector) { return new XPoint(point._x + vector.X, point._y + vector.Y); } /// /// Adds a point and a size. /// public static XPoint operator +(XPoint point, XSize size) // TODO: make obsolete { return new XPoint(point._x + size.Width, point._y + size.Height); } /// /// Adds a point and a vector. /// public static XPoint Add(XPoint point, XVector vector) { return new XPoint(point._x + vector.X, point._y + vector.Y); } /// /// Subtracts a vector from a point. /// public static XPoint operator -(XPoint point, XVector vector) { return new XPoint(point._x - vector.X, point._y - vector.Y); } /// /// Subtracts a vector from a point. /// public static XPoint Subtract(XPoint point, XVector vector) { return new XPoint(point._x - vector.X, point._y - vector.Y); } /// /// Subtracts a point from a point. /// public static XVector operator -(XPoint point1, XPoint point2) { return new XVector(point1._x - point2._x, point1._y - point2._y); } /// /// Subtracts a size from a point. /// [Obsolete("Use XVector instead of XSize as second parameter.")] public static XPoint operator -(XPoint point, XSize size) // TODO: make obsolete { return new XPoint(point._x - size.Width, point._y - size.Height); } /// /// Subtracts a point from a point. /// public static XVector Subtract(XPoint point1, XPoint point2) { return new XVector(point1._x - point2._x, point1._y - point2._y); } /// /// Multiplies a point with a matrix. /// public static XPoint operator *(XPoint point, XMatrix matrix) { return matrix.Transform(point); } /// /// Multiplies a point with a matrix. /// public static XPoint Multiply(XPoint point, XMatrix matrix) { return matrix.Transform(point); } /// /// Multiplies a point with a scalar value. /// public static XPoint operator *(XPoint point, double value) { return new XPoint(point._x * value, point._y * value); } /// /// Multiplies a point with a scalar value. /// public static XPoint operator *(double value, XPoint point) { return new XPoint(value * point._x, value * point._y); } /// /// Performs an explicit conversion from XPoint to XSize. /// public static explicit operator XSize(XPoint point) { return new XSize(Math.Abs(point._x), Math.Abs(point._y)); } /// /// Performs an explicit conversion from XPoint to XVector. /// public static explicit operator XVector(XPoint point) { return new XVector(point._x, point._y); } #if WPF || NETFX_CORE /// /// Performs an implicit conversion from XPoint to Point. /// public static implicit operator SysPoint(XPoint point) { return new SysPoint(point.X, point.Y); } /// /// Performs an implicit conversion from Point to XPoint. /// public static implicit operator XPoint(SysPoint point) { return new XPoint(point.X, point.Y); } #endif /// /// Gets the DebuggerDisplayAttribute text. /// // ReSharper disable UnusedMember.Local string DebuggerDisplay // ReSharper restore UnusedMember.Local { get { const string format = Config.SignificantFigures10; return String.Format(CultureInfo.InvariantCulture, "point=({0:" + format + "}, {1:" + format + "})", _x, _y); } } } }