using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework
{
public static class TextMeasure
{
private static SpriteFont tsf;
private static Dictionary<char, SpriteFont.Glyph> _glyphs;
private static SpriteFont.Glyph defaultGlyph;
private static char defaultfontchar = ' ';
public static void SetSpriteFont(SpriteFont s)
{
tsf = s;
_glyphs = tsf.GetGlyphs();
defaultGlyph = new SpriteFont.Glyph();
if (tsf.DefaultCharacter.HasValue)
{
defaultfontchar = (char)(tsf.DefaultCharacter.Value);
defaultGlyph = _glyphs[defaultfontchar];
}
}
public static string CutStringByBounds(string text, Rectangle boundRect)
{
var i = CutStringsEndingCharIndex(text, Vector2.One, boundRect);
return text.Substring(0, i);
}
public static string CutStringByBounds(SpriteFont sf, string text, Rectangle boundRect)
{
SetSpriteFont(sf);
var i = CutStringsEndingCharIndex(text, Vector2.One, boundRect);
return text.Substring(0, i);
}
public static string CutStringByBounds(SpriteFont sf, string text, Vector2 scale, Rectangle boundRect)
{
SetSpriteFont(sf);
var i = CutStringsEndingCharIndex(text, scale, boundRect);
return text.Substring(0, i);
}
public static string CutStringByBounds(string text, Vector2 scale, Rectangle boundRect)
{
var i = CutStringsEndingCharIndex(text, scale, boundRect);
return text.Substring(0, i);
}
public static int CutStringsEndingCharIndex(string text, Rectangle boundRect)
{
return CutStringsEndingCharIndex(text, Vector2.One, boundRect);
}
public static int CutStringsEndingCharIndex(SpriteFont sf, string text, Rectangle boundRect)
{
SetSpriteFont(sf);
return CutStringsEndingCharIndex(text, Vector2.One, boundRect);
}
public static int CutStringsEndingCharIndex(SpriteFont sf, string text, Vector2 scale, Rectangle boundRect)
{
SetSpriteFont(sf);
return CutStringsEndingCharIndex(text, scale, boundRect);
}
public static int CutStringsEndingCharIndex(string text, Vector2 scale, Rectangle boundRect)
{
var lineHeight = (float)tsf.LineSpacing;
var Spacing = tsf.Spacing;
Vector2 offset = Vector2.Zero;
Rectangle dest = new Rectangle();
var currentGlyph = SpriteFont.Glyph.Empty;
var firstGlyphOfLine = true;
int result = 0;
for (var i = 0; i < text.Length; i++)
{
var c = text[i];
if (c == '\r')
continue;
if (c == '\n')
{
offset.X = 0;
offset.Y += lineHeight;
firstGlyphOfLine = true;
continue;
}
if (_glyphs.ContainsKey(c))
currentGlyph = _glyphs[c];
else
if (!tsf.DefaultCharacter.HasValue)
throw new ArgumentException("Text Contains a Unresolvable Character");
else
currentGlyph = defaultGlyph;
if (firstGlyphOfLine)
{
offset.X = Math.Max(currentGlyph.LeftSideBearing, 0);
firstGlyphOfLine = false;
}
else
offset.X += Spacing + currentGlyph.LeftSideBearing;
var m = offset;
m.X += currentGlyph.Cropping.X;
m.Y += currentGlyph.Cropping.Y;
dest = new Rectangle(
(int)(m.X * scale.X),
(int)(m.Y * scale.Y),
(int)(currentGlyph.BoundsInTexture.Width * scale.X),
(int)(currentGlyph.BoundsInTexture.Height * scale.Y)
);
if (dest.Right < boundRect.Width)
{
result = i + 1;
}
else
{
return result;
}
offset.X += currentGlyph.Width + currentGlyph.RightSideBearing;
}
return result;
}
}
}