20

Aug

[XNA/Monogame] Implementare il Word-Wrapping

Ciao a tutti,

quando si sviluppa un’app con Visual Studio (o altri IDE che mettono a disposizione controlli per la UI) siamo abituati ad avere “gratis” la gestione del word-wrapping. Di solito è sufficiente impostare l’apposita property ed il controllo (TextBox e similari) fa tutto da solo.

In XNA/Monogame questo tipo di controlli non esiste e pertanto se vogliamo fare in modo che un testo vada a capo automaticamente per restare all’interno di un determinato spazio, lo dobbiamo gestire noi.

A tal proposito ho scritto un semplicissimo metodo che, dato lo SpriteFont, il testo e lo spazio massimo occupabile per ogni riga, restituisce il testo correttamente formattato (ovvero spezzato su più righe se necessario).

Il metodo è statico, in modo tale che possa essere utilizzato ogni qual volta ne avessimo bisogno senza creare istanze.

Ecco qui il codice:

   1: public static string TextWrapping(string texttoWrap, SpriteFont font, float maxLineWidth)
   2: {
   3:     //creo uno StringBuilder che conterrà il risultato
   4:     StringBuilder formattedText = new StringBuilder();
   5:  
   6:     //inizio a spezzare in "paragrafi" il testo nel caso ci siano già dei ritorni a capo impostati (\n)
   7:     string[] paragraphs = texttoWrap.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
   8:  
   9:     //per ogni paragrafo indento il testo
  10:     foreach (string paragraph in paragraphs)
  11:     {
  12:         float currentlineWidth = 0.0f;
  13:  
  14:         //ricavo un array con le parole del paragrafo
  15:         string[] words = paragraph.Split(' ');
  16:  
  17:         //ricavo lo spazio occupato dal blank
  18:         float spaceWidth = font.MeasureString(" ").X;
  19:  
  20:         foreach (string word in words)
  21:         {
  22:             //misuro quanto spazio occupa la parola
  23:             Vector2 size = font.MeasureString(word);
  24:  
  25:             //verifico se vado a superare la larghezza massima della riga
  26:             if (currentlineWidth + size.X < maxLineWidth)
  27:             {
  28:                 //se ci sta, aggiungo semplicemente la parola
  29:                 formattedText.Append(word + " ");
  30:                 currentlineWidth += size.X + spaceWidth;
  31:             }
  32:             else
  33:             {
  34:                 //se non ci sta vado a capo
  35:                 formattedText.Append("\n" + word + " ");
  36:                 currentlineWidth = size.X + spaceWidth;
  37:             }
  38:         }
  39:  
  40:         //alla fine di ogni paragrafo vado comunque a capo
  41:         formattedText.Append("\n");
  42:     }
  43:  
  44:     //ritorno il testo "wrappato"
  45:     return formattedText.ToString();
  46: }

 

Non è molta roba, ma può sempre tornare utile Sorriso

Alla prossima!

 

Marcello

by Marcello Marchetti on 8/20/2013