// 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}"; } }