如何精确测量字符的宽度?

时间:2012-03-31 17:14:03

标签: c# .net width character

也许我有些不对劲,但是......我想模拟字符间距。 我将单词(文本)分成单个字符列表,测量它们的宽度,然后在位图上一个接一个地绘制它们。我想,渲染文本的整体宽度将与整个未分割字符串的宽度相同,但是有些错误。在循环中渲染字符显示更广泛的结果。有没有办法获得共同(预期)的结果?

这是一段代码:

private struct CharWidths
{
    public char Char;
    public float Width;
}

private List<CharWidths> CharacterWidths = new List<CharWidths>();

...

private void GetCharacterWidths(string Text, Bitmap BMP)
{
    int i;
    int l = Text.Length;
    CharacterWidths.Clear();
    Graphics g = Graphics.FromImage(BMP);

    CharWidths cw = new CharWidths();
    for (i = 0; i < l; i++)
    {
        Size textSize = TextRenderer.MeasureText(Text[i].ToString(), Font);
        cw.Char = Text[i];
        cw.Width = textSize.Width;
        CharacterWidths.Add(cw);
    }
}

...

public void RenderToBitmap(Bitmap BMP)
{
    //MessageBox.Show("color");

    Graphics g = Graphics.FromImage(BMP);
    GetCharacterWidths("Lyborko", BMP);

    int i;
    float X = 0;
    PointF P = new PointF(); 
    for (i = 0; i < CharacterWidths.Count; i++)
    {
        P.X = X;
        P.Y = 0;

        g.DrawString(CharacterWidths[i].Char.ToString(), Font, Brushes.White, P);

        X = X+CharacterWidths[i].Width;
    }

    P.X = 0;
    P.Y = 30;
    g.DrawString("Lyborko", Font, Brushes.White, P);
    // see the difference
}

Thanx很多

1 个答案:

答案 0 :(得分:2)

首先应该说没有一个银弹解决方案,但有一些关于主题的建议:

  1. 考虑到您通过调用TextRenderer.MeasureText来传递当前device context(您之后用于绘制字符串的同一个)并且知道一个简单的事实MeasureText只是在缺少该参数的情况创建一个与桌面兼容的新的并且调用DrawTextEx WindowsSDK函数,我会说首先使用MeasureText的重载,你在其中指定像第一个参数device context那样的你用于渲染文本。 可以有所作为。

  2. 如果失败,我会尝试使用Control.GetPreferredSize方法来猜测大多数预设屏幕上控件的可能渲染维度,所以实际上你未来字符串的位图的维度。为此,您可以创建一些临时控件,分配字符串,渲染和调用此函数。我很清楚这个解决方案可能很难适应您的应用程序架构,但可以可能产生更好的结果。

  3. 希望这有帮助。