我正在编写一个从头开始的文本框,以便对语法高亮进行优化。但是,我需要以像素为单位获得字符的宽度,而不是像Graphics :: MeasureString给我的垃圾。我在网上找到了很多东西,特别是this,然而,它们似乎都没有用,或者没有考虑标签。我需要以最快的方式来测量字符的精确尺寸(以像素为单位)和制表符空间。我似乎无法想出这一个......
应该提到我正在使用C ++,CLR / CLI和GDI +
这是我的测量功能。在另一个函数中,它返回的RectangleF被绘制到屏幕:
RectangleF TextEditor::MeasureStringWidth(String^ ch, Graphics^ g, int xDistance, int lineYval)
{
RectangleF measured;
Font^ currentFont = gcnew Font(m_font, (float)m_fontSize);
StringFormat^ stringFormat = gcnew StringFormat;
RectangleF layout = RectangleF(xDistance,lineYval,35,m_fontHeightPix);
array<CharacterRange>^ charRanges = {CharacterRange(0,1)};
array<Region^>^ strRegions;
stringFormat->FormatFlags = StringFormatFlags::DirectionVertical;
stringFormat->SetMeasurableCharacterRanges(charRanges);
strRegions = g->MeasureCharacterRanges(ch, currentFont, layout, stringFormat);
if(strRegions->Length >= 1)
measured = strRegions[0]->GetBounds(g);
else
measured = RectangleF(0,0,0,0);
return measured;
}
我真的不明白MeasureCharacterRanges layoutRect参数的作用。我修改了Microsofts示例中的代码,仅使用或仅测量一个字符。
答案 0 :(得分:5)
您不应该使用Graphics
进行任何文字渲染。
从.NET Framework 2.0开始,不推荐使用Graphics.MeasureString
和Graphics.DrawString
,而是赞成新添加的帮助程序类TextRenderer
:
TextRenderer.MeasureText
TextRenderer.DrawText
GDI +文字渲染器已被放弃,10年多来没有任何改进或修复;以及软件渲染。
GDI渲染(TextRenderer
是一个简单的包装器)是硬件加速的,并继续得到渲染改进(连字,Uniscribe等)。
注意: GDI +文字呈现由Graphics.DrawString
和MeasureString
以下是Graphics
和TextRenderer
的衡量结果的比较:
GDI +测量不是“错误”,他们正在做他们想要的事情 - 如果它被渲染为原始文本,则返回文本的大小预期的字体作者(可以使用 Anti-alias rendering 实现):
但是没有人真正希望按照字体设计师的意图来查看文本,因为这会导致内容在像素边界上没有排列 - 使文本太模糊(就像你在苹果电脑)。理想情况下,文本应该在实际像素边界上对齐(即Windows 网格适合)
答案 1 :(得分:2)
MeasureCharacterRanges
就像MeasureString
一样,但更强大,更准确(也更慢)。