2011-12-18 239 views
3

我遇到了Graphics.DrawString()方法的问题。我的UserControl使用等宽字体在面板上绘制,显然,DrawString()以这种方式格式化文本,使其不再是完全等宽的。我一直在使用中修复这个,希望可以的StringFormat,但没有成功:使用DrawString()正确绘制文本

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); 

例如,绘制在索拉9“eeeeeeee”,当,不时地,两个e将接近另一个像素1个像素。有没有办法正确显示文本,等宽? (我的实际问题是:我从头开始制作自己的文本框控件,作为一个练习和乐趣,实际上它很顺利,但是显示文本的面板应该能够根据鼠标点击来定位插入符号由于字体的高度属性,查找正确的行很容易,但是找到该行中的当前索引不是,对于非等宽字体,我无法想象一种方法来确定插入索引,但是对于等宽字体字体应该是可行的,因为符号的宽度是固定的,所以,也许有更好的方法来确定这一点?)

亲切的问候, Jacco

回答

4

绘制等宽。只是每个字符的宽度不是整数像素 - 每个字符可能是9.9像素宽。 (为了保持字符清晰,在绘制时将它们对齐到最接近的像素,这就是为什么您有时会看到两个更接近的原因。)

一个选项是使用AntiAlias标志,该标志将停止尝试将每个字符捕捉到最接近的像素 - 它只是灰度 - 模糊边缘,因此整个间距看起来相对一致。但是,antialising在小字号下看起来不太好。

或者您可以使用TextRenderer而不是Graphics.DrawString。 TextRenderer使用旧的GDI渲染(而不是像Graphics类那样的GDI +),所以它不会完成子像素渲染 - 每个字符的宽度都是9像素,或者每个字符的宽度都是10像素。有时候,旧技术更好。

+0

AntiAlias标志使字体看起来对我来说真的很糟糕,即使在12号尺寸下 – 2011-12-18 23:23:55

+0

谢谢!该绘图现在使用TextRenderer完美工作。使用TextRenderer.MeasureString()进行测量时会出现一些问题。即使在将TextFormatFlags.NoPadding设置为TextFormatFlags之后,像“abcd”这样的字符串的测量结果也不正确(宽度为25,应该是28,Consolas 9),“a”足够奇怪地给出了10而不是7. – 2011-12-18 23:43:36

+0

我相信您还可以将'graphics.TextRenderingHint'设置为不同的值,以使其像TextRender一样绘制文本。我不记得具体的价值,但只有5个左右的选择。 – 2011-12-19 00:57:50