首先,How to measure width of character precisely?回答的问题对于这种情况并没有真正帮助,所以这不是重复的.
我有一个字符串.我绘制使用graphics.DrawString,但是当我需要在它之后添加另一个时,我需要知道前一个字符串的精确宽度.
为此,我使用graphics.MeasureString:
StringFormat format = new StringFormat(StringFormat.GenericTypographic);
format.Alignment = StringAlignment.Center;
format.Trimming = StringTrimming.None;
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
Run Code Online (Sandbox Code Playgroud)
我已经尝试了许多其他功能,就像TextRendered.MeasureText所有功能都失败一样,所有可能的参数组合.
MeasureString的上述组合最接近我的需要(它在大多数情况下都适用,特殊字符除外),但是使用像#破坏它这样的字符.宽度更短或更长.
有没有办法获得DrawString函数生成的文本的精确大小?DrawString如何计算绘图区域的大小?它必须显然是一些其他功能,因为尺寸总是不同的.
整个应用程序的源代码在这里https://gitorious.org/pidgeon/pidgeon-main/ (我使用它的文件,是https://gitorious.org/pidgeon/pidgeon-main/blobs/master/scrollback /SBABox.cs)
你只需要消除额外的宽度.您可以使用字符串格式执行此操作:
GdipStringFormatGetGenericTypographic()
Run Code Online (Sandbox Code Playgroud)
你也可以使用:
float doubleWidth = g.MeasureString(text+text,...).Width;
float singleWidth = g.MeasureString(text).Width;
float textWidth = doubleWidth-singleWidth;
Run Code Online (Sandbox Code Playgroud)
这将允许您使用其他语言,如日语.
在codeproject上,Pierre Anaud的解决方案是使用MeasureCharacterRanges,它返回一个与指定字符串的边界框完全匹配的区域:
static public int MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
{
System.Drawing.StringFormat format = new System.Drawing.StringFormat ();
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
var ranges = new System.Drawing.CharacterRange(0, text.Length);
System.Drawing.Region[] regions = new System.Drawing.Region[1];
format.SetMeasurableCharacterRanges (ranges);
regions = graphics.MeasureCharacterRanges (text, font, rect, format);
rect = regions[0].GetBounds (graphics);
return (int)(rect.Right + 1.0f);
}
Run Code Online (Sandbox Code Playgroud)
我参加聚会有点晚了,但我试图做类似的事情并偶然发现了这个问题。您可能已经在 MSDN 上的Graphics.MeasureString方法文档中看到了以下评论:
该MeasureString方法是专为个人使用的字符串,包括前和后弦的额外少量空间以允许悬垂字形。此外,DrawString方法调整字形点以优化显示质量,并且可能显示比MeasureString报告的字符串更窄的字符串。要获得适合布局中相邻字符串的指标(例如,在实现格式化文本时),请使用MeasureCharacterRanges方法或采用StringFormat并传递GenericTypographic的MeasureString方法之一。同时,确保TextRenderingHint的图形是抗锯齿。
您似乎试图遵循此建议,因为您将其StringFormat.GenericTypographic用作自定义StringFormat对象的起点。然而,该行
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
Run Code Online (Sandbox Code Playgroud)
有效地否定了您开始的事实,StringFormat.GenericTypographic因为它清除了任何先前设置的标志。您可能想要做的是StringFormatFlags.MeasureTrailingSpaces在保留其他标志的同时设置标志,如下所示:
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
Run Code Online (Sandbox Code Playgroud)