summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs')
-rw-r--r--Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs113
1 files changed, 113 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs
new file mode 100644
index 0000000..0ec6b86
--- /dev/null
+++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasExtensions.cs
@@ -0,0 +1,113 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace MonoGame.Extended.TextureAtlases
+{
+ public static class TextureAtlasExtensions
+ {
+ public static void Draw(this SpriteBatch spriteBatch, TextureRegion2D textureRegion, Vector2 position, Color color, Rectangle? clippingRectangle = null)
+ {
+ Draw(spriteBatch, textureRegion, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0, clippingRectangle);
+ }
+
+ public static void Draw(this SpriteBatch spriteBatch, TextureRegion2D textureRegion, Vector2 position, Color color,
+ float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth, Rectangle? clippingRectangle = null)
+ {
+ var sourceRectangle = textureRegion.Bounds;
+
+ if (clippingRectangle.HasValue)
+ {
+ var x = (int)(position.X - origin.X);
+ var y = (int)(position.Y - origin.Y);
+ var width = (int)(textureRegion.Width * scale.X);
+ var height = (int)(textureRegion.Height * scale.Y);
+ var destinationRectangle = new Rectangle(x, y, width, height);
+
+ sourceRectangle = ClipSourceRectangle(textureRegion.Bounds, destinationRectangle, clippingRectangle.Value);
+ position.X += sourceRectangle.X - textureRegion.Bounds.X;
+ position.Y += sourceRectangle.Y - textureRegion.Bounds.Y;
+
+ if(sourceRectangle.Width <= 0 || sourceRectangle.Height <= 0)
+ return;
+ }
+
+ spriteBatch.Draw(textureRegion.Texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
+ }
+
+ public static void Draw(this SpriteBatch spriteBatch, TextureRegion2D textureRegion, Rectangle destinationRectangle, Color color, Rectangle? clippingRectangle = null)
+ {
+ var ninePatchRegion = textureRegion as NinePatchRegion2D;
+
+ if (ninePatchRegion != null)
+ Draw(spriteBatch, ninePatchRegion, destinationRectangle, color, clippingRectangle);
+ else
+ Draw(spriteBatch, textureRegion.Texture, textureRegion.Bounds, destinationRectangle, color, clippingRectangle);
+ }
+
+ public static void Draw(this SpriteBatch spriteBatch, NinePatchRegion2D ninePatchRegion, Rectangle destinationRectangle, Color color, Rectangle? clippingRectangle = null)
+ {
+ var destinationPatches = ninePatchRegion.CreatePatches(destinationRectangle);
+ var sourcePatches = ninePatchRegion.SourcePatches;
+
+ for (var i = 0; i < sourcePatches.Length; i++)
+ {
+ var sourcePatch = sourcePatches[i];
+ var destinationPatch = destinationPatches[i];
+
+ if (clippingRectangle.HasValue)
+ {
+ sourcePatch = ClipSourceRectangle(sourcePatch, destinationPatch, clippingRectangle.Value);
+ destinationPatch = ClipDestinationRectangle(destinationPatch, clippingRectangle.Value);
+ Draw(spriteBatch, ninePatchRegion.Texture, sourcePatch, destinationPatch, color, clippingRectangle);
+ }
+ else
+ {
+ if (destinationPatch.Width > 0 && destinationPatch.Height > 0)
+ spriteBatch.Draw(ninePatchRegion.Texture, sourceRectangle: sourcePatch, destinationRectangle: destinationPatch, color: color);
+ }
+ }
+ }
+
+ public static void Draw(this SpriteBatch spriteBatch, Texture2D texture, Rectangle sourceRectangle, Rectangle destinationRectangle, Color color, Rectangle? clippingRectangle)
+ {
+ if (clippingRectangle.HasValue)
+ {
+ sourceRectangle = ClipSourceRectangle(sourceRectangle, destinationRectangle, clippingRectangle.Value);
+ destinationRectangle = ClipDestinationRectangle(destinationRectangle, clippingRectangle.Value);
+ }
+
+ if (destinationRectangle.Width > 0 && destinationRectangle.Height > 0)
+ spriteBatch.Draw(texture, destinationRectangle, sourceRectangle, color);
+ }
+
+ private static Rectangle ClipSourceRectangle(Rectangle sourceRectangle, Rectangle destinationRectangle, Rectangle clippingRectangle)
+ {
+ var left = (float)(clippingRectangle.Left - destinationRectangle.Left);
+ var right = (float)(destinationRectangle.Right - clippingRectangle.Right);
+ var top = (float)(clippingRectangle.Top - destinationRectangle.Top);
+ var bottom = (float)(destinationRectangle.Bottom - clippingRectangle.Bottom);
+ var x = left > 0 ? left : 0;
+ var y = top > 0 ? top : 0;
+ var w = (right > 0 ? right : 0) + x;
+ var h = (bottom > 0 ? bottom : 0) + y;
+
+ var scaleX = (float)destinationRectangle.Width / sourceRectangle.Width;
+ var scaleY = (float)destinationRectangle.Height / sourceRectangle.Height;
+ x /= scaleX;
+ y /= scaleY;
+ w /= scaleX;
+ h /= scaleY;
+
+ return new Rectangle((int)(sourceRectangle.X + x), (int)(sourceRectangle.Y + y), (int)(sourceRectangle.Width - w), (int)(sourceRectangle.Height - h));
+ }
+
+ private static Rectangle ClipDestinationRectangle(Rectangle destinationRectangle, Rectangle clippingRectangle)
+ {
+ var left = clippingRectangle.Left < destinationRectangle.Left ? destinationRectangle.Left : clippingRectangle.Left;
+ var top = clippingRectangle.Top < destinationRectangle.Top ? destinationRectangle.Top : clippingRectangle.Top;
+ var bottom = clippingRectangle.Bottom < destinationRectangle.Bottom ? clippingRectangle.Bottom : destinationRectangle.Bottom;
+ var right = clippingRectangle.Right < destinationRectangle.Right ? clippingRectangle.Right : destinationRectangle.Right;
+ return new Rectangle(left, top, right - left, bottom - top);
+ }
+ }
+} \ No newline at end of file