//
// 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;
using System.Runtime.CompilerServices;
///
/// Stores an ordered pair of single precision floating points, which specify a height and width.
///
///
/// 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.
///
public struct SizeF : IEquatable
{
///
/// Represents a that has Width and Height values set to zero.
///
public static readonly SizeF Empty = default(SizeF);
///
/// Initializes a new instance of the struct.
///
/// The width of the size.
/// The height of the size.
public SizeF(float width, float height)
{
this.Width = width;
this.Height = height;
}
///
/// Initializes a new instance of the struct.
///
/// The size
public SizeF(SizeF size)
: this()
{
this.Width = size.Width;
this.Height = size.Height;
}
///
/// Initializes a new instance of the struct from the given .
///
/// The point
public SizeF(PointF point)
{
this.Width = point.X;
this.Height = point.Y;
}
///
/// Gets or sets the width of this .
///
public float Width { get; set; }
///
/// Gets or sets the height of this .
///
public float Height { get; set; }
///
/// Gets a value indicating whether this is empty.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsEmpty => this.Equals(Empty);
///
/// Creates a with the dimensions of the specified by truncating each of the dimensions.
///
/// The size.
///
/// The .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator Size(SizeF size) => new Size(unchecked((int)size.Width), unchecked((int)size.Height));
///
/// Converts the given into a .
///
/// The size
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator PointF(SizeF size) => new PointF(size.Width, size.Height);
///
/// Computes the sum of adding two sizes.
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
///
/// The
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF operator +(SizeF left, SizeF right) => Add(left, right);
///
/// Computes the difference left by subtracting one size from another.
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
///
/// The
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF operator -(SizeF left, SizeF right) => Subtract(left, right);
///
/// Compares two objects for equality.
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
///
/// True if the current left is equal to the parameter; otherwise, false.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(SizeF left, SizeF right) => left.Equals(right);
///
/// Compares two objects for inequality.
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
///
/// True if the current left is unequal to the parameter; otherwise, false.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(SizeF left, SizeF right) => !left.Equals(right);
///
/// Performs vector addition of two objects.
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
/// The
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF Add(SizeF left, SizeF right) => new SizeF(left.Width + right.Width, left.Height + right.Height);
///
/// Contracts a by another
///
/// The size on the left hand of the operand.
/// The size on the right hand of the operand.
/// The
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height);
///
public override int GetHashCode()
{
return this.GetHashCode(this);
}
///
public override string ToString()
{
if (this.IsEmpty)
{
return "SizeF [ Empty ]";
}
return $"SizeF [ Width={this.Width}, Height={this.Height} ]";
}
///
public override bool Equals(object obj) => obj is SizeF && this.Equals((SizeF)obj);
///
[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();
///
/// Creates a with the coordinates of the specified .
///
/// The point.
///
/// The .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vector2(SizeF point) => new Vector2(point.Width, point.Height);
}
}