2013-04-13 3 views
4

XNA имеет класс Spritefont, который имеет метод MeasureString, который может возвращать ширину и высоту string. Я пытаюсь понять, как создать метод, который будет эффективно возвращать строку с Environment.Newline, вставленным в нужные места, так что если она соответствует определенной ширине и высоте (для этого используется Rectangle).Как реализовать перенос слов?

+1

Я нашел это [XNA Word Wrapping] (http://www.xnawiki.com/index.php/Basic_Word_Wrapping). Другой поток с некоторым [кодом] (http://xboxforums.create.msdn.com/forums/p/10536/55295.aspx). –

+0

@AlinaB. Спасибо, что на самом деле решил мою проблему! Вы должны опубликовать код с этой страницы в качестве ответа, если вики исчезнут. И ответ принадлежит вам. – user1306322

ответ

7

Я нашел следующий код: 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(); 
} 
2

Чтобы добавить ответ Алины, здесь является расширенной версией этой функции, которая будет также LineBreak отдельных слов, которые больше, чем 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(); 
    } 
0

Чтобы обработать блок текста с возвратом каретки, вам необходимо изменить код, как показано ниже:

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(); 
    } 
+0

Спасибо за модификацию, он работает очень хорошо, но почему '' 'sb.Append (" \ r \ r ");' '' part? он просто добавляет двойные пробелы между словами, почему это не '' 'sb.Append (" \ r ");' '' (работает одинаково без лишних пробелов, по крайней мере, в примерах, которые я проверил). –

 Смежные вопросы

  • Нет связанных вопросов^_^