Click here to Skip to main content
15,884,177 members
Articles / Programming Languages / C#
Tip/Trick

How To Draw Text Aligned In A Rectangle XNA

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
2 Feb 2013CPOL2 min read 18.3K   2   1
Here we see how to align a Text

Introduction

Well, drawing string in XNA is very easy but to align a text in a rectangle for programmers is a problem. So here we go to solve this problem. In this tip, 9 different aligning are supported:

  1. Top Left
  2. Middle Left
  3. Bottom Left
  4. Top Center
  5. Middle Center
  6. Bottom Center
  7. Top Right
  8. Middle Right
  9. Bottom Right

Using the Code

So here we go.

Well struct is first. I like them, they are the most wonderful things in programming, a structure of data.

So here we clear our mind about what a text might need. We provide kinds of alignment here in an enum structure and then we define our aligned Text features:

C#
public enum TextAlignment
{
    TopLeft = 0,
    MiddleLeft = 1,
    BottomLeft = 2,
    TopCenter = 3,
    MiddleCenter = 4,
    BottomCenter = 5,
    TopRight = 6,
    MiddleRight = 7,
    BottomRight = 8,

}
public struct AlignedText
{
    public int key;
    public string myText;
    public int FontSize;
    public Rectangle rect;
    public Color mycolor;
    public string strplaceOfUse;
    public bool ShouldItBeShownInThisScreen;
    public int HorizontalMargin;
    public string Action;
    public TextAlignment Alignment;
    public Vector2 FontOrigin;
    public float scale;
    public Vector2 FinalPos;
}

Now, we create a class to give an aligned text to us:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Language_Learning_Application
{
    public class clsTextAlignment
    {
        public AlignedText TextHelper(AlignedText myAlignedText,SpriteFont myFont)
        {
            AlignedText ReturnAlignmentText = new AlignedText();
            ////////////////////////////////////////////////////////////////////////////////////
            Vector2 position = new Vector2(myAlignedText.rect.Width, myAlignedText.rect.Height);
            SpriteFont  font = myFont;
            string fontText = myAlignedText.myText;
            Vector2 fontPosition = position;
            TextAlignment fontAlignment = myAlignedText.Alignment;
            float fontScale = myAlignedText.scale;
            Color fontColor = myAlignedText.mycolor;
            Vector2 fontOrigin = Vector2.Zero;
            Vector2 fontSize = font.MeasureString(fontText);

            //Horizontal alignment
            if (fontAlignment == TextAlignment.TopCenter ||
                fontAlignment == TextAlignment.MiddleCenter ||
                fontAlignment == TextAlignment.BottomCenter)
            {
                fontOrigin.X = fontSize.X / 2;
            }
            else if (fontAlignment == TextAlignment.TopRight ||
                     fontAlignment == TextAlignment.MiddleRight ||
                     fontAlignment == TextAlignment.BottomRight)
            {
                fontOrigin.X = fontSize.X;
            }

            //Vertical alignment
            if (fontAlignment == TextAlignment.MiddleLeft ||
                fontAlignment == TextAlignment.MiddleCenter ||
                fontAlignment == TextAlignment.MiddleRight)
            {
                fontOrigin.Y = fontSize.Y / 2;
            }
            else if (fontAlignment == TextAlignment.BottomLeft ||
                     fontAlignment == TextAlignment.BottomCenter ||
                     fontAlignment == TextAlignment.BottomRight)
            {
                fontOrigin.Y = fontSize.Y;
            }
           //fontOrigin.X =fontOrigin.X- myAlignedText.rect.X;
           //fontOrigin.Y = fontOrigin.Y - myAlignedText.rect.Y;
            ReturnAlignmentText = myAlignedText;
            ReturnAlignmentText.FontOrigin = fontOrigin;
            ///////////////////////////////////////////////////
            if (fontAlignment == TextAlignment.TopLeft)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Left,myAlignedText.rect.Top);
            }
            if (fontAlignment == TextAlignment.TopRight)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Right, myAlignedText.rect.Top);
            }
            if (fontAlignment == TextAlignment.TopCenter)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Width / 2 + 
                myAlignedText.rect.X, myAlignedText.rect.Top);
            }
            if (fontAlignment == TextAlignment.BottomLeft)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Left, myAlignedText.rect.Bottom);
            }
            if (fontAlignment == TextAlignment.BottomRight)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Right, myAlignedText.rect.Bottom);
            }
            if (fontAlignment == TextAlignment.BottomCenter)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Width / 2 + 
                myAlignedText.rect.X, myAlignedText.rect.Bottom);
            }
            if (fontAlignment == TextAlignment.MiddleLeft)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Left, 
                myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
            }
            if (fontAlignment == TextAlignment.MiddleRight)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Right, 
                myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
            }
            if (fontAlignment == TextAlignment.MiddleCenter)
            {
                ReturnAlignmentText.FinalPos = 
                new Vector2(myAlignedText.rect.Width / 2 + 
                myAlignedText.rect.X, myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
            }
            return ReturnAlignmentText;
        }       
    }
}

So the problem was easily solved, now we go for drawing our text in a rectangle.

Now we define our variables here:

C#
public AlignedText myAlignedText_NumberOfTheWords;
C#
public AlignedText[] myAlignedTexts = new AlignedText[1];

We use array to draw many of these types of text everywhere, here I just want to draw one of them.

Initializing is the most important thing you should learn, here we go:

  • Remember that key is needed when you may want to have the trace of things in an arraylist
  • myText is the text you want to show in the rectangle
  • Fontsize is our font size
  • Horizontal margin is our margin
  • Rect here is defined with its margin
  • strplaceof use is the state of your program where you may use the text
  • You can hide the text by "Should it be shown in this Screen" parameter
  • Action here says that our text does not do anything except showing a text
  • You can set the alignment what you want (there are 9 of them here)
  • Font origin is what you should not change, it's just helping to have our modification position data
  • The scale is what xna uses to scale things.
C#
//myAlignedText_NumberOfTheWords
           myAlignedText_NumberOfTheWords.key=0;
           myAlignedText_NumberOfTheWords.myText="hello";
           myAlignedText_NumberOfTheWords.FontSize=22;
           myAlignedText_NumberOfTheWords.HorizontalMargin=50;
           myAlignedText_NumberOfTheWords.rect = new Rectangle
           (0 + 10 + myAlignedText_NumberOfTheWords.HorizontalMargin,
           0 + 10, 300 -2* myAlignedText_NumberOfTheWords.HorizontalMargin, 200);
           myAlignedText_NumberOfTheWords.mycolor=Color.Blue;
           myAlignedText_NumberOfTheWords.strplaceOfUse = "AddNewWords_Word";
           myAlignedText_NumberOfTheWords.ShouldItBeShownInThisScreen=false;
           myAlignedText_NumberOfTheWords.Action="Text";
           myAlignedText_NumberOfTheWords.Alignment=TextAlignment.MiddleCenter;
           myAlignedText_NumberOfTheWords.FontOrigin=Vector2.Zero;
           myAlignedText_NumberOfTheWords.scale=1;

Now that we initialize our text, we should go for drawing it on the screen.

My drawing engine is like this:

C#
protected override void Draw(GameTime gameTime)
       {
           GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);
           // TODO: Add your drawing code here
           spriteBatch.Begin();
           clsMyDefenition.DrawAlignedTexts(spriteBatch);
           spriteBatch.End();
           // TODO: Add your drawing code here
           base.Draw(gameTime);
       }

I use another class "clsMyDefenition" to draw the alignedText:

C#
public void DrawAlignedTexts(SpriteBatch mybatch)
      {
          for (int i = 0; i < myAlignedTexts.Length; i++)
          {
              if (myAlignedTexts[i].ShouldItBeShownInThisScreen)
              {
                  AlignedText txtToBeDrawn=myclsTextAlignment.TextHelper
                  (myAlignedTexts[i],fncGivemeFont(myTexts[i].FontSize));
                  mybatch.DrawString(fncGivemeFont(myTexts[i].FontSize),
                  myAlignedTexts[i].myText, txtToBeDrawn.FinalPos,
                  myAlignedTexts[i].mycolor, 0f, txtToBeDrawn.FontOrigin,
                  myAlignedTexts[i].scale, SpriteEffects.None, 0);
              }
          }
      }

To pass our font, I created a function:

C#
//
       public SpriteFont fncGivemeFont(int fontsize)
       {
           string BaseDirectory = ".";
           SpriteFont myfont=null;
           switch (fontsize)
           {
               case 14:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont14");
                   break;
               }
               case 16:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont16");
                   break;
               }
               case 18:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont18");
                   break;
               }
               case 20:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont20");
                   break;
               }
               case 22:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont22");
                   break;
               }
               default:
               {
                   myfont = content.Load<SpriteFont>
                   (BaseDirectory + "\\Font\\myfont14");
                   break;
               }
           }
           return myfont;
       }

Points of Interest

So here, we learned how to align our text in a rectangle in 9 forms. Before that, you learnt how to wrap font for using in a textbox. Cheers, now you know lots of ways to draw your strings on screen.

To hear comments from you may encourage me to put more tutorial on the web. I will be happy to know your ideas about my programming style and if I have some limitations in this tutorial.

History

  • Started it in 1/24/2013

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
Italy Italy
Education:

NODET 2003-2007
B.Sc. Electrical Power Engineering 2007–2012

Work:

T.G.D. Co.(Power,Software) July 2010 -February 2012
Artnous Co.(Power) July 2010 -February 2012
Savay Co.(Software) September 2011- July 2012

Comments and Discussions

 
QuestionHow can get the content object Pin
Member 999133819-Dec-13 22:47
Member 999133819-Dec-13 22:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.