435 lines
13 KiB
C#
435 lines
13 KiB
C#
#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
|
|
{
|
|
/// <summary>
|
|
/// Represents a pair of floating point x- and y-coordinates that defines a point
|
|
/// in a two-dimensional plane.
|
|
/// </summary>
|
|
[DebuggerDisplay("{DebuggerDisplay}")]
|
|
[Serializable]
|
|
[StructLayout(LayoutKind.Sequential)] // TypeConverter(typeof(PointConverter)), ValueSerializer(typeof(PointValueSerializer))]
|
|
public struct XPoint : IFormattable
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the XPoint class with the specified coordinates.
|
|
/// </summary>
|
|
public XPoint(double x, double y)
|
|
{
|
|
_x = x;
|
|
_y = y;
|
|
}
|
|
|
|
#if GDI
|
|
/// <summary>
|
|
/// Initializes a new instance of the XPoint class with the specified point.
|
|
/// </summary>
|
|
public XPoint(System.Drawing.Point point)
|
|
{
|
|
_x = point.X;
|
|
_y = point.Y;
|
|
}
|
|
#endif
|
|
|
|
#if WPF || NETFX_CORE
|
|
/// <summary>
|
|
/// Initializes a new instance of the XPoint class with the specified point.
|
|
/// </summary>
|
|
public XPoint(SysPoint point)
|
|
{
|
|
_x = point.X;
|
|
_y = point.Y;
|
|
}
|
|
#endif
|
|
|
|
#if GDI
|
|
/// <summary>
|
|
/// Initializes a new instance of the XPoint class with the specified point.
|
|
/// </summary>
|
|
public XPoint(PointF point)
|
|
{
|
|
_x = point.X;
|
|
_y = point.Y;
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Determines whether two points are equal.
|
|
/// </summary>
|
|
public static bool operator ==(XPoint point1, XPoint point2)
|
|
{
|
|
// ReSharper disable CompareOfFloatsByEqualityOperator
|
|
return point1._x == point2._x && point1._y == point2._y;
|
|
// ReSharper restore CompareOfFloatsByEqualityOperator
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether two points are not equal.
|
|
/// </summary>
|
|
public static bool operator !=(XPoint point1, XPoint point2)
|
|
{
|
|
return !(point1 == point2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether the specified points are equal.
|
|
/// </summary>
|
|
public static bool Equals(XPoint point1, XPoint point2)
|
|
{
|
|
return point1.X.Equals(point2.X) && point1.Y.Equals(point2.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether this instance and a specified object are equal.
|
|
/// </summary>
|
|
public override bool Equals(object o)
|
|
{
|
|
if (!(o is XPoint))
|
|
return false;
|
|
return Equals(this, (XPoint)o);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether this instance and a specified point are equal.
|
|
/// </summary>
|
|
public bool Equals(XPoint value)
|
|
{
|
|
return Equals(this, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the hash code for this instance.
|
|
/// </summary>
|
|
public override int GetHashCode()
|
|
{
|
|
return X.GetHashCode() ^ Y.GetHashCode();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses the point from a string.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses an array of points from a string.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the x-coordinate of this XPoint.
|
|
/// </summary>
|
|
public double X
|
|
{
|
|
get { return _x; }
|
|
set { _x = value; }
|
|
}
|
|
double _x;
|
|
|
|
/// <summary>
|
|
/// Gets the x-coordinate of this XPoint.
|
|
/// </summary>
|
|
public double Y
|
|
{
|
|
get { return _y; }
|
|
set { _y = value; }
|
|
}
|
|
double _y;
|
|
|
|
#if CORE
|
|
#if UseGdiObjects
|
|
/// <summary>
|
|
/// Converts this XPoint to a System.Drawing.Point.
|
|
/// </summary>
|
|
public PointF ToPointF()
|
|
{
|
|
return new PointF((float)_x, (float)_y);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if GDI
|
|
/// <summary>
|
|
/// Converts this XPoint to a System.Drawing.Point.
|
|
/// </summary>
|
|
public PointF ToPointF()
|
|
{
|
|
return new PointF((float)_x, (float)_y);
|
|
}
|
|
#endif
|
|
|
|
#if WPF || NETFX_CORE
|
|
/// <summary>
|
|
/// Converts this XPoint to a System.Windows.Point.
|
|
/// </summary>
|
|
public SysPoint ToPoint()
|
|
{
|
|
return new SysPoint(_x, _y);
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Converts this XPoint to a human readable string.
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
return ConvertToString(null, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts this XPoint to a human readable string.
|
|
/// </summary>
|
|
public string ToString(IFormatProvider provider)
|
|
{
|
|
return ConvertToString(null, provider);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts this XPoint to a human readable string.
|
|
/// </summary>
|
|
string IFormattable.ToString(string format, IFormatProvider provider)
|
|
{
|
|
return ConvertToString(format, provider);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implements ToString.
|
|
/// </summary>
|
|
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 });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Offsets the x and y value of this point.
|
|
/// </summary>
|
|
public void Offset(double offsetX, double offsetY)
|
|
{
|
|
_x += offsetX;
|
|
_y += offsetY;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a point and a vector.
|
|
/// </summary>
|
|
public static XPoint operator +(XPoint point, XVector vector)
|
|
{
|
|
return new XPoint(point._x + vector.X, point._y + vector.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a point and a size.
|
|
/// </summary>
|
|
public static XPoint operator +(XPoint point, XSize size) // TODO: make obsolete
|
|
{
|
|
return new XPoint(point._x + size.Width, point._y + size.Height);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a point and a vector.
|
|
/// </summary>
|
|
public static XPoint Add(XPoint point, XVector vector)
|
|
{
|
|
return new XPoint(point._x + vector.X, point._y + vector.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subtracts a vector from a point.
|
|
/// </summary>
|
|
public static XPoint operator -(XPoint point, XVector vector)
|
|
{
|
|
return new XPoint(point._x - vector.X, point._y - vector.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subtracts a vector from a point.
|
|
/// </summary>
|
|
public static XPoint Subtract(XPoint point, XVector vector)
|
|
{
|
|
return new XPoint(point._x - vector.X, point._y - vector.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subtracts a point from a point.
|
|
/// </summary>
|
|
public static XVector operator -(XPoint point1, XPoint point2)
|
|
{
|
|
return new XVector(point1._x - point2._x, point1._y - point2._y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subtracts a size from a point.
|
|
/// </summary>
|
|
[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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Subtracts a point from a point.
|
|
/// </summary>
|
|
public static XVector Subtract(XPoint point1, XPoint point2)
|
|
{
|
|
return new XVector(point1._x - point2._x, point1._y - point2._y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Multiplies a point with a matrix.
|
|
/// </summary>
|
|
public static XPoint operator *(XPoint point, XMatrix matrix)
|
|
{
|
|
return matrix.Transform(point);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Multiplies a point with a matrix.
|
|
/// </summary>
|
|
public static XPoint Multiply(XPoint point, XMatrix matrix)
|
|
{
|
|
return matrix.Transform(point);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Multiplies a point with a scalar value.
|
|
/// </summary>
|
|
public static XPoint operator *(XPoint point, double value)
|
|
{
|
|
return new XPoint(point._x * value, point._y * value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Multiplies a point with a scalar value.
|
|
/// </summary>
|
|
public static XPoint operator *(double value, XPoint point)
|
|
{
|
|
return new XPoint(value * point._x, value * point._y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs an explicit conversion from XPoint to XSize.
|
|
/// </summary>
|
|
public static explicit operator XSize(XPoint point)
|
|
{
|
|
return new XSize(Math.Abs(point._x), Math.Abs(point._y));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs an explicit conversion from XPoint to XVector.
|
|
/// </summary>
|
|
public static explicit operator XVector(XPoint point)
|
|
{
|
|
return new XVector(point._x, point._y);
|
|
}
|
|
|
|
#if WPF || NETFX_CORE
|
|
/// <summary>
|
|
/// Performs an implicit conversion from XPoint to Point.
|
|
/// </summary>
|
|
public static implicit operator SysPoint(XPoint point)
|
|
{
|
|
return new SysPoint(point.X, point.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs an implicit conversion from Point to XPoint.
|
|
/// </summary>
|
|
public static implicit operator XPoint(SysPoint point)
|
|
{
|
|
return new XPoint(point.X, point.Y);
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Gets the DebuggerDisplayAttribute text.
|
|
/// </summary>
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
}
|