使用DrawString()正确绘制文本

时间:2011-12-18 23:02:33

标签: c# winforms

我遇到Graphics.DrawString()方法的问题。我的UserControl使用等宽字体在面板上绘制,显然,DrawString()以这样的方式格式化文本,它不再是完全等宽的。我一直在使用StringFormat以期解决这个问题,但没有成功:

StringFormat sf = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.MeasureTrailingSpaces);

绘制文字的代码:

for (int i = 0; i < document.Text.Count; i++)
                g.DrawString(document.Text[i], Font, Brushes.Black, new PointF(offset - 2, offset + Font.Height * i), sf);

例如,在Consolas 9中绘制“eeeeeeee”时,偶尔会有两个e靠近另一个像素。有没有办法正确显示文本,等宽?

(我的实际问题:我从头开始制作自己的文本框控件,作为练习和乐趣。实际上它很顺利,但显示文本的面板应该能够根据鼠标点击位置定位插入符号由于Font的Height属性,找到正确的行很容易。但是,查找该行中的当前索引不是。对于非等宽字体,我无法想象一种确定插入符号索引的方法,但对于等宽字体它应该是可行的,因为符号的宽度是固定的。那么,也许有更好的方法来确定它?)

亲切的问候, Jacco

1 个答案:

答案 0 :(得分:4)

绘制等宽的。只是每个字符的宽度不是整数像素 - 每个字符可能是9.9像素宽。 (为了使角色清晰可见,它会在绘制时将每个角色捕捉到最近的像素,这就是为什么有时候你会看到两个更接近的像素。)

一个选项是使用AntiAlias标志,它将停止尝试将每个字符捕捉到最近的像素 - 它只是灰度 - 模糊边缘,因此间距看起来相对一致。但是,对于较小的字体大小,抗锯齿效果不佳。

或者您可以使用TextRenderer而不是Graphics.DrawString。 TextRenderer使用旧的GDI渲染(而不是像Graphics类那样的GDI +),因此它根本不进行子像素渲染 - 要么每个字符宽9像素,要么每个字符宽10像素。有时,旧技术更好。