#region Using Statements // System using System; using System.Collections.Generic; using System.Globalization; // XNA using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; // 3rd Party #endregion namespace IgnLib.Extensions { /// /// Extension methods appended to the SpriteBatch class. /// public static class SpriteBatchExtensions { /// /// Draws a int or long without generating garbage ( = w/o using .ToString() ) /// #region DrawGarbageFreeInt #region DrawIntXX Fields private static string[] digits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; private static string[] intCharBuffer = new string[10]; private static float[] intXPositionBuffer = new float[10]; private static readonly string intMinValue = Int32.MinValue.ToString(CultureInfo.InvariantCulture); private static string[] longCharBuffer = new string[20]; private static float[] longXPositionBuffer = new float[20]; private static readonly string longMinValue = Int64.MinValue.ToString(CultureInfo.InvariantCulture); #endregion #region DrawInt32 /// /// Extension method for SpriteBatch that draws an integer without allocating /// any memory. This function avoids garbage collections that are normally caused /// by calling Int32.ToString or String.Format. /// /// The SpriteBatch instance whose DrawString method will be invoked. /// The SpriteFont to draw the integer value with. /// The integer value to draw. /// The screen position specifying where to draw the value. /// The color of the text drawn. /// The next position on the line to draw text. This value uses position.Y and position.X plus the equivalent of calling spriteFont.MeasureString on value.ToString(CultureInfo.InvariantCulture). public static Vector2 DrawInt32( this SpriteBatch spriteBatch, SpriteFont spriteFont, int value, Vector2 position, Color color, float layerDepth) { if (spriteBatch == null) { throw new ArgumentNullException("spriteBatch"); } if (spriteFont == null) { throw new ArgumentNullException("spriteFont"); } Vector2 nextPosition = position; if (value == Int32.MinValue) { nextPosition.X = nextPosition.X + spriteFont.MeasureString(intMinValue).X; spriteBatch.DrawString(spriteFont, intMinValue, position, color); position = nextPosition; } else { if (value < 0) { nextPosition.X = nextPosition.X + spriteFont.MeasureString("-").X; spriteBatch.DrawString(spriteFont, "-", position, color, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth); value = -value; position = nextPosition; } int index = 0; do { int modulus = value % 10; value = value / 10; intCharBuffer[index] = digits[modulus]; intXPositionBuffer[index] = spriteFont.MeasureString(digits[modulus]).X; index += 1; } while (value > 0); for (int i = index - 1; i >= 0; --i) { nextPosition.X = nextPosition.X + intXPositionBuffer[i]; spriteBatch.DrawString(spriteFont, intCharBuffer[i], position, color, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth); position = nextPosition; } } return position; } #endregion #region DrawInt64 /// /// Extension method for SpriteBatch that draws a long integer without allocating /// any memory. This function avoids garbage collections that are normally caused /// by calling Int64.ToString or String.Format. /// /// The SpriteBatch instance whose DrawString method will be invoked. /// The SpriteFont to draw the integer value with. /// The long value to draw. /// The screen position specifying where to draw the value. /// The color of the text drawn. /// The next position on the line to draw text. This value uses position.Y and position.X plus the equivalent of calling spriteFont.MeasureString on value.ToString(CultureInfo.InvariantCulture). public static Vector2 DrawInt64( this SpriteBatch spriteBatch, SpriteFont spriteFont, long value, Vector2 position, Color color, float layerDepth) { if (spriteBatch == null) { throw new ArgumentNullException("spriteBatch"); } if (spriteFont == null) { throw new ArgumentNullException("spriteFont"); } Vector2 nextPosition = position; if (value == Int64.MinValue) { nextPosition.X = nextPosition.X + spriteFont.MeasureString(longMinValue).X; spriteBatch.DrawString(spriteFont, longMinValue, position, color); position = nextPosition; } else { if (value < 0) { nextPosition.X = nextPosition.X + spriteFont.MeasureString("-").X; spriteBatch.DrawString(spriteFont, "-", position, color, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth); value = -value; position = nextPosition; } int index = 0; do { long modulus = value % 10; value = value / 10; longCharBuffer[index] = digits[modulus]; longXPositionBuffer[index] = spriteFont.MeasureString(digits[modulus]).X; index += 1; } while (value > 0); for (int i = index - 1; i >= 0; --i) { nextPosition.X = nextPosition.X + longXPositionBuffer[i]; spriteBatch.DrawString(spriteFont, longCharBuffer[i], position, color, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, layerDepth); position = nextPosition; } } return position; } #endregion #endregion /// /// Draws shadowed string /// #region Shadowed String public static void DrawShadowedString(this SpriteBatch sb, SpriteFont font, string text, Vector2 position) { sb.DrawString(font, text, position, Color.Black, 0f, font.MeasureString(text) / 2f, 1.05f, SpriteEffects.None, 1f); // BLACK sb.DrawString(font, text, position, Color.White, 0f, font.MeasureString(text) / 2f, 1f, SpriteEffects.None, 1f); // WHITE } #endregion } }