mirror of https://github.com/SixLabors/ImageSharp
173 changed files with 384 additions and 3676 deletions
@ -0,0 +1,80 @@ |
|||
// <copyright file="FillPaths.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 Drawing; |
|||
using Drawing.Brushes; |
|||
using ImageSharp.PixelFormats; |
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TPixel}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="path">The shape.</param>
|
|||
/// <param name="options">The graphics options.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path, GraphicsOptions options) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
var pb = new PathBuilder(); |
|||
path(pb); |
|||
|
|||
return source.Fill(brush, pb.Build(), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
return source.Fill(brush, path, GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Action<PathBuilder> path, GraphicsOptions options) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
return source.Fill(new SolidBrush<TPixel>(color), path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Action<PathBuilder> path) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
return source.Fill(new SolidBrush<TPixel>(color), path); |
|||
} |
|||
} |
|||
} |
|||
@ -1,29 +0,0 @@ |
|||
// <copyright file="RectangleExtensions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for helping to bridge Shaper2D and ImageSharp primitives.
|
|||
/// </summary>
|
|||
internal static class RectangleExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Converts a Shaper2D <see cref="SixLabors.Shapes.Rectangle"/> to an ImageSharp <see cref="Rectangle"/> by creating a <see cref="Rectangle"/> the entirely surrounds the source.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <returns>A <see cref="Rectangle"/> representation of this <see cref="SixLabors.Shapes.Rectangle"/></returns>
|
|||
public static Rectangle Convert(this SixLabors.Shapes.Rectangle source) |
|||
{ |
|||
int left = (int)MathF.Floor(source.Left); |
|||
int right = (int)MathF.Ceiling(source.Right); |
|||
int top = (int)MathF.Floor(source.Top); |
|||
int bottom = (int)MathF.Ceiling(source.Bottom); |
|||
return new Rectangle(left, top, right - left, bottom - top); |
|||
} |
|||
} |
|||
} |
|||
@ -1,183 +0,0 @@ |
|||
// <copyright file="Ellipse.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; |
|||
|
|||
/// <summary>
|
|||
/// Represents an ellipse.
|
|||
/// </summary>
|
|||
public struct Ellipse : IEquatable<Ellipse> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="Ellipse"/> that has X and Y values set to zero.
|
|||
/// </summary>
|
|||
public static readonly Ellipse Empty = default(Ellipse); |
|||
|
|||
/// <summary>
|
|||
/// The center point.
|
|||
/// </summary>
|
|||
private Point center; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Ellipse"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="center">The center point.</param>
|
|||
/// <param name="radiusX">The x-radius.</param>
|
|||
/// <param name="radiusY">The y-radius.</param>
|
|||
public Ellipse(Point center, float radiusX, float radiusY) |
|||
{ |
|||
this.center = center; |
|||
this.RadiusX = radiusX; |
|||
this.RadiusY = radiusY; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the x-radius of this <see cref="Ellipse"/>.
|
|||
/// </summary>
|
|||
public float RadiusX { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the y-radius of this <see cref="Ellipse"/>.
|
|||
/// </summary>
|
|||
public float RadiusY { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="Ellipse"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Ellipse"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Ellipse"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Ellipse"/> 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>
|
|||
public static bool operator ==(Ellipse left, Ellipse right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Ellipse"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Ellipse"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Ellipse"/> 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>
|
|||
public static bool operator !=(Ellipse left, Ellipse right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the center point of the given <see cref="Ellipse"/>
|
|||
/// </summary>
|
|||
/// <param name="ellipse">The ellipse</param>
|
|||
/// <returns><see cref="Vector2"/></returns>
|
|||
public static Vector2 Center(Ellipse ellipse) |
|||
{ |
|||
return new Vector2(ellipse.center.X, ellipse.center.Y); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specfied point is contained within the rectangular region defined by
|
|||
/// this <see cref="Ellipse"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-coordinate of the given point.</param>
|
|||
/// <param name="y">The y-coordinate of the given point.</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
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; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return this.GetHashCode(this); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
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} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (obj is Ellipse) |
|||
{ |
|||
return this.Equals((Ellipse)obj); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(Ellipse other) |
|||
{ |
|||
return this.center.Equals(other.center) |
|||
&& this.RadiusX.Equals(other.RadiusX) |
|||
&& this.RadiusY.Equals(other.RadiusY); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the hash code for this instance.
|
|||
/// </summary>
|
|||
/// <param name="ellipse">
|
|||
/// The instance of <see cref="Point"/> 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(Ellipse ellipse) |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = ellipse.center.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ ellipse.RadiusX.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ ellipse.RadiusY.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,72 +0,0 @@ |
|||
// <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)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,257 +0,0 @@ |
|||
// <copyright file="Point.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 integer 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 Point : IEquatable<Point> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="Point"/> that has X and Y values set to zero.
|
|||
/// </summary>
|
|||
public static readonly Point Empty = default(Point); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Point"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The horizontal and vertical position of the point.</param>
|
|||
public Point(int value) |
|||
: this() |
|||
{ |
|||
this.X = LowInt16(value); |
|||
this.Y = HighInt16(value); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Point"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="x">The horizontal position of the point.</param>
|
|||
/// <param name="y">The vertical position of the point.</param>
|
|||
public Point(int x, int y) |
|||
: this() |
|||
{ |
|||
this.X = x; |
|||
this.Y = y; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Point"/> struct from the given <see cref="Size"/>.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
public Point(Size size) |
|||
{ |
|||
this.X = size.Width; |
|||
this.Y = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the x-coordinate of this <see cref="Point"/>.
|
|||
/// </summary>
|
|||
public int X { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the y-coordinate of this <see cref="Point"/>.
|
|||
/// </summary>
|
|||
public int Y { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="Point"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="PointF"/> with the coordinates of the specified <see cref="Point"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator PointF(Point point) => new PointF(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Vector2"/> with the coordinates of the specified <see cref="Point"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator Vector2(Point point) => new Vector2(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Size"/> with the coordinates of the specified <see cref="Point"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator Size(Point point) => new Size(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="Point"/> by a given <see cref="Size"/>.
|
|||
/// </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="Point"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point operator +(Point point, Size size) => Add(point, size); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="Point"/> by the negative of a given <see cref="Size"/>.
|
|||
/// </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="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point operator -(Point point, Size size) => Subtract(point, size); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Point"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Point"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Point"/> 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 ==(Point left, Point right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Point"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Point"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Point"/> 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 !=(Point left, Point right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="Point"/> by the negative of a given <see cref="Size"/>.
|
|||
/// </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="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Add(Point point, Size size) => new Point(unchecked(point.X + size.Width), unchecked(point.Y + size.Height)); |
|||
|
|||
/// <summary>
|
|||
/// Translates a <see cref="Point"/> by the negative of a given <see cref="Size"/>.
|
|||
/// </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="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Subtract(Point point, Size size) => new Point(unchecked(point.X - size.Width), unchecked(point.Y - size.Height)); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="PointF"/> to a <see cref="Point"/> by performing a ceiling operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Ceiling(PointF point) => new Point(unchecked((int)MathF.Ceiling(point.X)), unchecked((int)MathF.Ceiling(point.Y))); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="PointF"/> to a <see cref="Point"/> by performing a round operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Round(PointF point) => new Point(unchecked((int)MathF.Round(point.X)), unchecked((int)MathF.Round(point.Y))); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="PointF"/> to a <see cref="Point"/> by performing a truncate operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Truncate(PointF point) => new Point(unchecked((int)point.X), unchecked((int)point.Y)); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="Vector2"/> to a <see cref="Point"/> by performing a round operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="vector">The vector</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Round(Vector2 vector) => new Point(unchecked((int)MathF.Round(vector.X)), unchecked((int)MathF.Round(vector.Y))); |
|||
|
|||
/// <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="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Rotate(Point point, Matrix3x2 rotation) => Round(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="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Skew(Point point, Matrix3x2 skew) => Round(Vector2.Transform(new Vector2(point.X, point.Y), skew)); |
|||
|
|||
/// <summary>
|
|||
/// Translates this <see cref="Point"/> 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(int dx, int dy) |
|||
{ |
|||
unchecked |
|||
{ |
|||
this.X += dx; |
|||
this.Y += dy; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Translates this <see cref="Point"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="point">The <see cref="Point"/> used offset this <see cref="Point"/>.</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Offset(Point point) => this.Offset(point.X, point.Y); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() => this.GetHashCode(this); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "Point [ Empty ]"; |
|||
} |
|||
|
|||
return $"Point [ X={this.X}, Y={this.Y} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is Point && this.Equals((Point)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Point other) => this.X == other.X && this.Y == other.Y; |
|||
|
|||
private static short HighInt16(int n) => unchecked((short)((n >> 16) & 0xffff)); |
|||
|
|||
private static short LowInt16(int n) => unchecked((short)(n & 0xffff)); |
|||
|
|||
private int GetHashCode(Point point) => point.X ^ point.Y; |
|||
} |
|||
} |
|||
@ -1,233 +0,0 @@ |
|||
// <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(); |
|||
} |
|||
} |
|||
@ -1,467 +0,0 @@ |
|||
// <copyright file="Rectangle.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>
|
|||
/// Stores a set of four integers that represent the location and size of a rectangle.
|
|||
/// </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 Rectangle : IEquatable<Rectangle> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="Rectangle"/> that has X, Y, Width, and Height values set to zero.
|
|||
/// </summary>
|
|||
public static readonly Rectangle Empty = default(Rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Rectangle"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="x">The horizontal position of the rectangle.</param>
|
|||
/// <param name="y">The vertical position of the rectangle.</param>
|
|||
/// <param name="width">The width of the rectangle.</param>
|
|||
/// <param name="height">The height of the rectangle.</param>
|
|||
public Rectangle(int x, int y, int width, int height) |
|||
{ |
|||
this.X = x; |
|||
this.Y = y; |
|||
this.Width = width; |
|||
this.Height = height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Rectangle"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="point">
|
|||
/// The <see cref="Point"/> which specifies the rectangles point in a two-dimensional plane.
|
|||
/// </param>
|
|||
/// <param name="size">
|
|||
/// The <see cref="Size"/> which specifies the rectangles height and width.
|
|||
/// </param>
|
|||
public Rectangle(Point point, Size size) |
|||
{ |
|||
this.X = point.X; |
|||
this.Y = point.Y; |
|||
this.Width = size.Width; |
|||
this.Height = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the x-coordinate of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int X { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the y-coordinate of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Y { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the width of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Width { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the height of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Height { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the coordinates of the upper-left corner of the rectangular region represented by this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public Point Location |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get => new Point(this.X, this.Y); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
set |
|||
{ |
|||
this.X = value.X; |
|||
this.Y = value.Y; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the size of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public Size Size |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get => new Size(this.Width, this.Height); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
set |
|||
{ |
|||
this.Width = value.Width; |
|||
this.Height = value.Height; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="Rectangle"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Gets the y-coordinate of the top edge of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Top |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.Y; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the x-coordinate of the right edge of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Right |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return unchecked(this.X + this.Width); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the y-coordinate of the bottom edge of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Bottom |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return unchecked(this.Y + this.Height); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the x-coordinate of the left edge of this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
public int Left |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.X; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="RectangleF"/> with the coordinates of the specified <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator RectangleF(Rectangle rectangle) => new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Vector4"/> with the coordinates of the specified <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator Vector4(Rectangle rectangle) => new Vector4(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Rectangle"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Rectangle"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Rectangle"/> 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 ==(Rectangle left, Rectangle right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Rectangle"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="Rectangle"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="Rectangle"/> 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 !=(Rectangle left, Rectangle right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="Rectangle"/> with the specified location and size. </summary>
|
|||
/// <param name="left">The left coordinate of the rectangle</param>
|
|||
/// <param name="top">The top coordinate of the rectangle</param>
|
|||
/// <param name="right">The right coordinate of the rectangle</param>
|
|||
/// <param name="bottom">The bottom coordinate of the rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
|
|||
// ReSharper disable once InconsistentNaming
|
|||
public static Rectangle FromLTRB(int left, int top, int right, int bottom) => new Rectangle(left, top, unchecked(right - left), unchecked(bottom - top)); |
|||
|
|||
/// <summary>
|
|||
/// Returns the center point of the given <see cref="Rectangle"/>
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Point Center(Rectangle rectangle) => new Point(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2)); |
|||
|
|||
/// <summary>
|
|||
/// Creates a rectangle that represents the intersection between <paramref name="a"/> and
|
|||
/// <paramref name="b"/>. If there is no intersection, an empty rectangle is returned.
|
|||
/// </summary>
|
|||
/// <param name="a">The first rectangle</param>
|
|||
/// <param name="b">The second rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Intersect(Rectangle a, Rectangle b) |
|||
{ |
|||
int x1 = Math.Max(a.X, b.X); |
|||
int x2 = Math.Min(a.Right, b.Right); |
|||
int y1 = Math.Max(a.Y, b.Y); |
|||
int y2 = Math.Min(a.Bottom, b.Bottom); |
|||
|
|||
if (x2 >= x1 && y2 >= y1) |
|||
{ |
|||
return new Rectangle(x1, y1, x2 - x1, y2 - y1); |
|||
} |
|||
|
|||
return Empty; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Rectangle"/> that is inflated by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <param name="x">The amount to inflate the width by</param>
|
|||
/// <param name="y">The amount to inflate the height by</param>
|
|||
/// <returns>A new <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Inflate(Rectangle rectangle, int x, int y) |
|||
{ |
|||
Rectangle r = rectangle; |
|||
r.Inflate(x, y); |
|||
return r; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="RectangleF"/> to a <see cref="Rectangle"/> by performing a ceiling operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Ceiling(RectangleF rectangle) |
|||
{ |
|||
unchecked |
|||
{ |
|||
return new Rectangle( |
|||
(int)MathF.Ceiling(rectangle.X), |
|||
(int)MathF.Ceiling(rectangle.Y), |
|||
(int)MathF.Ceiling(rectangle.Width), |
|||
(int)MathF.Ceiling(rectangle.Height)); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="RectangleF"/> to a <see cref="Rectangle"/> by performing a truncate operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Truncate(RectangleF rectangle) |
|||
{ |
|||
unchecked |
|||
{ |
|||
return new Rectangle( |
|||
(int)rectangle.X, |
|||
(int)rectangle.Y, |
|||
(int)rectangle.Width, |
|||
(int)rectangle.Height); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="RectangleF"/> to a <see cref="Rectangle"/> by performing a round operation on all the coordinates.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Round(RectangleF rectangle) |
|||
{ |
|||
unchecked |
|||
{ |
|||
return new Rectangle( |
|||
(int)MathF.Round(rectangle.X), |
|||
(int)MathF.Round(rectangle.Y), |
|||
(int)MathF.Round(rectangle.Width), |
|||
(int)MathF.Round(rectangle.Height)); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a rectangle that represents the union between <paramref name="a"/> and <paramref name="b"/>.
|
|||
/// </summary>
|
|||
/// <param name="a">The first rectangle</param>
|
|||
/// <param name="b">The second rectangle</param>
|
|||
/// <returns>The <see cref="Rectangle"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Rectangle Union(Rectangle a, Rectangle b) |
|||
{ |
|||
int x1 = Math.Min(a.X, b.X); |
|||
int x2 = Math.Max(a.Right, b.Right); |
|||
int y1 = Math.Min(a.Y, b.Y); |
|||
int y2 = Math.Max(a.Bottom, b.Bottom); |
|||
|
|||
return new Rectangle(x1, y1, x2 - x1, y2 - y1); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a Rectangle that represents the intersection between this Rectangle and the <paramref name="rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Intersect(Rectangle rectangle) |
|||
{ |
|||
Rectangle result = Intersect(rectangle, this); |
|||
|
|||
this.X = result.X; |
|||
this.Y = result.Y; |
|||
this.Width = result.Width; |
|||
this.Height = result.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Inflates this <see cref="Rectangle"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="width">The width</param>
|
|||
/// <param name="height">The height</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Inflate(int width, int height) |
|||
{ |
|||
unchecked |
|||
{ |
|||
this.X -= width; |
|||
this.Y -= height; |
|||
|
|||
this.Width += 2 * width; |
|||
this.Height += 2 * height; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Inflates this <see cref="Rectangle"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Inflate(Size size) => this.Inflate(size.Width, size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specfied point is contained within the rectangular region defined by
|
|||
/// this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-coordinate of the given point.</param>
|
|||
/// <param name="y">The y-coordinate of the given point.</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(int x, int y) => this.X <= x && x < this.Right && this.Y <= y && y < this.Bottom; |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specified point is contained within the rectangular region defined by this <see cref="Rectangle"/> .
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(Point point) => this.Contains(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the rectangular region represented by <paramref name="rectangle"/> is entirely contained
|
|||
/// within the rectangular region represented by this <see cref="Rectangle"/> .
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(Rectangle rectangle) => |
|||
(this.X <= rectangle.X) && (rectangle.Right <= this.Right) && |
|||
(this.Y <= rectangle.Y) && (rectangle.Bottom <= this.Bottom); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specfied <see cref="Rectangle"/> intersects the rectangular region defined by
|
|||
/// this <see cref="Rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The other Rectange </param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool IntersectsWith(Rectangle rectangle) => |
|||
(rectangle.X < this.Right) && (this.X < rectangle.Right) && |
|||
(rectangle.Y < this.Bottom) && (this.Y < rectangle.Bottom); |
|||
|
|||
/// <summary>
|
|||
/// Adjusts the location of this rectangle by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Offset(Point point) => this.Offset(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Adjusts the location of this rectangle 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(int dx, int dy) |
|||
{ |
|||
unchecked |
|||
{ |
|||
this.X += dx; |
|||
this.Y += dy; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() => this.GetHashCode(this); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "Rectangle [ Empty ]"; |
|||
} |
|||
|
|||
return $"Rectangle [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is Rectangle && this.Equals((Rectangle)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Rectangle other) => this.X == other.X && this.Y == other.Y && this.Width == other.Width && this.Height == other.Height; |
|||
|
|||
private int GetHashCode(Rectangle rectangle) |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = rectangle.X; |
|||
hashCode = (hashCode * 397) ^ rectangle.Y; |
|||
hashCode = (hashCode * 397) ^ rectangle.Width; |
|||
hashCode = (hashCode * 397) ^ rectangle.Height; |
|||
return hashCode; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,400 +0,0 @@ |
|||
// <copyright file="RectangleF.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>
|
|||
/// Stores a set of four single precision floating points that represent the location and size of a rectangle.
|
|||
/// </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 RectangleF : IEquatable<RectangleF> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="RectangleF"/> that has X, Y, Width, and Height values set to zero.
|
|||
/// </summary>
|
|||
public static readonly RectangleF Empty = default(RectangleF); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RectangleF"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="x">The horizontal position of the rectangle.</param>
|
|||
/// <param name="y">The vertical position of the rectangle.</param>
|
|||
/// <param name="width">The width of the rectangle.</param>
|
|||
/// <param name="height">The height of the rectangle.</param>
|
|||
public RectangleF(float x, float y, float width, float height) |
|||
{ |
|||
this.X = x; |
|||
this.Y = y; |
|||
this.Width = width; |
|||
this.Height = height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RectangleF"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="point">
|
|||
/// The <see cref="Point"/> which specifies the rectangles point in a two-dimensional plane.
|
|||
/// </param>
|
|||
/// <param name="size">
|
|||
/// The <see cref="Size"/> which specifies the rectangles height and width.
|
|||
/// </param>
|
|||
public RectangleF(PointF point, SizeF size) |
|||
{ |
|||
this.X = point.X; |
|||
this.Y = point.Y; |
|||
this.Width = size.Width; |
|||
this.Height = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the x-coordinate of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float X { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the y-coordinate of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Y { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the width of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Width { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the height of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Height { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the coordinates of the upper-left corner of the rectangular region represented by this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public PointF Location |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get => new PointF(this.X, this.Y); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
set |
|||
{ |
|||
this.X = value.X; |
|||
this.Y = value.Y; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the size of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public SizeF Size |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get => new SizeF(this.Width, this.Height); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
set |
|||
{ |
|||
this.Width = value.Width; |
|||
this.Height = value.Height; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="RectangleF"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => (this.Width <= 0) || (this.Height <= 0); |
|||
|
|||
/// <summary>
|
|||
/// Gets the y-coordinate of the top edge of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Top |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.Y; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the x-coordinate of the right edge of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Right |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.X + this.Width; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the y-coordinate of the bottom edge of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Bottom |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.Y + this.Height; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the x-coordinate of the left edge of this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
public float Left |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return this.X; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Rectangle"/> with the coordinates of the specified <see cref="RectangleF"/> by truncating each coordinate.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator Rectangle(RectangleF rectangle) => Rectangle.Truncate(rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="RectangleF"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="RectangleF"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="RectangleF"/> 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 ==(RectangleF left, RectangleF right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="RectangleF"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="RectangleF"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="RectangleF"/> 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 !=(RectangleF left, RectangleF right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="RectangleF"/> with the specified location and size. </summary>
|
|||
/// <param name="left">The left coordinate of the rectangle</param>
|
|||
/// <param name="top">The top coordinate of the rectangle</param>
|
|||
/// <param name="right">The right coordinate of the rectangle</param>
|
|||
/// <param name="bottom">The bottom coordinate of the rectangle</param>
|
|||
/// <returns>The <see cref="RectangleF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
|
|||
// ReSharper disable once InconsistentNaming
|
|||
public static RectangleF FromLTRB(float left, float top, float right, float bottom) => new RectangleF(left, top, right - left, bottom - top); |
|||
|
|||
/// <summary>
|
|||
/// Returns the center point of the given <see cref="RectangleF"/>
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="Point"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static PointF Center(RectangleF rectangle) => new PointF(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2)); |
|||
|
|||
/// <summary>
|
|||
/// Creates a rectangle that represents the intersection between <paramref name="a"/> and
|
|||
/// <paramref name="b"/>. If there is no intersection, an empty rectangle is returned.
|
|||
/// </summary>
|
|||
/// <param name="a">The first rectangle</param>
|
|||
/// <param name="b">The second rectangle</param>
|
|||
/// <returns>The <see cref="RectangleF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static RectangleF Intersect(RectangleF a, RectangleF b) |
|||
{ |
|||
float x1 = MathF.Max(a.X, b.X); |
|||
float x2 = MathF.Min(a.Right, b.Right); |
|||
float y1 = MathF.Max(a.Y, b.Y); |
|||
float y2 = MathF.Min(a.Bottom, b.Bottom); |
|||
|
|||
if (x2 >= x1 && y2 >= y1) |
|||
{ |
|||
return new RectangleF(x1, y1, x2 - x1, y2 - y1); |
|||
} |
|||
|
|||
return Empty; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="RectangleF"/> that is inflated by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <param name="x">The amount to inflate the width by</param>
|
|||
/// <param name="y">The amount to inflate the height by</param>
|
|||
/// <returns>A new <see cref="RectangleF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static RectangleF Inflate(RectangleF rectangle, float x, float y) |
|||
{ |
|||
RectangleF r = rectangle; |
|||
r.Inflate(x, y); |
|||
return r; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a rectangle that represents the union between <paramref name="a"/> and <paramref name="b"/>.
|
|||
/// </summary>
|
|||
/// <param name="a">The first rectangle</param>
|
|||
/// <param name="b">The second rectangle</param>
|
|||
/// <returns>The <see cref="RectangleF"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static RectangleF Union(RectangleF a, RectangleF b) |
|||
{ |
|||
float x1 = MathF.Min(a.X, b.X); |
|||
float x2 = MathF.Max(a.Right, b.Right); |
|||
float y1 = MathF.Min(a.Y, b.Y); |
|||
float y2 = MathF.Max(a.Bottom, b.Bottom); |
|||
|
|||
return new RectangleF(x1, y1, x2 - x1, y2 - y1); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a RectangleF that represents the intersection between this RectangleF and the <paramref name="rectangle"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Intersect(RectangleF rectangle) |
|||
{ |
|||
RectangleF result = Intersect(rectangle, this); |
|||
|
|||
this.X = result.X; |
|||
this.Y = result.Y; |
|||
this.Width = result.Width; |
|||
this.Height = result.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Inflates this <see cref="RectangleF"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="width">The width</param>
|
|||
/// <param name="height">The height</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Inflate(float width, float height) |
|||
{ |
|||
this.X -= width; |
|||
this.Y -= height; |
|||
|
|||
this.Width += 2 * width; |
|||
this.Height += 2 * height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Inflates this <see cref="RectangleF"/> by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Inflate(SizeF size) => this.Inflate(size.Width, size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specfied point is contained within the rectangular region defined by
|
|||
/// this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-coordinate of the given point.</param>
|
|||
/// <param name="y">The y-coordinate of the given point.</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(float x, float y) => this.X <= x && x < this.Right && this.Y <= y && y < this.Bottom; |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specified point is contained within the rectangular region defined by this <see cref="RectangleF"/> .
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(PointF point) => this.Contains(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the rectangular region represented by <paramref name="rectangle"/> is entirely contained
|
|||
/// within the rectangular region represented by this <see cref="RectangleF"/> .
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The rectangle</param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Contains(RectangleF rectangle) => |
|||
(this.X <= rectangle.X) && (rectangle.Right <= this.Right) && |
|||
(this.Y <= rectangle.Y) && (rectangle.Bottom <= this.Bottom); |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specfied <see cref="RectangleF"/> intersects the rectangular region defined by
|
|||
/// this <see cref="RectangleF"/>.
|
|||
/// </summary>
|
|||
/// <param name="rectangle">The other Rectange </param>
|
|||
/// <returns>The <see cref="bool"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool IntersectsWith(RectangleF rectangle) => |
|||
(rectangle.X < this.Right) && (this.X < rectangle.Right) && |
|||
(rectangle.Y < this.Bottom) && (this.Y < rectangle.Bottom); |
|||
|
|||
/// <summary>
|
|||
/// Adjusts the location of this rectangle by the specified amount.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public void Offset(PointF point) => this.Offset(point.X, point.Y); |
|||
|
|||
/// <summary>
|
|||
/// Adjusts the location of this rectangle 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; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() => this.GetHashCode(this); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "RectangleF [ Empty ]"; |
|||
} |
|||
|
|||
return $"RectangleF [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is RectangleF && this.Equals((RectangleF)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(RectangleF other) => this.X.Equals(other.X) && this.Y.Equals(other.Y) && this.Width.Equals(other.Width) && this.Height.Equals(other.Height); |
|||
|
|||
private int GetHashCode(RectangleF rectangle) |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = rectangle.X.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ rectangle.Y.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ rectangle.Width.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ rectangle.Height.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,225 +0,0 @@ |
|||
// <copyright file="Size.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 integers, 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 Size : IEquatable<Size> |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a <see cref="Size"/> that has Width and Height values set to zero.
|
|||
/// </summary>
|
|||
public static readonly Size Empty = default(Size); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Size"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The width and height of the size</param>
|
|||
public Size(int value) |
|||
: this() |
|||
{ |
|||
this.Width = value; |
|||
this.Height = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Size"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="width">The width of the size.</param>
|
|||
/// <param name="height">The height of the size.</param>
|
|||
public Size(int width, int height) |
|||
{ |
|||
this.Width = width; |
|||
this.Height = height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Size"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
public Size(Size size) |
|||
: this() |
|||
{ |
|||
this.Width = size.Width; |
|||
this.Height = size.Height; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Size"/> struct from the given <see cref="Point"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point</param>
|
|||
public Size(Point point) |
|||
{ |
|||
this.Width = point.X; |
|||
this.Height = point.Y; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the width of this <see cref="Size"/>.
|
|||
/// </summary>
|
|||
public int Width { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the height of this <see cref="Size"/>.
|
|||
/// </summary>
|
|||
public int Height { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this <see cref="Size"/> is empty.
|
|||
/// </summary>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public bool IsEmpty => this.Equals(Empty); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="SizeF"/> with the dimensions of the specified <see cref="Size"/>.
|
|||
/// </summary>
|
|||
/// <param name="size">The point</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static implicit operator SizeF(Size size) => new SizeF(size.Width, size.Height); |
|||
|
|||
/// <summary>
|
|||
/// Converts the given <see cref="Size"/> into a <see cref="Point"/>.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static explicit operator Point(Size size) => new Point(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="Size"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size operator +(Size left, Size 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="Size"/>
|
|||
/// </returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size operator -(Size left, Size right) => Subtract(left, right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Size"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Size"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Size"/> 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 ==(Size left, Size right) => left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="Size"/> objects for inequality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="Size"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="Size"/> 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 !=(Size left, Size right) => !left.Equals(right); |
|||
|
|||
/// <summary>
|
|||
/// Performs vector addition of two <see cref="Size"/> 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="Size"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size Add(Size left, Size right) => new Size(unchecked(left.Width + right.Width), unchecked(left.Height + right.Height)); |
|||
|
|||
/// <summary>
|
|||
/// Contracts a <see cref="Size"/> by another <see cref="Size"/>
|
|||
/// </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="Size"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size Subtract(Size left, Size right) => new Size(unchecked(left.Width - right.Width), unchecked(left.Height - right.Height)); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a ceiling operation on all the dimensions.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
/// <returns>The <see cref="Size"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size Ceiling(SizeF size) => new Size(unchecked((int)MathF.Ceiling(size.Width)), unchecked((int)MathF.Ceiling(size.Height))); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a round operation on all the dimensions.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
/// <returns>The <see cref="Size"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size Round(SizeF size) => new Size(unchecked((int)MathF.Round(size.Width)), unchecked((int)MathF.Round(size.Height))); |
|||
|
|||
/// <summary>
|
|||
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a round operation on all the dimensions.
|
|||
/// </summary>
|
|||
/// <param name="size">The size</param>
|
|||
/// <returns>The <see cref="Size"/></returns>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static Size Truncate(SizeF size) => new Size(unchecked((int)size.Width), unchecked((int)size.Height)); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() => this.GetHashCode(this); |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
if (this.IsEmpty) |
|||
{ |
|||
return "Size [ Empty ]"; |
|||
} |
|||
|
|||
return $"Size [ Width={this.Width}, Height={this.Height} ]"; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) => obj is Size && this.Equals((Size)obj); |
|||
|
|||
/// <inheritdoc/>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Size other) => this.Width == other.Width && this.Height == other.Height; |
|||
|
|||
/// <summary>
|
|||
/// Returns the hash code for this instance.
|
|||
/// </summary>
|
|||
/// <param name="size">
|
|||
/// The instance of <see cref="Size"/> 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(Size size) => size.Width ^ size.Height; |
|||
} |
|||
} |
|||
@ -1,179 +0,0 @@ |
|||
// <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(); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue