64 lines
3.1 KiB
C#
64 lines
3.1 KiB
C#
|
|
using Microsoft.Xna.Framework;
|
|||
|
|
using Microsoft.Xna.Framework.Graphics;
|
|||
|
|
|
|||
|
|
namespace Theriapolis.Game.CodexUI.Core;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 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.
|
|||
|
|
/// </summary>
|
|||
|
|
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
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// Draw a 9-slice <paramref name="texture"/> tinted with <paramref name="tint"/>
|
|||
|
|
/// into <paramref name="dest"/> using <paramref name="insets"/> as the corner sizes.
|
|||
|
|
/// </summary>
|
|||
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|