using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Theriapolis.Game.CodexUI.Core; /// /// Renders a 9-slice texture into an arbitrary destination rectangle: the /// four corners stay at their authored size, the four edges stretch along /// one axis, and the centre stretches both axes. Used for parchment cards, /// gilded borders, button backgrounds, and slot frames. /// /// Per-side inset values describe how many source-texture pixels the /// fixed-size corner+edge bands take. They must add up to less than the /// source texture's width/height in each axis or the centre band collapses. /// public readonly struct NineSliceInsets { public readonly int Left, Top, Right, Bottom; public NineSliceInsets(int uniform) : this(uniform, uniform, uniform, uniform) { } public NineSliceInsets(int l, int t, int r, int b) { Left = l; Top = t; Right = r; Bottom = b; } } public static class NineSlice { /// /// Draw a 9-slice tinted with /// into using as the corner sizes. /// public static void Draw(SpriteBatch sb, Texture2D texture, Rectangle dest, NineSliceInsets insets, Color tint) { int sw = texture.Width; int sh = texture.Height; int l = insets.Left, t = insets.Top, r = insets.Right, b = insets.Bottom; int cw = sw - l - r; // source center width int ch = sh - t - b; // source center height if (cw < 1) cw = 1; if (ch < 1) ch = 1; int dl = dest.X; int dt = dest.Y; int dcw = System.Math.Max(0, dest.Width - l - r); int dch = System.Math.Max(0, dest.Height - t - b); int dr = dest.X + dest.Width - r; int db = dest.Y + dest.Height - b; // Corners (1× scale) sb.Draw(texture, new Rectangle(dl, dt, l, t), new Rectangle(0, 0, l, t), tint); sb.Draw(texture, new Rectangle(dr, dt, r, t), new Rectangle(sw - r, 0, r, t), tint); sb.Draw(texture, new Rectangle(dl, db, l, b), new Rectangle(0, sh - b, l, b), tint); sb.Draw(texture, new Rectangle(dr, db, r, b), new Rectangle(sw - r, sh - b, r, b), tint); // Edges (stretched along their long axis) sb.Draw(texture, new Rectangle(dl + l, dt, dcw, t), new Rectangle(l, 0, cw, t), tint); sb.Draw(texture, new Rectangle(dl + l, db, dcw, b), new Rectangle(l, sh - b, cw, b), tint); sb.Draw(texture, new Rectangle(dl, dt + t, l, dch), new Rectangle(0, t, l, ch), tint); sb.Draw(texture, new Rectangle(dr, dt + t, r, dch), new Rectangle(sw - r, t, r, ch), tint); // Centre (stretched both axes) sb.Draw(texture, new Rectangle(dl + l, dt + t, dcw, dch), new Rectangle(l, t, cw, ch), tint); } }