// Copyright (c) Craftwork Games. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace MonoGame.Extended.Graphics;
///
/// Represents a region of a texture.
///
public class Texture2DRegion
{
///
/// Gets the name assigned to this texture region when it was created.
///
public string Name { get; }
///
/// Gets the texture associated with this texture region.
///
public Texture2D Texture { get; }
///
/// Gets the top-left x-coordinate of the texture region within the texture.
///
public int X { get; }
///
/// Gets the top-left y-coordinate of the texture region within the texture.
///
public int Y { get; }
///
/// Gets the width, in pixels, of the texture region.
///
public int Width { get; }
///
/// Gets the height, in pixels, of the texture region.
///
public int Height { get; }
///
/// Gets the size of the texture region.
///
public Size Size { get; }
///
/// Gets or sets the user-defined data associated with this texture region.
///
public object Tag { get; set; }
///
/// Gets the bounds of the texture region within the texture.
///
public Rectangle Bounds { get; }
///
/// Gets the top UV coordinate of the texture region.
///
public float TopUV { get; }
///
/// Gets the right UV coordinate of the texture region.
///
public float RightUV { get; }
///
/// Gets the bottom UV coordinate of the texture region.
///
public float BottomUV { get; }
///
/// Gets the left UV coordinate of the texture region.
///
public float LeftUV { get; }
///
/// Gets a value indicating whether this texture region is rotated 90 degrees clockwise in the atlas.
///
public bool IsRotated { get; }
///
/// Gets the original size of the texture region before trimming.
///
public Size OriginalSize { get; }
///
/// Gets the offset between the top-left corner of the original sprite and the top-left corner of the trimmed sprite.
///
public Vector2 Offset { get; }
///
/// Gets the normalized origin point of the texture region, or null if no origin is specified.
///
public Vector2? OriginNormalized { get; }
///
/// Initializes a new instance of the class representing the entire texture.
///
/// The texture to create the region from.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture)
: this(texture, 0, 0, texture.Width, texture.Height, null) { }
///
/// Initializes a new instance of the class representing the entire texture with the
/// specified name.
///
/// The texture to create the region from.
/// The name of the texture region.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture, string name)
: this(texture, 0, 0, texture.Bounds.Width, texture.Bounds.Height, null) { }
///
/// Initializes a new instance of the class with the specified region of the texture.
///
/// The texture to create the region from.
/// The region of the texture to use.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture, Rectangle region)
: this(texture, region.X, region.Y, region.Width, region.Height, null) { }
///
/// Initializes a new instance of the class with the specified region of the texture.
///
/// The texture to create the region from.
/// The top-left x-coordinate of the region within the texture.
/// The top-left y-coordinate of the region within the texture.
/// The width, in pixels, of the region.
/// The height, in pixels, of the region.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture, int x, int y, int width, int height)
: this(texture, x, y, width, height, null) { }
///
/// Initializes a new instance of the class with the specified region of the texture and
/// name.
///
/// The texture to create the region from.
/// The region of the texture to use.
/// The name of the texture region.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture, Rectangle region, string name)
: this(texture, region.X, region.Y, region.Width, region.Height, name) { }
///
/// Initializes a new instance of the class with the specified region of the texture and
/// name.
///
/// The texture to create the region from.
/// The top-left x-coordinate of the region within the texture.
/// The top-left y-coordinate of the region within the texture.
/// The width, in pixels, of the region.
/// The height, in pixels, of the region.
/// The name of the texture region.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture,int x, int y, int width, int height, string name)
: this(texture, x, y, width, height, false, new Size(width, height), Vector2.Zero, null, name) { }
///
/// Initializes a new instance of the class with the specified region of the texture,
/// original size, offset, origin, and name.
///
/// The texture to create the region from.
/// The top-left x-coordinate of the region within the texture.
/// The top-left y-coordinate of the region within the texture.
/// The width, in pixels, of the region.
/// The height, in pixels, of the region.
/// A value indicating whether this texture region is rotated 90 degrees clockwise in the atlas.
/// The original size of the texture region before trimming.
/// The offset between the top-left corner of the original sprite and the top-left corner of the trimmed sprite.
/// The origin point of the texture region, or null if no origin is specified.
/// The name of the texture region.
///
/// Thrown if is .
///
///
/// Thrown if has been disposed prior.
///
public Texture2DRegion(Texture2D texture, int x, int y, int width, int height, bool isRotated, Size originalSize, Vector2 offset, Vector2? originNormalized, string name)
{
ArgumentNullException.ThrowIfNull(texture);
if (texture.IsDisposed)
{
throw new ObjectDisposedException(nameof(texture));
}
if (string.IsNullOrEmpty(name))
{
name = $"{texture.Name}";
}
Name = name;
Texture = texture;
X = x;
Y = y;
Width = width;
Height = height;
IsRotated = isRotated;
OriginalSize = originalSize;
Offset = offset;
OriginNormalized = originNormalized;
Bounds = new Rectangle(x, y, width, height);
Size = new Size(width, height);
TopUV = Bounds.Top / (float)texture.Height;
RightUV = Bounds.Right / (float)texture.Width;
BottomUV = Bounds.Bottom / (float)texture.Height;
LeftUV = Bounds.Left / (float)texture.Width;
}
// Used for unit tests only
internal Texture2DRegion(string name, Rectangle bounds) : this(name, bounds.X, bounds.Y, bounds.Width, bounds.Height) { }
// Used for unit tests only
internal Texture2DRegion(string name, int x, int y, int width, int height)
{
Name = name;
Texture = null;
X = x;
Y = y;
Width = width;
Height = height;
Bounds = new Rectangle(x, y, width, height);
Size = new Size(width, height);
OriginalSize = Size;
Offset = Vector2.Zero;
OriginNormalized = null;
TopUV = Bounds.Top / 1.0f;
RightUV = Bounds.Right / 1.0f;
BottomUV = Bounds.Bottom / 1.0f;
LeftUV = Bounds.Left / 1.0f;
}
///
public override string ToString()
{
return $"{Name ?? string.Empty} {Bounds}";
}
}