【问题标题】:C# String Length for Graphics图形的 C# 字符串长度
【发布时间】:2012-08-07 10:37:07
【问题描述】:

我开发了一个像 Word 这样的程序。为此,我需要将字符串写入同一“行”,并且我还希望能够以不同的方式格式化每个单词/字母/句子,控制颜色、大小、字体等。

所以我必须计算一个字符串的像素长度和高度,然后将它们排成一行。但是函数(Graphics) MeasureString 有一个问题,这个函数在字符串前面/后面放置了额外的长度。这个函数在空白方面也有一些问题。

我尝试了不同的 StringFormater,但每次它们返回的长度过长或不够。

是否存在用于在Graphics 对象上写入不同格式字符串的函数或用于计算字符串精确像素长度的函数?

【问题讨论】:

标签: c# graphics


【解决方案1】:

首先,要正确解决这是一个相当棘手的问题 - 您最好尝试找到可以为您解决此问题的现有控件(例如 RichTextBox)。

也就是说,如果您确实想这样做,那么这或多或少是解决此问题的正确方法,但是如果您查看MeasureString documentation,您会注意到您看到的行为是故意的

MeasureString 方法设计用于单个字符串 并在字符串前后包含少量额外空格 允许悬垂的字形。此外,DrawString 方法调整 字形点以优化显示质量并可能显示字符串 比 MeasureString 报告的要窄。获取合适的指标 对于布局中的相邻字符串(例如,在实现 格式化文本),使用MeasureCharacterRanges 方法或其中一种 MeasureString 方法采用StringFormat,并通过 GenericTypographic。此外,请确保 TextRenderingHint 用于 GraphicsAntiAlias

所以在我看来,您应该改用 Graphics.MeasureCharacterRanges Method

这是我准备的一个示例,交易以两种不同的颜色呈现一些文本。要试用,只需将其粘贴到新表单中

protected override void OnPaint(PaintEventArgs e)
{
    // This is where we wish to print our string
    var region = new RectangleF(50, 50, 200, 50);

    // This is the font we wish to use
    var font = new Font("Times New Roman", 16.0F);

    // Draw a string for comparison
    DrawString(e.Graphics, "RedBlack", font, Brushes.Black, new RectangleF(50, 150, 200, 50));

    // Draw the first string and keep a track of the Region it was rendered in
    var first = DrawString(e.Graphics, "Red", font, Brushes.Red, region);

    // Adjust the region we wish to print 
    region = new RectangleF(region.X + first.GetBounds(e.Graphics).Width, region.Y, region.Width, region.Height);

    // Draw the second string
    DrawString(e.Graphics, "Black", font, Brushes.Black, region);

    base.OnPaint(e);
}

private Region DrawString(Graphics g, string s, Font font, Brush brush, RectangleF layoutRectangle)
{
    var format = new StringFormat();
    format.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, s.Length) });

    g.DrawString(s, font, brush, layoutRectangle, format);
    return g.MeasureCharacterRanges(s, font, layoutRectangle, format)[0];
}

这就是它的样子

请注意,您需要小心剪辑 - 默认情况下,GDI 会为您将渲染的文本“换行”到新行,但这将不再起作用,您最终会得到类似这样的结果

此外,如果您尝试打印出具有不同字体/字体大小的文本,那么每种字体的“底部”都不会与您期望的对齐。尝试查看 Formatting text on a common baseline 以获取有关如何处理该问题的一些提示。

【讨论】:

    【解决方案2】:

    MeasureString 无疑是解决这个问题的正确方法。 看看这侧底部的示例http://msdn.microsoft.com/de-de/library/957webty(v=vs.80).aspx,因为我会说没有其他方法。

    【讨论】:

      猜你喜欢
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多