diff --git a/src/SixLabors.Primitives/ApproximateFloatComparer.cs b/src/SixLabors.Primitives/ApproximateFloatComparer.cs deleted file mode 100644 index 9722508a46..0000000000 --- a/src/SixLabors.Primitives/ApproximateFloatComparer.cs +++ /dev/null @@ -1,209 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -using System; -using System.Collections.Generic; -using System.Numerics; - -namespace SixLabors.Primitives -{ - internal struct ApproximateFloatComparer - : IEqualityComparer, - IEqualityComparer, - IEqualityComparer, - IEqualityComparer, - IEqualityComparer, - IEqualityComparer, - IEqualityComparer - { - private readonly float tolerance; - const float defaultTolerance = 1e-5f; - - public ApproximateFloatComparer(float tolerance = defaultTolerance) - { - this.tolerance = tolerance; - } - - public static bool Equal(float x, float y, float tolerance) - { - float d = x - y; - - return d > -tolerance && d < tolerance; - } - - public static bool Equal(float x, float y) - { - return Equal(x, y, defaultTolerance); - } - - public bool Equals(float x, float y) - { - return Equal(x, y, this.tolerance); - } - - public int GetHashCode(float obj) - { - var diff = obj % this.tolerance;// how different from tollerance are we? - return (obj - diff).GetHashCode(); - } - - public bool Equals(Vector4 a, Vector4 b) - { - return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z) && this.Equals(a.W, b.W); - } - - public int GetHashCode(Vector4 obj) - { - int hash = GetHashCode(obj.X); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Y)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Z)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.W)); - return hash; - } - - public bool Equals(Vector2 a, Vector2 b) - { - return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y); - } - - public int GetHashCode(Vector2 obj) - { - int hash = GetHashCode(obj.X); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Y)); - return hash; - } - - public bool Equals(Vector3 a, Vector3 b) - { - return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z); - } - - public int GetHashCode(Vector3 obj) - { - int hash = GetHashCode(obj.X); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Y)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Z)); - return hash; - } - - public static bool Equal(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b, float tolerance) - { - return Equal(a.M11, b.M11, tolerance) && - Equal(a.M12, b.M12, tolerance) && - Equal(a.M21, b.M21, tolerance) && - Equal(a.M22, b.M22, tolerance) && - Equal(a.M31, b.M31, tolerance) && - Equal(a.M32, b.M32, tolerance); - } - - public static bool Equal(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b) - { - return Equal(a, b, defaultTolerance); - } - - public bool Equals(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b) - { - return Equal(a, b, this.tolerance); - } - - public int GetHashCode(System.Numerics.Matrix3x2 obj) - { - int hash = GetHashCode(obj.M11); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M11)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M12)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M21)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M22)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M31)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M32)); - return hash; - } - - - public static bool Equal(Matrix4x4 a, Matrix4x4 b, float tolerance) - { - return - Equal(a.M11, b.M11, tolerance) && - Equal(a.M12, b.M12, tolerance) && - Equal(a.M13, b.M13, tolerance) && - Equal(a.M14, b.M14, tolerance) && - - Equal(a.M21, b.M21, tolerance) && - Equal(a.M22, b.M22, tolerance) && - Equal(a.M23, b.M23, tolerance) && - Equal(a.M24, b.M24, tolerance) && - - Equal(a.M31, b.M31, tolerance) && - Equal(a.M32, b.M32, tolerance) && - Equal(a.M33, b.M33, tolerance) && - Equal(a.M34, b.M34, tolerance) && - - Equal(a.M41, b.M41, tolerance) && - Equal(a.M42, b.M42, tolerance) && - Equal(a.M43, b.M43, tolerance) && - Equal(a.M44, b.M44, tolerance); - } - - public static bool Equal(Matrix4x4 a, Matrix4x4 b) - { - return Equal(a, b, defaultTolerance); - } - - public bool Equals(Matrix4x4 a, Matrix4x4 b) - { - return Equal(a, b, this.tolerance); - } - - - public int GetHashCode(Matrix4x4 obj) - { - int hash = GetHashCode(obj.M11); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M12)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M13)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M14)); - - hash = HashHelpers.Combine(hash, GetHashCode(obj.M21)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M22)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M23)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M24)); - - hash = HashHelpers.Combine(hash, GetHashCode(obj.M31)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M32)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M33)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M34)); - - hash = HashHelpers.Combine(hash, GetHashCode(obj.M41)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M42)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M43)); - hash = HashHelpers.Combine(hash, GetHashCode(obj.M44)); - return hash; - } - - - public static bool Equal(PointF a, PointF b, float tolerance) - { - return - Equal(a.X, b.X, tolerance) && - Equal(a.Y, b.Y, tolerance); - } - - public static bool Equal(PointF a, PointF b) - { - return Equal(a, b, defaultTolerance); - } - - public bool Equals(PointF a, PointF b) - { - return Equal(a, b, this.tolerance); - } - - - public int GetHashCode(PointF obj) - { - int hash = GetHashCode(obj.X); - hash = HashHelpers.Combine(hash, GetHashCode(obj.Y)); - return hash; - } - } -} diff --git a/src/SixLabors.Primitives/Ellipse.cs b/src/SixLabors.Primitives/Ellipse.cs deleted file mode 100644 index e1890df275..0000000000 --- a/src/SixLabors.Primitives/Ellipse.cs +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives -{ - using System; - using System.ComponentModel; - using System.Numerics; - - /// - /// Represents an ellipse. - /// - public struct Ellipse : IEquatable - { - /// - /// Represents a that has X and Y values set to zero. - /// - public static readonly Ellipse Empty = default(Ellipse); - - /// - /// The center point. - /// - private Point center; - - /// - /// Initializes a new instance of the struct. - /// - /// The center point. - /// The x-radius. - /// The y-radius. - public Ellipse(Point center, float radiusX, float radiusY) - { - this.center = center; - this.RadiusX = radiusX; - this.RadiusY = radiusY; - } - - /// - /// Gets the x-radius of this . - /// - public float RadiusX { get; } - - /// - /// Gets the y-radius of this . - /// - public float RadiusY { get; } - - /// - /// Gets a value indicating whether this is empty. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public bool IsEmpty => this.Equals(Empty); - - /// - /// Compares two objects for equality. - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator ==(Ellipse left, Ellipse right) - { - return left.Equals(right); - } - - /// - /// Compares two objects for inequality. - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is unequal to the parameter; otherwise, false. - /// - public static bool operator !=(Ellipse left, Ellipse right) - { - return !left.Equals(right); - } - - /// - /// Returns the center point of the given - /// - /// The ellipse - /// - public static Vector2 Center(Ellipse ellipse) - { - return new Vector2(ellipse.center.X, ellipse.center.Y); - } - - /// - /// Determines if the specfied point is contained within the rectangular region defined by - /// this . - /// - /// The x-coordinate of the given point. - /// The y-coordinate of the given point. - /// The - public bool Contains(int x, int y) - { - if (this.RadiusX <= 0 || this.RadiusY <= 0) - { - return false; - } - - // TODO: SIMD? - // This is a more general form of the circle equation - // X^2/a^2 + Y^2/b^2 <= 1 - Point normalized = new Point(x - this.center.X, y - this.center.Y); - int nX = normalized.X; - int nY = normalized.Y; - - return ((double)(nX * nX) / (this.RadiusX * this.RadiusX)) - + ((double)(nY * nY) / (this.RadiusY * this.RadiusY)) - <= 1.0; - } - - /// - public override int GetHashCode() - { - return this.GetHashCode(this); - } - - /// - public override string ToString() - { - if (this.IsEmpty) - { - return "Ellipse [ Empty ]"; - } - - return - $"Ellipse [ RadiusX={this.RadiusX}, RadiusY={this.RadiusX}, Centre={this.center.X},{this.center.Y} ]"; - } - - /// - public override bool Equals(object obj) - { - if (obj is Ellipse) - { - return this.Equals((Ellipse)obj); - } - - return false; - } - - /// - public bool Equals(Ellipse other) - { - return this.center.Equals(other.center) - && this.RadiusX.Equals(other.RadiusX) - && this.RadiusY.Equals(other.RadiusY); - } - - /// - /// Returns the hash code for this instance. - /// - /// - /// The instance of to return the hash code for. - /// - /// - /// A 32-bit signed integer that is the hash code for this instance. - /// - private int GetHashCode(Ellipse ellipse) - { - int hashCode = ellipse.center.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, ellipse.RadiusX.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, ellipse.RadiusY.GetHashCode()); - return hashCode; - } - } -} diff --git a/src/SixLabors.Primitives/LongRational.cs b/src/SixLabors.Primitives/LongRational.cs deleted file mode 100644 index 4f01936eec..0000000000 --- a/src/SixLabors.Primitives/LongRational.cs +++ /dev/null @@ -1,352 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives -{ - using System; - using System.Globalization; - using System.Text; - - /// - /// Represents a number that can be expressed as a fraction - /// - /// - /// This is a very simplified implementation of a rational number designed for use with metadata only. - /// - internal struct LongRational : IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// - /// The number above the line in a vulgar fraction showing how many of the parts - /// indicated by the denominator are taken. - /// - /// - /// The number below the line in a vulgar fraction; a divisor. - /// - public LongRational(long numerator, long denominator) - : this(numerator, denominator, false) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The number above the line in a vulgar fraction showing how many of the parts - /// indicated by the denominator are taken. - /// - /// - /// The number below the line in a vulgar fraction; a divisor. - /// - /// - /// Whether to attempt to simplify the fractional parts. - /// - public LongRational(long numerator, long denominator, bool simplify) - : this() - { - this.Numerator = numerator; - this.Denominator = denominator; - - if (simplify) - { - this.Simplify(); - } - } - - /// - /// Initializes a new instance of the struct. - /// - /// The to create the instance from. - /// Whether to use the best possible precision when parsing the value. - public LongRational(double value, bool bestPrecision) - : this() - { - if (double.IsNaN(value)) - { - this.Numerator = this.Denominator = 0; - return; - } - - if (double.IsPositiveInfinity(value)) - { - this.Numerator = 1; - this.Denominator = 0; - return; - } - - if (double.IsNegativeInfinity(value)) - { - this.Numerator = -1; - this.Denominator = 0; - return; - } - - this.Numerator = 1; - this.Denominator = 1; - - double val = Math.Abs(value); - double df = this.Numerator / (double)this.Denominator; - double epsilon = bestPrecision ? double.Epsilon : .000001; - - while (Math.Abs(df - val) > epsilon) - { - if (df < val) - { - this.Numerator++; - } - else - { - this.Denominator++; - this.Numerator = (int)(val * this.Denominator); - } - - df = this.Numerator / (double)this.Denominator; - } - - if (value < 0.0) - { - this.Numerator *= -1; - } - - this.Simplify(); - } - - /// - /// Gets the numerator of a number. - /// - public long Numerator - { - get; - private set; - } - - /// - /// Gets the denominator of a number. - /// - public long Denominator - { - get; - private set; - } - - /// - /// Gets a value indicating whether this instance is indeterminate. - /// - public bool IsIndeterminate - { - get - { - if (this.Denominator != 0) - { - return false; - } - - return this.Numerator == 0; - } - } - - /// - /// Gets a value indicating whether this instance is an integer (n, 1) - /// - public bool IsInteger => this.Denominator == 1; - - /// - /// Gets a value indicating whether this instance is equal to negative infinity (-1, 0) - /// - public bool IsNegativeInfinity - { - get - { - if (this.Denominator != 0) - { - return false; - } - - return this.Numerator == -1; - } - } - - /// - /// Gets a value indicating whether this instance is equal to positive infinity (1, 0) - /// - public bool IsPositiveInfinity - { - get - { - if (this.Denominator != 0) - { - return false; - } - - return this.Numerator == 1; - } - } - - /// - /// Gets a value indicating whether this instance is equal to 0 (0, 1) - /// - public bool IsZero - { - get - { - if (this.Denominator != 1) - { - return false; - } - - return this.Numerator == 0; - } - } - - /// - public bool Equals(LongRational other) - { - if (this.Denominator == other.Denominator) - { - return this.Numerator == other.Numerator; - } - - if (this.Numerator == 0 && this.Denominator == 0) - { - return other.Numerator == 0 && other.Denominator == 0; - } - - if (other.Numerator == 0 && other.Denominator == 0) - { - return this.Numerator == 0 && this.Denominator == 0; - } - - return (this.Numerator * other.Denominator) == (this.Denominator * other.Numerator); - } - - /// - public override int GetHashCode() - { - return this.GetHashCode(this); - } - - /// - public override string ToString() - { - return this.ToString(CultureInfo.InvariantCulture); - } - - /// - /// Converts the numeric value of this instance to its equivalent string representation using - /// the specified culture-specific format information. - /// - /// - /// An object that supplies culture-specific formatting information. - /// - /// The - public string ToString(IFormatProvider provider) - { - if (this.IsIndeterminate) - { - return "[ Indeterminate ]"; - } - - if (this.IsPositiveInfinity) - { - return "[ PositiveInfinity ]"; - } - - if (this.IsNegativeInfinity) - { - return "[ NegativeInfinity ]"; - } - - if (this.IsZero) - { - return "0"; - } - - if (this.IsInteger) - { - return this.Numerator.ToString(provider); - } - - StringBuilder sb = new StringBuilder(); - sb.Append(this.Numerator.ToString(provider)); - sb.Append("/"); - sb.Append(this.Denominator.ToString(provider)); - return sb.ToString(); - } - - /// - /// Finds the greatest common divisor of two values. - /// - /// The first value - /// The second value - /// The - private static long GreatestCommonDivisor(long left, long right) - { - return right == 0 ? left : GreatestCommonDivisor(right, left % right); - } - - /// - /// Simplifies the - /// - private void Simplify() - { - if (this.IsIndeterminate) - { - return; - } - - if (this.IsNegativeInfinity) - { - return; - } - - if (this.IsPositiveInfinity) - { - return; - } - - if (this.IsInteger) - { - return; - } - - if (this.IsZero) - { - return; - } - - if (this.Numerator == 0) - { - this.Denominator = 0; - return; - } - - if (this.Numerator == this.Denominator) - { - this.Numerator = 1; - this.Denominator = 1; - } - - long gcd = GreatestCommonDivisor(Math.Abs(this.Numerator), Math.Abs(this.Denominator)); - if (gcd > 1) - { - this.Numerator = this.Numerator / gcd; - this.Denominator = this.Denominator / gcd; - } - } - - /// - /// Returns the hash code for this instance. - /// - /// - /// The instance of to return the hash code for. - /// - /// - /// A 32-bit signed integer that is the hash code for this instance. - /// - private int GetHashCode(LongRational rational) => HashHelpers.Combine(rational.Numerator.GetHashCode(), rational.Denominator.GetHashCode()); - } -} \ No newline at end of file diff --git a/src/SixLabors.Primitives/Rational.cs b/src/SixLabors.Primitives/Rational.cs deleted file mode 100644 index 3d7003b4eb..0000000000 --- a/src/SixLabors.Primitives/Rational.cs +++ /dev/null @@ -1,189 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives -{ - using System; - using System.Globalization; - - /// - /// Represents a number that can be expressed as a fraction. - /// - /// - /// This is a very simplified implementation of a rational number designed for use with metadata only. - /// - public struct Rational : IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// The to create the rational from. - public Rational(uint value) - : this(value, 1) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. - /// The number below the line in a vulgar fraction; a divisor. - public Rational(uint numerator, uint denominator) - : this(numerator, denominator, true) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. - /// The number below the line in a vulgar fraction; a divisor. - /// Specified if the rational should be simplified. - public Rational(uint numerator, uint denominator, bool simplify) - { - LongRational rational = new LongRational(numerator, denominator, simplify); - - this.Numerator = (uint)rational.Numerator; - this.Denominator = (uint)rational.Denominator; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The to create the instance from. - public Rational(double value) - : this(value, false) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The to create the instance from. - /// Whether to use the best possible precision when parsing the value. - public Rational(double value, bool bestPrecision) - { - LongRational rational = new LongRational(Math.Abs(value), bestPrecision); - - this.Numerator = (uint)rational.Numerator; - this.Denominator = (uint)rational.Denominator; - } - - /// - /// Gets the numerator of a number. - /// - public uint Numerator { get; } - - /// - /// Gets the denominator of a number. - /// - public uint Denominator { get; } - - /// - /// Determines whether the specified instances are considered equal. - /// - /// The first to compare. - /// The second to compare. - /// The - public static bool operator ==(Rational left, Rational right) - { - return Rational.Equals(left, right); - } - - /// - /// Determines whether the specified instances are not considered equal. - /// - /// The first to compare. - /// The second to compare. - /// The - public static bool operator !=(Rational left, Rational right) - { - return !Rational.Equals(left, right); - } - - /// - /// Converts the specified to an instance of this type. - /// - /// The to convert to an instance of this type. - /// - /// The . - /// - public static Rational FromDouble(double value) - { - return new Rational(value, false); - } - - /// - /// Converts the specified to an instance of this type. - /// - /// The to convert to an instance of this type. - /// Whether to use the best possible precision when parsing the value. - /// - /// The . - /// - public static Rational FromDouble(double value, bool bestPrecision) - { - return new Rational(value, bestPrecision); - } - - /// - public override bool Equals(object obj) - { - if (obj is Rational) - { - return this.Equals((Rational)obj); - } - - return false; - } - - /// - public bool Equals(Rational other) - { - LongRational left = new LongRational(this.Numerator, this.Denominator); - LongRational right = new LongRational(other.Numerator, other.Denominator); - - return left.Equals(right); - } - - /// - public override int GetHashCode() - { - LongRational self = new LongRational(this.Numerator, this.Denominator); - return self.GetHashCode(); - } - - /// - /// Converts a rational number to the nearest . - /// - /// - /// The . - /// - public double ToDouble() - { - return this.Numerator / (double)this.Denominator; - } - - /// - public override string ToString() - { - return this.ToString(CultureInfo.InvariantCulture); - } - - /// - /// Converts the numeric value of this instance to its equivalent string representation using - /// the specified culture-specific format information. - /// - /// - /// An object that supplies culture-specific formatting information. - /// - /// The - public string ToString(IFormatProvider provider) - { - LongRational rational = new LongRational(this.Numerator, this.Denominator); - return rational.ToString(provider); - } - } -} \ No newline at end of file diff --git a/src/SixLabors.Primitives/SignedRational.cs b/src/SixLabors.Primitives/SignedRational.cs deleted file mode 100644 index 07fd105da4..0000000000 --- a/src/SixLabors.Primitives/SignedRational.cs +++ /dev/null @@ -1,189 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives -{ - using System; - using System.Globalization; - - /// - /// Represents a number that can be expressed as a fraction. - /// - /// - /// This is a very simplified implementation of a rational number designed for use with metadata only. - /// - public struct SignedRational : IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// The to create the rational from. - public SignedRational(int value) - : this(value, 1) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. - /// The number below the line in a vulgar fraction; a divisor. - public SignedRational(int numerator, int denominator) - : this(numerator, denominator, true) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken. - /// The number below the line in a vulgar fraction; a divisor. - /// Specified if the rational should be simplified. - public SignedRational(int numerator, int denominator, bool simplify) - { - LongRational rational = new LongRational(numerator, denominator, simplify); - - this.Numerator = (int)rational.Numerator; - this.Denominator = (int)rational.Denominator; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The to create the instance from. - public SignedRational(double value) - : this(value, false) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The to create the instance from. - /// Whether to use the best possible precision when parsing the value. - public SignedRational(double value, bool bestPrecision) - { - LongRational rational = new LongRational(value, bestPrecision); - - this.Numerator = (int)rational.Numerator; - this.Denominator = (int)rational.Denominator; - } - - /// - /// Gets the numerator of a number. - /// - public int Numerator { get; } - - /// - /// Gets the denominator of a number. - /// - public int Denominator { get; } - - /// - /// Determines whether the specified instances are considered equal. - /// - /// The first to compare. - /// The second to compare. - /// The - public static bool operator ==(SignedRational left, SignedRational right) - { - return SignedRational.Equals(left, right); - } - - /// - /// Determines whether the specified instances are not considered equal. - /// - /// The first to compare. - /// The second to compare. - /// The - public static bool operator !=(SignedRational left, SignedRational right) - { - return !SignedRational.Equals(left, right); - } - - /// - /// Converts the specified to an instance of this type. - /// - /// The to convert to an instance of this type. - /// - /// The . - /// - public static SignedRational FromDouble(double value) - { - return new SignedRational(value, false); - } - - /// - /// Converts the specified to an instance of this type. - /// - /// The to convert to an instance of this type. - /// Whether to use the best possible precision when parsing the value. - /// - /// The . - /// - public static SignedRational FromDouble(double value, bool bestPrecision) - { - return new SignedRational(value, bestPrecision); - } - - /// - public override bool Equals(object obj) - { - if (obj is SignedRational) - { - return this.Equals((SignedRational)obj); - } - - return false; - } - - /// - public bool Equals(SignedRational other) - { - LongRational left = new LongRational(this.Numerator, this.Denominator); - LongRational right = new LongRational(other.Numerator, other.Denominator); - - return left.Equals(right); - } - - /// - public override int GetHashCode() - { - LongRational self = new LongRational(this.Numerator, this.Denominator); - return self.GetHashCode(); - } - - /// - /// Converts a rational number to the nearest . - /// - /// - /// The . - /// - public double ToDouble() - { - return this.Numerator / (double)this.Denominator; - } - - /// - public override string ToString() - { - return this.ToString(CultureInfo.InvariantCulture); - } - - /// - /// Converts the numeric value of this instance to its equivalent string representation using - /// the specified culture-specific format information. - /// - /// - /// An object that supplies culture-specific formatting information. - /// - /// The - public string ToString(IFormatProvider provider) - { - LongRational rational = new LongRational(this.Numerator, this.Denominator); - return rational.ToString(provider); - } - } -} \ No newline at end of file diff --git a/src/SixLabors.Primitives/Size.cs b/src/SixLabors.Primitives/Size.cs index d0716d5ac3..abc7ad4cb2 100644 --- a/src/SixLabors.Primitives/Size.cs +++ b/src/SixLabors.Primitives/Size.cs @@ -124,6 +124,55 @@ namespace SixLabors.Primitives [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Size operator -(Size left, Size right) => Subtract(left, right); + /// + /// Multiplies a by an producing . + /// + /// Multiplier of type . + /// Multiplicand of type . + /// Product of type . + public static Size operator *(int left, Size right) => Multiply(right, left); + + /// + /// Multiplies by an producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type . + public static Size operator *(Size left, int right) => Multiply(left, right); + + /// + /// Divides by an producing . + /// + /// Dividend of type . + /// Divisor of type . + /// Result of type . + public static Size operator /(Size left, int right) => new Size(unchecked(left.Width / right), unchecked(left.Height / right)); + + /// + /// Multiplies by a producing . + /// + /// Multiplier of type . + /// Multiplicand of type . + /// Product of type . + public static SizeF operator *(float left, Size right) => Multiply(right, left); + + /// + /// Multiplies by a producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type . + public static SizeF operator *(Size left, float right) => Multiply(left, right); + + /// + /// Divides by a producing . + /// + /// Dividend of type . + /// Divisor of type . + /// Result of type . + public static SizeF operator /(Size left, float right) + => new SizeF(left.Width / right, left.Height / right); + /// /// Compares two objects for equality. /// @@ -172,6 +221,24 @@ namespace SixLabors.Primitives [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Size Subtract(Size left, Size right) => new Size(unchecked(left.Width - right.Width), unchecked(left.Height - right.Height)); + /// + /// Multiplies by an producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type . + private static Size Multiply(Size size, int multiplier) => + new Size(unchecked(size.Width * multiplier), unchecked(size.Height * multiplier)); + + /// + /// Multiplies by a producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type SizeF. + private static SizeF Multiply(Size size, float multiplier) => + new SizeF(size.Width * multiplier, size.Height * multiplier); + /// /// Converts a to a by performing a ceiling operation on all the dimensions. /// diff --git a/src/SixLabors.Primitives/SizeF.cs b/src/SixLabors.Primitives/SizeF.cs index 54db16b77f..e356a4edbe 100644 --- a/src/SixLabors.Primitives/SizeF.cs +++ b/src/SixLabors.Primitives/SizeF.cs @@ -116,6 +116,31 @@ namespace SixLabors.Primitives [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SizeF operator -(SizeF left, SizeF right) => Subtract(left, right); + /// + /// Multiplies by a producing . + /// + /// Multiplier of type . + /// Multiplicand of type . + /// Product of type . + public static SizeF operator *(float left, SizeF right) => Multiply(right, left); + + /// + /// Multiplies by a producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type . + public static SizeF operator *(SizeF left, float right) => Multiply(left, right); + + /// + /// Divides by a producing . + /// + /// Dividend of type . + /// Divisor of type . + /// Result of type . + public static SizeF operator /(SizeF left, float right) + => new SizeF(left.Width / right, left.Height / right); + /// /// Compares two objects for equality. /// @@ -156,6 +181,15 @@ namespace SixLabors.Primitives [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height); + /// + /// Multiplies by a producing . + /// + /// Multiplicand of type . + /// Multiplier of type . + /// Product of type SizeF. + private static SizeF Multiply(SizeF size, float multiplier) => + new SizeF(size.Width * multiplier, size.Height * multiplier); + /// public override int GetHashCode() { diff --git a/tests/SixLabors.Primitives.Tests/RationalTests.cs b/tests/SixLabors.Primitives.Tests/RationalTests.cs deleted file mode 100644 index e59505cf5f..0000000000 --- a/tests/SixLabors.Primitives.Tests/RationalTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives.Tests -{ - using Xunit; - - /// - /// Tests the struct. - /// - public class RationalTests - { - /// - /// Tests the equality operators for equality. - /// - [Fact] - public void AreEqual() - { - Rational r1 = new Rational(3, 2); - Rational r2 = new Rational(3, 2); - - Assert.Equal(r1, r2); - Assert.True(r1 == r2); - - Rational r3 = new Rational(7.55); - Rational r4 = new Rational(755, 100); - Rational r5 = new Rational(151, 20); - - Assert.Equal(r3, r4); - Assert.Equal(r4, r5); - } - - /// - /// Tests the equality operators for inequality. - /// - [Fact] - public void AreNotEqual() - { - Rational first = new Rational(0, 100); - Rational second = new Rational(100, 100); - - Assert.NotEqual(first, second); - Assert.True(first != second); - } - - /// - /// Tests whether the Rational constructor correctly assign properties. - /// - [Fact] - public void ConstructorAssignsProperties() - { - Rational rational = new Rational(7, 55); - Assert.Equal(7U, rational.Numerator); - Assert.Equal(55U, rational.Denominator); - - rational = new Rational(755, 100); - Assert.Equal(151U, rational.Numerator); - Assert.Equal(20U, rational.Denominator); - - rational = new Rational(755, 100, false); - Assert.Equal(755U, rational.Numerator); - Assert.Equal(100U, rational.Denominator); - - rational = new Rational(-7.55); - Assert.Equal(151U, rational.Numerator); - Assert.Equal(20U, rational.Denominator); - - rational = new Rational(7); - Assert.Equal(7U, rational.Numerator); - Assert.Equal(1U, rational.Denominator); - } - - [Fact] - public void Fraction() - { - Rational first = new Rational(1.0 / 1600); - Rational second = new Rational(1.0 / 1600, true); - Assert.False(first.Equals(second)); - } - - [Fact] - public void ToDouble() - { - Rational rational = new Rational(0, 0); - Assert.Equal(double.NaN, rational.ToDouble()); - - rational = new Rational(2, 0); - Assert.Equal(double.PositiveInfinity, rational.ToDouble()); - } - - [Fact] - public void ToStringRepresention() - { - Rational rational = new Rational(0, 0); - Assert.Equal("[ Indeterminate ]", rational.ToString()); - - rational = new Rational(double.PositiveInfinity); - Assert.Equal("[ PositiveInfinity ]", rational.ToString()); - - rational = new Rational(double.NegativeInfinity); - Assert.Equal("[ PositiveInfinity ]", rational.ToString()); - - rational = new Rational(0, 1); - Assert.Equal("0", rational.ToString()); - - rational = new Rational(2, 1); - Assert.Equal("2", rational.ToString()); - - rational = new Rational(1, 2); - Assert.Equal("1/2", rational.ToString()); - } - } -} \ No newline at end of file diff --git a/tests/SixLabors.Primitives.Tests/SignedRationalTests.cs b/tests/SixLabors.Primitives.Tests/SignedRationalTests.cs deleted file mode 100644 index bc7a5b8106..0000000000 --- a/tests/SixLabors.Primitives.Tests/SignedRationalTests.cs +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace SixLabors.Primitives.Tests -{ - using Xunit; - - /// - /// Tests the struct. - /// - public class SignedRationalTests - { - /// - /// Tests the equality operators for equality. - /// - [Fact] - public void AreEqual() - { - SignedRational r1 = new SignedRational(3, 2); - SignedRational r2 = new SignedRational(3, 2); - - Assert.Equal(r1, r2); - Assert.True(r1 == r2); - - SignedRational r3 = new SignedRational(7.55); - SignedRational r4 = new SignedRational(755, 100); - SignedRational r5 = new SignedRational(151, 20); - - Assert.Equal(r3, r4); - Assert.Equal(r4, r5); - } - - /// - /// Tests the equality operators for inequality. - /// - [Fact] - public void AreNotEqual() - { - SignedRational first = new SignedRational(0, 100); - SignedRational second = new SignedRational(100, 100); - - Assert.NotEqual(first, second); - Assert.True(first != second); - } - - /// - /// Tests whether the Rational constructor correctly assign properties. - /// - [Fact] - public void ConstructorAssignsProperties() - { - SignedRational rational = new SignedRational(7, -55); - Assert.Equal(7, rational.Numerator); - Assert.Equal(-55, rational.Denominator); - - rational = new SignedRational(-755, 100); - Assert.Equal(-151, rational.Numerator); - Assert.Equal(20, rational.Denominator); - - rational = new SignedRational(-755, -100, false); - Assert.Equal(-755, rational.Numerator); - Assert.Equal(-100, rational.Denominator); - - rational = new SignedRational(-151, -20); - Assert.Equal(-151, rational.Numerator); - Assert.Equal(-20, rational.Denominator); - - rational = new SignedRational(-7.55); - Assert.Equal(-151, rational.Numerator); - Assert.Equal(20, rational.Denominator); - - rational = new SignedRational(7); - Assert.Equal(7, rational.Numerator); - Assert.Equal(1, rational.Denominator); - } - - [Fact] - public void Fraction() - { - SignedRational first = new SignedRational(1.0 / 1600); - SignedRational second = new SignedRational(1.0 / 1600, true); - Assert.False(first.Equals(second)); - } - - [Fact] - public void ToDouble() - { - SignedRational rational = new SignedRational(0, 0); - Assert.Equal(double.NaN, rational.ToDouble()); - - rational = new SignedRational(2, 0); - Assert.Equal(double.PositiveInfinity, rational.ToDouble()); - - rational = new SignedRational(-2, 0); - Assert.Equal(double.NegativeInfinity, rational.ToDouble()); - } - - [Fact] - public void ToStringRepresention() - { - SignedRational rational = new SignedRational(0, 0); - Assert.Equal("[ Indeterminate ]", rational.ToString()); - - rational = new SignedRational(double.PositiveInfinity); - Assert.Equal("[ PositiveInfinity ]", rational.ToString()); - - rational = new SignedRational(double.NegativeInfinity); - Assert.Equal("[ NegativeInfinity ]", rational.ToString()); - - rational = new SignedRational(0, 1); - Assert.Equal("0", rational.ToString()); - - rational = new SignedRational(2, 1); - Assert.Equal("2", rational.ToString()); - - rational = new SignedRational(1, 2); - Assert.Equal("1/2", rational.ToString()); - } - } -} \ No newline at end of file diff --git a/tests/SixLabors.Primitives.Tests/SizeFTests.cs b/tests/SixLabors.Primitives.Tests/SizeFTests.cs index baa16c7e40..e4dec3fd6a 100644 --- a/tests/SixLabors.Primitives.Tests/SizeFTests.cs +++ b/tests/SixLabors.Primitives.Tests/SizeFTests.cs @@ -159,5 +159,86 @@ namespace SixLabors.Primitives.Tests var sz = new SizeF(0, 0); Assert.Equal("SizeF [ Empty ]", sz.ToString()); } + + [Theory] + [InlineData(1000.234f, 0.0f)] + [InlineData(1000.234f, 1.0f)] + [InlineData(1000.234f, 2400.933f)] + [InlineData(1000.234f, float.MaxValue)] + [InlineData(1000.234f, -1.0f)] + [InlineData(1000.234f, -2400.933f)] + [InlineData(1000.234f, float.MinValue)] + [InlineData(float.MaxValue, 0.0f)] + [InlineData(float.MaxValue, 1.0f)] + [InlineData(float.MaxValue, 2400.933f)] + [InlineData(float.MaxValue, float.MaxValue)] + [InlineData(float.MaxValue, -1.0f)] + [InlineData(float.MaxValue, -2400.933f)] + [InlineData(float.MaxValue, float.MinValue)] + [InlineData(float.MinValue, 0.0f)] + [InlineData(float.MinValue, 1.0f)] + [InlineData(float.MinValue, 2400.933f)] + [InlineData(float.MinValue, float.MaxValue)] + [InlineData(float.MinValue, -1.0f)] + [InlineData(float.MinValue, -2400.933f)] + [InlineData(float.MinValue, float.MinValue)] + public void MultiplicationTest(float dimension, float multiplier) + { + SizeF sz1 = new SizeF(dimension, dimension); + SizeF mulExpected; + + mulExpected = new SizeF(dimension * multiplier, dimension * multiplier); + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + [Theory] + [InlineData(1111.1111f, 2222.2222f, 3333.3333f)] + public void MultiplicationTestWidthHeightMultiplier(float width, float height, float multiplier) + { + SizeF sz1 = new SizeF(width, height); + SizeF mulExpected; + + mulExpected = new SizeF(width * multiplier, height * multiplier); + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + [Theory] + [InlineData(0.0f, 1.0f)] + [InlineData(1.0f, 1.0f)] + [InlineData(-1.0f, 1.0f)] + [InlineData(1.0f, -1.0f)] + [InlineData(-1.0f, -1.0f)] + [InlineData(float.MaxValue, float.MaxValue)] + [InlineData(float.MaxValue, float.MinValue)] + [InlineData(float.MinValue, float.MaxValue)] + [InlineData(float.MinValue, float.MinValue)] + [InlineData(float.MaxValue, 1.0f)] + [InlineData(float.MinValue, 1.0f)] + [InlineData(float.MaxValue, -1.0f)] + [InlineData(float.MinValue, -1.0f)] + [InlineData(float.MinValue, 0.0f)] + [InlineData(1.0f, float.MinValue)] + [InlineData(1.0f, float.MinValue)] + [InlineData(-1.0f, float.MinValue)] + [InlineData(-1.0f, float.MinValue)] + public void DivideTestSizeFloat(float dimension, float divisor) + { + SizeF size = new SizeF(dimension, dimension); + SizeF expected = new SizeF(dimension / divisor, dimension / divisor); + Assert.Equal(expected, size / divisor); + } + + [Theory] + [InlineData(-111.111f, 222.222f, 333.333f)] + public void DivideTestSizeFloatWidthHeightDivisor(float width, float height, float divisor) + { + SizeF size = new SizeF(width, height); + SizeF expected = new SizeF(width / divisor, height / divisor); + Assert.Equal(expected, size / divisor); + } } } \ No newline at end of file diff --git a/tests/SixLabors.Primitives.Tests/SizeTests.cs b/tests/SixLabors.Primitives.Tests/SizeTests.cs index 3eabf6221d..821cf16914 100644 --- a/tests/SixLabors.Primitives.Tests/SizeTests.cs +++ b/tests/SixLabors.Primitives.Tests/SizeTests.cs @@ -5,6 +5,7 @@ namespace SixLabors.Primitives.Tests { + using System; using System.Globalization; using Xunit; @@ -191,5 +192,184 @@ namespace SixLabors.Primitives.Tests var sz = new Size(0, 0); Assert.Equal("Size [ Empty ]", sz.ToString()); } + + [Theory] + [InlineData(1000, 0)] + [InlineData(1000, 1)] + [InlineData(1000, 2400)] + [InlineData(1000, int.MaxValue)] + [InlineData(1000, -1)] + [InlineData(1000, -2400)] + [InlineData(1000, int.MinValue)] + [InlineData(int.MaxValue, 0)] + [InlineData(int.MaxValue, 1)] + [InlineData(int.MaxValue, 2400)] + [InlineData(int.MaxValue, int.MaxValue)] + [InlineData(int.MaxValue, -1)] + [InlineData(int.MaxValue, -2400)] + [InlineData(int.MaxValue, int.MinValue)] + [InlineData(int.MinValue, 0)] + [InlineData(int.MinValue, 1)] + [InlineData(int.MinValue, 2400)] + [InlineData(int.MinValue, int.MaxValue)] + [InlineData(int.MinValue, -1)] + [InlineData(int.MinValue, -2400)] + [InlineData(int.MinValue, int.MinValue)] + public void MultiplicationTestSizeInt(int dimension, int multiplier) + { + Size sz1 = new Size(dimension, dimension); + Size mulExpected; + + unchecked + { + mulExpected = new Size(dimension * multiplier, dimension * multiplier); + } + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + [Theory] + [InlineData(1000, 2000, 3000)] + public void MultiplicationTestSizeIntWidthHeightMultiplier(int width, int height, int multiplier) + { + Size sz1 = new Size(width, height); + Size mulExpected; + + unchecked + { + mulExpected = new Size(width * multiplier, height * multiplier); + } + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + + [Theory] + [InlineData(1000, 0.0f)] + [InlineData(1000, 1.0f)] + [InlineData(1000, 2400.933f)] + [InlineData(1000, float.MaxValue)] + [InlineData(1000, -1.0f)] + [InlineData(1000, -2400.933f)] + [InlineData(1000, float.MinValue)] + [InlineData(int.MaxValue, 0.0f)] + [InlineData(int.MaxValue, 1.0f)] + [InlineData(int.MaxValue, 2400.933f)] + [InlineData(int.MaxValue, float.MaxValue)] + [InlineData(int.MaxValue, -1.0f)] + [InlineData(int.MaxValue, -2400.933f)] + [InlineData(int.MaxValue, float.MinValue)] + [InlineData(int.MinValue, 0.0f)] + [InlineData(int.MinValue, 1.0f)] + [InlineData(int.MinValue, 2400.933f)] + [InlineData(int.MinValue, float.MaxValue)] + [InlineData(int.MinValue, -1.0f)] + [InlineData(int.MinValue, -2400.933f)] + [InlineData(int.MinValue, float.MinValue)] + public void MultiplicationTestSizeFloat(int dimension, float multiplier) + { + Size sz1 = new Size(dimension, dimension); + SizeF mulExpected; + + mulExpected = new SizeF(dimension * multiplier, dimension * multiplier); + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + [Theory] + [InlineData(1000, 2000, 30.33f)] + public void MultiplicationTestSizeFloatWidthHeightMultiplier(int width, int height, float multiplier) + { + Size sz1 = new Size(width, height); + SizeF mulExpected; + + mulExpected = new SizeF(width * multiplier, height * multiplier); + + Assert.Equal(mulExpected, sz1 * multiplier); + Assert.Equal(mulExpected, multiplier * sz1); + } + + + [Fact] + public void DivideByZeroChecks() + { + Size size = new Size(100, 100); + Assert.Throws(() => size / 0); + + SizeF expectedSizeF = new SizeF(float.PositiveInfinity, float.PositiveInfinity); + Assert.Equal(expectedSizeF, size / 0.0f); + } + + [Theory] + [InlineData(0, 1)] + [InlineData(1, 1)] + [InlineData(-1, 1)] + [InlineData(1, -1)] + [InlineData(-1, -1)] + [InlineData(int.MaxValue, int.MaxValue)] + [InlineData(int.MaxValue, int.MinValue)] + [InlineData(int.MinValue, int.MaxValue)] + [InlineData(int.MinValue, int.MinValue)] + [InlineData(int.MaxValue, 1)] + [InlineData(int.MinValue, 1)] + [InlineData(int.MaxValue, -1)] + public void DivideTestSizeInt(int dimension, int divisor) + { + Size size = new Size(dimension, dimension); + Size expected; + + expected = new Size(dimension / divisor, dimension / divisor); + + Assert.Equal(expected, size / divisor); + } + + [Theory] + [InlineData(1111, 2222, 3333)] + public void DivideTestSizeIntWidthHeightDivisor(int width, int height, int divisor) + { + Size size = new Size(width, height); + Size expected; + + expected = new Size(width / divisor, height / divisor); + + Assert.Equal(expected, size / divisor); + } + + [Theory] + [InlineData(0, 1.0f)] + [InlineData(1, 1.0f)] + [InlineData(-1, 1.0f)] + [InlineData(1, -1.0f)] + [InlineData(-1, -1.0f)] + [InlineData(int.MaxValue, float.MaxValue)] + [InlineData(int.MaxValue, float.MinValue)] + [InlineData(int.MinValue, float.MaxValue)] + [InlineData(int.MinValue, float.MinValue)] + [InlineData(int.MaxValue, 1.0f)] + [InlineData(int.MinValue, 1.0f)] + [InlineData(int.MaxValue, -1.0f)] + [InlineData(int.MinValue, -1.0f)] + public void DivideTestSizeFloat(int dimension, float divisor) + { + SizeF size = new SizeF(dimension, dimension); + SizeF expected; + + expected = new SizeF(dimension / divisor, dimension / divisor); + Assert.Equal(expected, size / divisor); + } + + [Theory] + [InlineData(1111, 2222, -333.33f)] + public void DivideTestSizeFloatWidthHeightDivisor(int width, int height, float divisor) + { + SizeF size = new SizeF(width, height); + SizeF expected; + + expected = new SizeF(width / divisor, height / divisor); + Assert.Equal(expected, size / divisor); + } } } \ No newline at end of file