如何实现文字自动换行?

5

XNA有一个Spritefont类,其中有一个MeasureString方法,可以返回string的宽度和高度。我正在尝试理解如何创建一个方法,以便有效地返回一个带有正确换行符Environment.Newline的字符串,使其适合特定的宽度和高度(矩形用作参数)。


1
我找到了这个XNA自动换行。还有一个帖子包含一些代码 - Alina B.
@AlinaB。谢谢,那真的解决了我的问题!你应该将那个页面上的代码作为答案发布,以防维基消失。而这个答案属于你。 - user1306322
3个回答

8
我找到了以下代码:XNA - 基本的单词换行
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

补充Alina的回答,这是一个扩展版本的函数,它也会在单词长度超过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();
    }

1
为了处理带有回车符的文本块,您需要按照以下方式修改代码:
  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();
    }

感谢您的修改,它运行得非常好。但是为什么要加上sb.Append("\r \r");这一部分呢?它只是在单词之间添加了双倍空格,为什么不是sb.Append("\r");(在我检查的示例中,没有额外的空格也可以正常工作)? - Ronen Ness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接