/// <summary>
        /// Draws a multi-string.
        /// WARNING! This grows more CPU-intensive as the number of words grow (only if word wrap enabled). It is recommended to use the DrawMultiLineText method instead - it uses caching.
        /// </summary>
        /// <param name="fnt">A reference to a SpriteFont object.</param>
        /// <param name="text">The text to be drawn. <remarks>If the text contains \n it
        /// will be treated as a new line marker and the text will drawn acordingy.</remarks></param>
        /// <param name="r">The screen rectangle that the rext should be drawn inside of.</param>
        /// <param name="col">The color of the text that will be drawn.</param>
        /// <param name="align">Specified the alignment within the specified screen rectangle.</param>
        /// <param name="textBounds">Returns a rectangle representing the size of the bouds of
        /// the text that was drawn.</param>
        /// <param name="cachedLines">This parameter is internal. Do not use it, merely throw away the variable.</param>
        private static void SetupNewMultilineString(FontFamily fnt, string text, Rectangle r,
                                                    Color col, TextAlignment align, out Rectangle textBounds, out List <MultilineFragment> cachedLines)
        {
            textBounds  = r;
            cachedLines = new List <MultilineFragment>();
            if (text == string.Empty)
            {
                return;
            }

            Data d = new Data();

            d.FontGroup          = Fonts[fnt];
            d.ReadyFragment      = new StringBuilder();
            d.Builder            = new StringBuilder();
            d.CurrentFont        = d.FontGroup.Regular;
            d.CurrentX           = 0;
            d.CurrentY           = 0;
            d.TotalNumberOfLines = 0;
            d.Width      = r.Width;
            d.Height     = r.Height;
            d.IsBold     = false;
            d.IsItalics  = false;
            d.LineHeight = d.FontGroup.Regular.LineSpacing;
            d.Color      = col;
            d.End        = false;
            d.Lines      = new List <List <MultilineFragment> >();
            d.ThisLine   = new List <MultilineFragment>();
            foreach (char t in text)
            {
                if (t == '{')
                {
                    // Flush and write.
                    Primitives.FlushAndWrite(d);
                    // Ready to change mode.
                }
                else if (t == '}')
                {
                    // Change mode.
                    switch (d.Builder.ToString())
                    {
                    case "b": d.IsBold = !d.IsBold; d.UpdateFont(); break;

                    case "i": d.IsItalics = !d.IsItalics; d.UpdateFont(); break;

                    case "/b": d.IsBold = !d.IsBold; d.UpdateFont(); break;

                    case "/i":
                        d.IsItalics = !d.IsItalics; d.UpdateFont(); break;

                    default:
                        string tag = d.Builder.ToString();
                        if (tag.StartsWith("icon:"))
                        {
                            Texture2D icon = Library.Icons[tag.Substring(5)];
                            d.Builder.Clear();
                            // Now add icon.
                            int iconwidth      = d.LineHeight;
                            int remainingSpace = (int)(d.Width - d.CurrentX);
                            if (remainingSpace > iconwidth + 3)
                            {
                                d.ThisLine.Add(new MultilineFragment(icon,
                                                                     new Vector2(d.CurrentX, d.CurrentY), iconwidth));
                                d.CurrentX += iconwidth + 3;
                            }
                            else
                            {
                                Primitives.FlushAndWrite(d);
                                Primitives.GoToNextLine(d);

                                d.ThisLine.Add(new MultilineFragment(icon,
                                                                     new Vector2(d.CurrentX, d.CurrentY), iconwidth));
                                d.CurrentX += iconwidth + 3;
                            }
                            break;
                        }
                        d.Color = Primitives.ColorFromString(tag);
                        if (tag[0] == '/')
                        {
                            d.Color = col;
                        }
                        break;
                    }
                    d.Builder.Clear();
                }
                else if (t == ' ')
                {
                    // Flush.
                    // Add builder to ready.
                    string without = d.ReadyFragment.ToString();
                    d.ReadyFragment.Append(d.Builder);
                    if (d.CurrentFont.MeasureString(d.ReadyFragment.ToString()).X <= d.Width - d.CurrentX)
                    {
                        // It will fit.
                        d.Builder.Clear();
                        d.Builder.Append(' ');
                    }
                    else
                    {
                        // It would not fit.
                        d.ReadyFragment = new StringBuilder(without);
                        string newone = d.Builder.ToString();
                        d.Builder = new StringBuilder();
                        Primitives.FlushAndWrite(d);
                        Primitives.GoToNextLine(d);
                        d.Builder.Append(newone);
                        Primitives.FlushAndWrite(d);
                        d.Builder.Clear();
                        d.Builder.Append(' ');
                    }
                    // Write if overflowing.
                }
                else if (t == '\n')
                {
                    // Flush and write.
                    Primitives.FlushAndWrite(d);
                    // Skip to new line automatically.
                    Primitives.GoToNextLine(d);
                }
                else
                {
                    d.Builder.Append(t);
                }
                if (d.End)
                {
                    break;
                }
            }
            // Flush and write.
            FlushAndWrite(d);
            FinishLine(d);
            d.TotalNumberOfLines += 1;
            // Modify for non-top-left.

            // Output.
            textBounds = new Rectangle(r.X, r.Y, (int)d.Maximumwidthencountered, d.TotalNumberOfLines * d.LineHeight);
            int yoffset = 0;

            switch (align)
            {
            case TextAlignment.TopLeft:
            case TextAlignment.Top:
            case TextAlignment.TopRight:
                break;

            case TextAlignment.Bottom:
            case TextAlignment.BottomLeft:
            case TextAlignment.BottomRight:
                yoffset = r.Height - d.TotalNumberOfLines * d.LineHeight;
                break;

            case TextAlignment.Middle:
            case TextAlignment.Left:
            case TextAlignment.Right:
                yoffset = (r.Height - (d.TotalNumberOfLines * d.LineHeight)) / 2;
                break;
            }
            foreach (var line in d.Lines)
            {
                foreach (var fragment in line)
                {
                    if (fragment.Text == "")
                    {
                        continue;
                    }
                    float xoffset   = 0;
                    float lineWidth = line.Sum(frg => frg.Width);
                    switch (align)
                    {
                    case TextAlignment.Right:
                    case TextAlignment.TopRight:
                    case TextAlignment.BottomRight:
                        xoffset = r.Width - lineWidth;
                        break;

                    case TextAlignment.Middle:
                    case TextAlignment.Top:
                    case TextAlignment.Bottom:
                        xoffset = (r.Width - lineWidth) / 2;
                        break;
                    }
                    fragment.PositionOffset += new Vector2(xoffset, yoffset);
                    fragment.PositionOffset  = new Vector2((int)fragment.PositionOffset.X, (int)fragment.PositionOffset.Y);
                    cachedLines.Add(fragment);
                }
            }
        }