XNA has Spritefont class, which has a MeasureString method, which can return the Width and Height of a string
. I'm trying to understand how to create a method that will efficiently return a string with Environment.Newline
inserted in the right places, so that if fits a certain Width and Height (Rectangle is used as a parameter for that).
Asked
Active
Viewed 4,448 times
5

user1306322
- 8,561
- 18
- 61
- 122
-
1I found this [XNA Word Wrapping](http://www.xnawiki.com/index.php/Basic_Word_Wrapping). Another thread with some [code](http://xboxforums.create.msdn.com/forums/p/10536/55295.aspx). – Alina B. Apr 13 '13 at 10:56
-
@AlinaB. Thanks, that actually solved my problem! You should post the code from that page as an answer, in case the wiki disappears. And the answer belongs to you. – user1306322 Apr 13 '13 at 11:26
3 Answers
8
I found following code: XNA - Basic Word Wrapping
public string WrapText(SpriteFont spriteFont, string text, float maxLineWidth)
{
string[] words = text.Split(' ');
StringBuilder sb = new StringBuilder();
float lineWidth = 0f;
float spaceWidth = spriteFont.MeasureString(" ").X;
foreach (string word in words)
{
Vector2 size = spriteFont.MeasureString(word);
if (lineWidth + size.X < maxLineWidth)
{
sb.Append(word + " ");
lineWidth += size.X + spaceWidth;
}
else
{
sb.Append("\n" + word + " ");
lineWidth = size.X + spaceWidth;
}
}
return sb.ToString();
}

Alina B.
- 1,256
- 8
- 18
2
To add to Alina's answer, here is an extended version of that function, that will also linebreak single words that are longer than maxLineWidth
public static string WrapText(SpriteFont font, string text, float maxLineWidth)
{
string[] words = text.Split(' ');
StringBuilder sb = new StringBuilder();
float lineWidth = 0f;
float spaceWidth = font.MeasureString(" ").X;
foreach (string word in words)
{
Vector2 size = font.MeasureString(word);
if (lineWidth + size.X < maxLineWidth)
{
sb.Append(word + " ");
lineWidth += size.X + spaceWidth;
}
else
{
if (size.X > maxLineWidth)
{
if (sb.ToString() == "")
{
sb.Append(WrapText(font, word.Insert(word.Length / 2, " ") + " ", maxLineWidth));
}
else
{
sb.Append("\n" + WrapText(font, word.Insert(word.Length / 2, " ") + " ", maxLineWidth));
}
}
else
{
sb.Append("\n" + word + " ");
lineWidth = size.X + spaceWidth;
}
}
}
return sb.ToString();
}

Erra
- 93
- 6
1
To handle a block of text with carriage returns you need to modify the code as below:
public static string WrapText(SpriteFont font, string text, float maxLineWidth)
{
string[] words = text.Split(' ');
StringBuilder sb = new StringBuilder();
float lineWidth = 0f;
float spaceWidth = font.MeasureString(" ").X;
foreach (string word in words)
{
Vector2 size = font.MeasureString(word);
if (word.Contains("\r"))
{
lineWidth = 0f;
sb.Append("\r \r" );
}
if (lineWidth + size.X < maxLineWidth )
{
sb.Append(word + " ");
lineWidth += size.X + spaceWidth;
}
else
{
if (size.X > maxLineWidth )
{
if (sb.ToString() == " ")
{
sb.Append(WrapText(font, word.Insert(word.Length / 2, " ") + " ", maxLineWidth));
}
else
{
sb.Append("\n" + WrapText(font, word.Insert(word.Length / 2, " ") + " ", maxLineWidth));
}
}
else
{
sb.Append("\n" + word + " ");
lineWidth = size.X + spaceWidth;
}
}
}
return sb.ToString();
}

zetar
- 1,225
- 2
- 20
- 45
-
Thanks for the modification it works pretty good, but why's the ```sb.Append("\r \r");``` part? it just add double spaces between words, why isn't it ```sb.Append("\r");``` (works the same without the extra spaces, at least in the examples I checked). – Ronen Ness Oct 31 '16 at 23:04