mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
20 changed files with 2533 additions and 595 deletions
@ -0,0 +1,72 @@ |
|||
// <copyright file="Matrix3x2Extensions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Matrix3x2"/> struct
|
|||
/// </summary>
|
|||
public static class Matrix3x2Extensions |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a rotation matrix for the given rotation in degrees and a center point.
|
|||
/// </summary>
|
|||
/// <param name="degree">The angle in degrees</param>
|
|||
/// <param name="centerPoint">The center point</param>
|
|||
/// <returns>The rotation <see cref="Matrix3x2"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Matrix3x2 CreateRotation(float degree, Point centerPoint) |
|||
{ |
|||
float radian = MathF.DegreeToRadian(degree); |
|||
return Matrix3x2.CreateRotation(radian, new Vector2(centerPoint.X, centerPoint.Y)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a rotation matrix for the given rotation in degrees and a center point.
|
|||
/// </summary>
|
|||
/// <param name="degree">The angle in degrees</param>
|
|||
/// <param name="centerPoint">The center point</param>
|
|||
/// <returns>The rotation <see cref="Matrix3x2"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Matrix3x2 CreateRotation(float degree, PointF centerPoint) |
|||
{ |
|||
float radian = MathF.DegreeToRadian(degree); |
|||
return Matrix3x2.CreateRotation(radian, centerPoint); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a skew matrix for the given angle in degrees and a center point.
|
|||
/// </summary>
|
|||
/// <param name="degreesX">The x-angle in degrees</param>
|
|||
/// <param name="degreesY">The y-angle in degrees</param>
|
|||
/// <param name="centerPoint">The center point</param>
|
|||
/// <returns>The rotation <see cref="Matrix3x2"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Matrix3x2 CreateSkew(float degreesX, float degreesY, Point centerPoint) |
|||
{ |
|||
float radiansX = MathF.DegreeToRadian(degreesX); |
|||
float radiansY = MathF.DegreeToRadian(degreesY); |
|||
return Matrix3x2.CreateSkew(radiansX, radiansY, new Vector2(centerPoint.X, centerPoint.Y)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a skew matrix for the given angle in degrees and a center point.
|
|||
/// </summary>
|
|||
/// <param name="degreesX">The x-angle in degrees</param>
|
|||
/// <param name="degreesY">The y-angle in degrees</param>
|
|||
/// <returns>The rotation <see cref="Matrix3x2"/></returns>
|
|||
/// <param name="centerPoint">The center point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Matrix3x2 CreateSkew(float degreesX, float degreesY, PointF centerPoint) |
|||
{ |
|||
float radiansX = MathF.DegreeToRadian(degreesX); |
|||
float radiansY = MathF.DegreeToRadian(degreesY); |
|||
return Matrix3x2.CreateSkew(radiansX, radiansY, new Vector2(centerPoint.X, centerPoint.Y)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,233 @@ |
|||
// <copyright file="PointF.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
/// <summary>
|
|||
/// Represents an ordered pair of single precision floating point x- and y-coordinates that defines a point in
|
|||
/// a two-dimensional plane.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
|||
/// as it avoids the need to create new values for modification operations.
|
|||
/// </remarks>
|
|||
public struct PointF : IEquatable<PointF> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="PointF"/> that has X and Y values set to zero.
|
|||
/// </summary>
|
|||
public static readonly PointF Empty = default(PointF); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PointF"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="x">The horizontal position of the point.</param>
|
|||
/// <param name="y">The vertical position of the point.</param>
|
|||
public PointF(float x, float y) |
|||
: this() |
|||
{ |
|||
this.X = x; |
|||
this.Y = y; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PointF"/> struct from the given <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
public PointF(SizeF size) |
|||
{ |
|||
this.X = size.Width; |
|||
this.Y = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the x-coordinate of this <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
public float X { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the y-coordinate of this <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
public float Y { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="PointF"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Vector2"/> with the coordinates of the specified <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Vector2"/>.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator PointF(Vector2 vector) => new PointF(vector.X, vector.Y); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Vector2"/> with the coordinates of the specified <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Vector2"/>.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator Vector2(PointF point) => new Vector2(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Point"/> with the coordinates of the specified <see cref="PointF"/> by truncating each of the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Point"/>.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator Point(PointF point) => Point.Truncate(point); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="PointF"/> by a given <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point on the left hand of the operand.</param>
|
|||
/// <param name="size">The size on the right hand of the operand.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="PointF"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF operator +(PointF point, SizeF size) => Add(point, size); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="PointF"/> by the negative of a given <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point on the left hand of the operand.</param>
|
|||
/// <param name="size">The size on the right hand of the operand.</param>
|
|||
/// <returns>The <see cref="PointF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF operator -(PointF point, SizeF size) => Subtract(point, size); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="PointF"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="PointF"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="PointF"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator ==(PointF left, PointF right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="PointF"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="PointF"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="PointF"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator !=(PointF left, PointF right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="PointF"/> by the negative of a given <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point on the left hand of the operand.</param>
|
|||
/// <param name="size">The size on the right hand of the operand.</param>
|
|||
/// <returns>The <see cref="PointF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF Add(PointF point, SizeF size) => new PointF(point.X + size.Width, point.Y + size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="PointF"/> by the negative of a given <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point on the left hand of the operand.</param>
|
|||
/// <param name="size">The size on the right hand of the operand.</param>
|
|||
/// <returns>The <see cref="PointF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF Subtract(PointF point, SizeF size) => new PointF(point.X - size.Width, point.Y - size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Rotates a point around the given rotation matrix.
|
|||
/// </summary>
|
|||
/// <param name="point">The point to rotate</param>
|
|||
/// <param name="rotation">Rotation matrix used</param>
|
|||
/// <returns>The rotated <see cref="PointF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF Rotate(PointF point, Matrix3x2 rotation) => Vector2.Transform(new Vector2(point.X, point.Y), rotation); |
|||
|
|||
/// <summary>
|
|||
/// Skews a point using the given skew matrix.
|
|||
/// </summary>
|
|||
/// <param name="point">The point to rotate</param>
|
|||
/// <param name="skew">Rotation matrix used</param>
|
|||
/// <returns>The rotated <see cref="PointF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF Skew(PointF point, Matrix3x2 skew) => Vector2.Transform(new Vector2(point.X, point.Y), skew); |
|||
|
|||
/// <summary>
|
|||
/// Translates this <see cref="PointF"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="dx">The amount to offset the x-coordinate.</param>
|
|||
/// <param name="dy">The amount to offset the y-coordinate.</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Offset(float dx, float dy) |
|||
{ |
|||
this.X += dx; |
|||
this.Y += dy; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Translates this <see cref="PointF"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="point">The <see cref="PointF"/> used offset this <see cref="PointF"/>.</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Offset(PointF point) => this.Offset(point.X, point.Y); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() => this.GetHashCode(this); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "PointF [ Empty ]"; |
|||
} |
|||
|
|||
return $"PointF [ X={this.X}, Y={this.Y} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is PointF && this.Equals((PointF)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(PointF other) => this.X.Equals(other.X) && this.Y.Equals(other.Y); |
|||
|
|||
/// <summary>
|
|||
/// Returns the hash code for this instance.
|
|||
/// </summary>
|
|||
/// <param name="point">
|
|||
/// The instance of <see cref="PointF"/> to return the hash code for.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// A 32-bit signed integer that is the hash code for this instance.
|
|||
/// </returns>
|
|||
private int GetHashCode(PointF point) => point.X.GetHashCode() ^ point.Y.GetHashCode(); |
|||
} |
|||
} |
|||
@ -0,0 +1,179 @@ |
|||
// <copyright file="SizeF.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
/// <summary>
|
|||
/// Stores an ordered pair of single precision floating points, which specify a height and width.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
|||
/// as it avoids the need to create new values for modification operations.
|
|||
/// </remarks>
|
|||
public struct SizeF : IEquatable<SizeF> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="SizeF"/> that has Width and Height values set to zero.
|
|||
/// </summary>
|
|||
public static readonly SizeF Empty = default(SizeF); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SizeF"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="width">The width of the size.</param>
|
|||
/// <param name="height">The height of the size.</param>
|
|||
public SizeF(float width, float height) |
|||
{ |
|||
this.Width = width; |
|||
this.Height = height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SizeF"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
public SizeF(SizeF size) |
|||
: this() |
|||
{ |
|||
this.Width = size.Width; |
|||
this.Height = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SizeF"/> struct from the given <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
public SizeF(PointF point) |
|||
{ |
|||
this.Width = point.X; |
|||
this.Height = point.Y; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the width of this <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
public float Width { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the height of this <see cref="SizeF"/>.
|
|||
/// </summary>
|
|||
public float Height { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="SizeF"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Size"/> with the dimensions of the specified <see cref="SizeF"/> by truncating each of the dimensions.
|
|||
/// </summary>
|
|||
/// <param name="size">The size.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Size"/>.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator Size(SizeF size) => new Size(unchecked((int)size.Width), unchecked((int)size.Height)); |
|||
|
|||
/// <summary>
|
|||
/// Converts the given <see cref="SizeF"/> into a <see cref="PointF"/>.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator PointF(SizeF size) => new PointF(size.Width, size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Computes the sum of adding two sizes.
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="SizeF"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static SizeF operator +(SizeF left, SizeF right) => Add(left, right); |
|||
|
|||
/// <summary>
|
|||
/// Computes the difference left by subtracting one size from another.
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="SizeF"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static SizeF operator -(SizeF left, SizeF right) => Subtract(left, right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="SizeF"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator ==(SizeF left, SizeF right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="SizeF"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static bool operator !=(SizeF left, SizeF right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Performs vector addition of two <see cref="SizeF"/> objects.
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>The <see cref="SizeF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static SizeF Add(SizeF left, SizeF right) => new SizeF(left.Width + right.Width, left.Height + right.Height); |
|||
|
|||
/// <summary>
|
|||
/// Contracts a <see cref="SizeF"/> by another <see cref="SizeF"/>
|
|||
/// </summary>
|
|||
/// <param name="left">The size on the left hand of the operand.</param>
|
|||
/// <param name="right">The size on the right hand of the operand.</param>
|
|||
/// <returns>The <see cref="SizeF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return this.GetHashCode(this); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "SizeF [ Empty ]"; |
|||
} |
|||
|
|||
return $"SizeF [ Width={this.Width}, Height={this.Height} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is SizeF && this.Equals((SizeF)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(SizeF other) => this.Width.Equals(other.Width) && this.Height.Equals(other.Height); |
|||
|
|||
private int GetHashCode(SizeF size) => size.Width.GetHashCode() ^ size.Height.GetHashCode(); |
|||
} |
|||
} |
|||
@ -0,0 +1,192 @@ |
|||
// <copyright file="PointFTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests.Numerics |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using System.Numerics; |
|||
using System.Reflection; |
|||
using Xunit; |
|||
|
|||
public class PointFTests |
|||
{ |
|||
[Fact] |
|||
public void DefaultConstructorTest() |
|||
{ |
|||
Assert.Equal(PointF.Empty, new PointF()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(float.MinValue, float.MaxValue)] |
|||
[InlineData(0.0, 0.0)] |
|||
public void NonDefaultConstructorTest(float x, float y) |
|||
{ |
|||
var p1 = new PointF(x, y); |
|||
|
|||
Assert.Equal(x, p1.X); |
|||
Assert.Equal(y, p1.Y); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IsEmptyDefaultsTest() |
|||
{ |
|||
Assert.True(PointF.Empty.IsEmpty); |
|||
Assert.True(new PointF().IsEmpty); |
|||
Assert.True(new PointF(0, 0).IsEmpty); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
public void IsEmptyRandomTest(float x, float y) |
|||
{ |
|||
Assert.False(new PointF(x, y).IsEmpty); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void CoordinatesTest(float x, float y) |
|||
{ |
|||
var p = new PointF(x, y); |
|||
Assert.Equal(x, p.X); |
|||
Assert.Equal(y, p.Y); |
|||
|
|||
p.X = 10; |
|||
Assert.Equal(10, p.X); |
|||
|
|||
p.Y = -10.123f; |
|||
Assert.Equal(-10.123, p.Y, 3); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue, int.MaxValue, int.MinValue)] |
|||
[InlineData(float.MinValue, float.MaxValue, int.MinValue, int.MaxValue)] |
|||
[InlineData(0, 0, 0, 0)] |
|||
public void ArithmeticTestWithSize(float x, float y, int x1, int y1) |
|||
{ |
|||
var p = new PointF(x, y); |
|||
var s = new Size(x1, y1); |
|||
|
|||
var addExpected = new PointF(x + x1, y + y1); |
|||
var subExpected = new PointF(x - x1, y - y1); |
|||
Assert.Equal(addExpected, p + s); |
|||
Assert.Equal(subExpected, p - s); |
|||
Assert.Equal(addExpected, PointF.Add(p, s)); |
|||
Assert.Equal(subExpected, PointF.Subtract(p, s)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void ArithmeticTestWithSizeF(float x, float y) |
|||
{ |
|||
var p = new PointF(x, y); |
|||
var s = new SizeF(y, x); |
|||
|
|||
var addExpected = new PointF(x + y, y + x); |
|||
var subExpected = new PointF(x - y, y - x); |
|||
Assert.Equal(addExpected, p + s); |
|||
Assert.Equal(subExpected, p - s); |
|||
Assert.Equal(addExpected, PointF.Add(p, s)); |
|||
Assert.Equal(subExpected, PointF.Subtract(p, s)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RotateTest() |
|||
{ |
|||
var p = new PointF(13, 17); |
|||
Matrix3x2 matrix = Matrix3x2Extensions.CreateRotation(45, PointF.Empty); |
|||
|
|||
var pout = PointF.Rotate(p, matrix); |
|||
|
|||
Assert.Equal(new PointF(-2.82842732F, 21.2132034F), pout); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SkewTest() |
|||
{ |
|||
var p = new PointF(13, 17); |
|||
Matrix3x2 matrix = Matrix3x2Extensions.CreateSkew(45, 45, PointF.Empty); |
|||
|
|||
var pout = PointF.Skew(p, matrix); |
|||
Assert.Equal(new PointF(30, 30), pout); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void EqualityTest(float x, float y) |
|||
{ |
|||
var pLeft = new PointF(x, y); |
|||
var pRight = new PointF(y, x); |
|||
|
|||
if (x == y) |
|||
{ |
|||
Assert.True(pLeft == pRight); |
|||
Assert.False(pLeft != pRight); |
|||
Assert.True(pLeft.Equals(pRight)); |
|||
Assert.True(pLeft.Equals((object)pRight)); |
|||
Assert.Equal(pLeft.GetHashCode(), pRight.GetHashCode()); |
|||
return; |
|||
} |
|||
|
|||
Assert.True(pLeft != pRight); |
|||
Assert.False(pLeft == pRight); |
|||
Assert.False(pLeft.Equals(pRight)); |
|||
Assert.False(pLeft.Equals((object)pRight)); |
|||
} |
|||
|
|||
[Fact] |
|||
public static void EqualityTest_NotPointF() |
|||
{ |
|||
var point = new PointF(0, 0); |
|||
Assert.False(point.Equals(null)); |
|||
Assert.False(point.Equals(0)); |
|||
|
|||
// If PointF implements IEquatable<PointF> (e.g. in .NET Core), then structs that are implicitly
|
|||
// convertible to var can potentially be equal.
|
|||
// See https://github.com/dotnet/corefx/issues/5255.
|
|||
bool expectsImplicitCastToPointF = typeof(IEquatable<PointF>).IsAssignableFrom(point.GetType()); |
|||
Assert.Equal(expectsImplicitCastToPointF, point.Equals(new Point(0, 0))); |
|||
|
|||
Assert.False(point.Equals((object)new Point(0, 0))); // No implicit cast
|
|||
} |
|||
|
|||
[Fact] |
|||
public static void GetHashCodeTest() |
|||
{ |
|||
var point = new PointF(10, 10); |
|||
Assert.Equal(point.GetHashCode(), new PointF(10, 10).GetHashCode()); |
|||
Assert.NotEqual(point.GetHashCode(), new PointF(20, 10).GetHashCode()); |
|||
Assert.NotEqual(point.GetHashCode(), new PointF(10, 20).GetHashCode()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToStringTest() |
|||
{ |
|||
var p = new PointF(5.1F, -5.123F); |
|||
Assert.Equal(string.Format(CultureInfo.CurrentCulture, "PointF [ X={0}, Y={1} ]", p.X, p.Y), p.ToString()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToStringEmptyTest() |
|||
{ |
|||
var p = new PointF(0, 0); |
|||
Assert.Equal("PointF [ Empty ]", p.ToString()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,267 @@ |
|||
// <copyright file="RectangleFTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using System.Reflection; |
|||
|
|||
using Xunit; |
|||
|
|||
/// <summary>
|
|||
/// Tests the <see cref="RectangleF"/> struct.
|
|||
/// </summary>
|
|||
public class RectangleFTests |
|||
{ |
|||
[Fact] |
|||
public void DefaultConstructorTest() |
|||
{ |
|||
Assert.Equal(RectangleF.Empty, new RectangleF()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void NonDefaultConstructorTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect1 = new RectangleF(x, y, width, height); |
|||
var p = new PointF(x, y); |
|||
var s = new SizeF(width, height); |
|||
var rect2 = new RectangleF(p, s); |
|||
|
|||
Assert.Equal(rect1, rect2); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void FromLTRBTest(float left, float top, float right, float bottom) |
|||
{ |
|||
var expected = new RectangleF(left, top, right - left, bottom - top); |
|||
var actual = RectangleF.FromLTRB(left, top, right, bottom); |
|||
|
|||
Assert.Equal(expected, actual); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void DimensionsTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect = new RectangleF(x, y, width, height); |
|||
var p = new PointF(x, y); |
|||
var s = new SizeF(width, height); |
|||
|
|||
Assert.Equal(p, rect.Location); |
|||
Assert.Equal(s, rect.Size); |
|||
Assert.Equal(x, rect.X); |
|||
Assert.Equal(y, rect.Y); |
|||
Assert.Equal(width, rect.Width); |
|||
Assert.Equal(height, rect.Height); |
|||
Assert.Equal(x, rect.Left); |
|||
Assert.Equal(y, rect.Top); |
|||
Assert.Equal(x + width, rect.Right); |
|||
Assert.Equal(y + height, rect.Bottom); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IsEmptyTest() |
|||
{ |
|||
Assert.True(RectangleF.Empty.IsEmpty); |
|||
Assert.True(new RectangleF().IsEmpty); |
|||
Assert.True(new RectangleF(1, -2, -10, 10).IsEmpty); |
|||
Assert.True(new RectangleF(1, -2, 10, -10).IsEmpty); |
|||
Assert.True(new RectangleF(1, -2, 0, 0).IsEmpty); |
|||
|
|||
Assert.False(new RectangleF(0, 0, 10, 10).IsEmpty); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
public static void LocationSetTest(float x, float y) |
|||
{ |
|||
var point = new PointF(x, y); |
|||
var rect = new RectangleF(10, 10, 10, 10) { Location = point }; |
|||
Assert.Equal(point, rect.Location); |
|||
Assert.Equal(point.X, rect.X); |
|||
Assert.Equal(point.Y, rect.Y); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
public static void SizeSetTest(float x, float y) |
|||
{ |
|||
var size = new SizeF(x, y); |
|||
var rect = new RectangleF(10, 10, 10, 10) { Size = size }; |
|||
Assert.Equal(size, rect.Size); |
|||
Assert.Equal(size.Width, rect.Width); |
|||
Assert.Equal(size.Height, rect.Height); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void EqualityTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect1 = new RectangleF(x, y, width, height); |
|||
var rect2 = new RectangleF(width, height, x, y); |
|||
|
|||
Assert.True(rect1 != rect2); |
|||
Assert.False(rect1 == rect2); |
|||
Assert.False(rect1.Equals(rect2)); |
|||
Assert.False(rect1.Equals((object)rect2)); |
|||
} |
|||
|
|||
[Fact] |
|||
public static void EqualityTestNotRectangleF() |
|||
{ |
|||
var rectangle = new RectangleF(0, 0, 0, 0); |
|||
Assert.False(rectangle.Equals(null)); |
|||
Assert.False(rectangle.Equals(0)); |
|||
|
|||
// If RectangleF implements IEquatable<RectangleF> (e.g. in .NET Core), then classes that are implicitly
|
|||
// convertible to RectangleF can potentially be equal.
|
|||
// See https://github.com/dotnet/corefx/issues/5255.
|
|||
bool expectsImplicitCastToRectangleF = typeof(IEquatable<RectangleF>).IsAssignableFrom(rectangle.GetType()); |
|||
Assert.Equal(expectsImplicitCastToRectangleF, rectangle.Equals(new Rectangle(0, 0, 0, 0))); |
|||
|
|||
Assert.False(rectangle.Equals((object)new Rectangle(0, 0, 0, 0))); // No implicit cast
|
|||
} |
|||
|
|||
[Fact] |
|||
public static void GetHashCodeTest() |
|||
{ |
|||
var rect1 = new RectangleF(10, 10, 10, 10); |
|||
var rect2 = new RectangleF(10, 10, 10, 10); |
|||
Assert.Equal(rect1.GetHashCode(), rect2.GetHashCode()); |
|||
Assert.NotEqual(rect1.GetHashCode(), new RectangleF(20, 10, 10, 10).GetHashCode()); |
|||
Assert.NotEqual(rect1.GetHashCode(), new RectangleF(10, 20, 10, 10).GetHashCode()); |
|||
Assert.NotEqual(rect1.GetHashCode(), new RectangleF(10, 10, 20, 10).GetHashCode()); |
|||
Assert.NotEqual(rect1.GetHashCode(), new RectangleF(10, 10, 10, 20).GetHashCode()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void ContainsTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect = new RectangleF(x, y, width, height); |
|||
float X = (x + width) / 2; |
|||
float Y = (y + height) / 2; |
|||
var p = new PointF(X, Y); |
|||
var r = new RectangleF(X, Y, width / 2, height / 2); |
|||
|
|||
Assert.False(rect.Contains(X, Y)); |
|||
Assert.False(rect.Contains(p)); |
|||
Assert.False(rect.Contains(r)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue / 2, float.MinValue / 2, float.MinValue / 2, float.MaxValue / 2)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void InflateTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect = new RectangleF(x, y, width, height); |
|||
var inflatedRect = new RectangleF(x - width, y - height, width + 2 * width, height + 2 * height); |
|||
|
|||
rect.Inflate(width, height); |
|||
Assert.Equal(inflatedRect, rect); |
|||
|
|||
var s = new SizeF(x, y); |
|||
inflatedRect = RectangleF.Inflate(rect, x, y); |
|||
|
|||
rect.Inflate(s); |
|||
Assert.Equal(inflatedRect, rect); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MaxValue / 2, float.MinValue / 2)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void IntersectTest(float x, float y, float width, float height) |
|||
{ |
|||
var rect1 = new RectangleF(x, y, width, height); |
|||
var rect2 = new RectangleF(y, x, width, height); |
|||
var expectedRect = RectangleF.Intersect(rect1, rect2); |
|||
rect1.Intersect(rect2); |
|||
Assert.Equal(expectedRect, rect1); |
|||
Assert.False(rect1.IntersectsWith(expectedRect)); |
|||
} |
|||
|
|||
[Fact] |
|||
public static void IntersectIntersectingRectsTest() |
|||
{ |
|||
var rect1 = new RectangleF(0, 0, 5, 5); |
|||
var rect2 = new RectangleF(1, 1, 3, 3); |
|||
var expected = new RectangleF(1, 1, 3, 3); |
|||
|
|||
Assert.Equal(expected, RectangleF.Intersect(rect1, rect2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void UnionTest(float x, float y, float width, float height) |
|||
{ |
|||
var a = new RectangleF(x, y, width, height); |
|||
var b = new RectangleF(width, height, x, y); |
|||
|
|||
float x1 = Math.Min(a.X, b.X); |
|||
float x2 = Math.Max(a.X + a.Width, b.X + b.Width); |
|||
float y1 = Math.Min(a.Y, b.Y); |
|||
float y2 = Math.Max(a.Y + a.Height, b.Y + b.Height); |
|||
|
|||
var expectedRectangle = new RectangleF(x1, y1, x2 - x1, y2 - y1); |
|||
|
|||
Assert.Equal(expectedRectangle, RectangleF.Union(a, b)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(float.MaxValue, float.MinValue, float.MinValue, float.MaxValue)] |
|||
[InlineData(float.MaxValue, 0, 0, float.MaxValue)] |
|||
[InlineData(0, float.MinValue, float.MaxValue, 0)] |
|||
public void OffsetTest(float x, float y, float width, float height) |
|||
{ |
|||
var r1 = new RectangleF(x, y, width, height); |
|||
var expectedRect = new RectangleF(x + width, y + height, width, height); |
|||
var p = new PointF(width, height); |
|||
|
|||
r1.Offset(p); |
|||
Assert.Equal(expectedRect, r1); |
|||
|
|||
expectedRect.Offset(p); |
|||
r1.Offset(width, height); |
|||
Assert.Equal(expectedRect, r1); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToStringTest() |
|||
{ |
|||
var r = new RectangleF(5, 5.1F, 1.3F, 1); |
|||
Assert.Equal(string.Format(CultureInfo.CurrentCulture, "RectangleF [ X={0}, Y={1}, Width={2}, Height={3} ]", r.X, r.Y, r.Width, r.Height), r.ToString()); |
|||
} |
|||
|
|||
[InlineData(0, 0, 0, 0)] |
|||
[InlineData(5, -5, 0.2, -1.3)] |
|||
public void ToStringTestEmpty(float x, float y, float width, float height) |
|||
{ |
|||
var r = new RectangleF(x, y, width, height); |
|||
Assert.Equal("RectangleF [ Empty ]", r.ToString()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,163 @@ |
|||
// <copyright file="SizeTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using System.Reflection; |
|||
using Xunit; |
|||
|
|||
public class SizeFTests |
|||
{ |
|||
[Fact] |
|||
public void DefaultConstructorTest() |
|||
{ |
|||
Assert.Equal(SizeF.Empty, new SizeF()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void NonDefaultConstructorAndDimensionsTest(float width, float height) |
|||
{ |
|||
var s1 = new SizeF(width, height); |
|||
var p1 = new PointF(width, height); |
|||
var s2 = new SizeF(s1); |
|||
|
|||
Assert.Equal(s1, s2); |
|||
Assert.Equal(s1, new SizeF(p1)); |
|||
Assert.Equal(s2, new SizeF(p1)); |
|||
|
|||
Assert.Equal(width, s1.Width); |
|||
Assert.Equal(height, s1.Height); |
|||
|
|||
s1.Width = 10; |
|||
Assert.Equal(10, s1.Width); |
|||
|
|||
s1.Height = -10.123f; |
|||
Assert.Equal(-10.123, s1.Height, 3); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IsEmptyDefaultsTest() |
|||
{ |
|||
Assert.True(SizeF.Empty.IsEmpty); |
|||
Assert.True(new SizeF().IsEmpty); |
|||
Assert.True(new SizeF(0, 0).IsEmpty); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
public void IsEmptyRandomTest(float width, float height) |
|||
{ |
|||
Assert.False(new SizeF(width, height).IsEmpty); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void ArithmeticTest(float width, float height) |
|||
{ |
|||
var s1 = new SizeF(width, height); |
|||
var s2 = new SizeF(height, width); |
|||
var addExpected = new SizeF(width + height, width + height); |
|||
var subExpected = new SizeF(width - height, height - width); |
|||
|
|||
Assert.Equal(addExpected, s1 + s2); |
|||
Assert.Equal(addExpected, SizeF.Add(s1, s2)); |
|||
|
|||
Assert.Equal(subExpected, s1 - s2); |
|||
Assert.Equal(subExpected, SizeF.Subtract(s1, s2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void EqualityTest(float width, float height) |
|||
{ |
|||
var sLeft = new SizeF(width, height); |
|||
var sRight = new SizeF(height, width); |
|||
|
|||
if (width == height) |
|||
{ |
|||
Assert.True(sLeft == sRight); |
|||
Assert.False(sLeft != sRight); |
|||
Assert.True(sLeft.Equals(sRight)); |
|||
Assert.True(sLeft.Equals((object)sRight)); |
|||
Assert.Equal(sLeft.GetHashCode(), sRight.GetHashCode()); |
|||
return; |
|||
} |
|||
|
|||
Assert.True(sLeft != sRight); |
|||
Assert.False(sLeft == sRight); |
|||
Assert.False(sLeft.Equals(sRight)); |
|||
Assert.False(sLeft.Equals((object)sRight)); |
|||
} |
|||
|
|||
[Fact] |
|||
public static void EqualityTest_NotSizeF() |
|||
{ |
|||
var size = new SizeF(0, 0); |
|||
Assert.False(size.Equals(null)); |
|||
Assert.False(size.Equals(0)); |
|||
|
|||
// If SizeF implements IEquatable<SizeF> (e.g in .NET Core), then classes that are implicitly
|
|||
// convertible to SizeF can potentially be equal.
|
|||
// See https://github.com/dotnet/corefx/issues/5255.
|
|||
bool expectsImplicitCastToSizeF = typeof(IEquatable<SizeF>).IsAssignableFrom(size.GetType()); |
|||
Assert.Equal(expectsImplicitCastToSizeF, size.Equals(new Size(0, 0))); |
|||
|
|||
Assert.False(size.Equals((object)new Size(0, 0))); // No implicit cast
|
|||
} |
|||
|
|||
[Fact] |
|||
public static void GetHashCodeTest() |
|||
{ |
|||
var size = new SizeF(10, 10); |
|||
Assert.Equal(size.GetHashCode(), new SizeF(10, 10).GetHashCode()); |
|||
Assert.NotEqual(size.GetHashCode(), new SizeF(20, 10).GetHashCode()); |
|||
Assert.NotEqual(size.GetHashCode(), new SizeF(10, 20).GetHashCode()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(float.MaxValue, float.MinValue)] |
|||
[InlineData(float.MinValue, float.MinValue)] |
|||
[InlineData(float.MaxValue, float.MaxValue)] |
|||
[InlineData(0, 0)] |
|||
public void ConversionTest(float width, float height) |
|||
{ |
|||
var s1 = new SizeF(width, height); |
|||
var p1 = (PointF)s1; |
|||
var s2 = new Size(unchecked((int)width), unchecked((int)height)); |
|||
|
|||
Assert.Equal(new PointF(width, height), p1); |
|||
Assert.Equal(p1, (PointF)s1); |
|||
Assert.Equal(s2, (Size)s1); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToStringTest() |
|||
{ |
|||
var sz = new SizeF(10, 5); |
|||
Assert.Equal(string.Format(CultureInfo.CurrentCulture, "SizeF [ Width={0}, Height={1} ]", sz.Width, sz.Height), sz.ToString()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToStringTestEmpty() |
|||
{ |
|||
var sz = new SizeF(0, 0); |
|||
Assert.Equal("SizeF [ Empty ]", sz.ToString()); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue