これは丸めの問題ではありません。違い〜5+ピクセル。
テストケース文字列: "" MACD(26,12,9)-0.000016 "
e.Graphics.MeasureString("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)
TextRenderer.MeasureText("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)
結果は常に:
139.3942
134
サイズにそれほど大きな違いがあるのはなぜですか? Paintメソッドの外側の文字列の幅のラウンドが必要です。ただし、MeasureStringと一致する必要があります。
TextRenderer
はGDIを使用してテキストをレンダリングしますが、Graphics
はGDI +を使用します。2つは少し異なる方法でテキストをレイアウトするため、サイズが異なります。
どちらを使用するかは、最終的に実際にテキストを描画するために何を使用するかによって異なります。 GDI + Graphics.DrawString
で描画している場合は、Graphics.MeasureString
を使用して測定します。 GDI TextRenderer.DrawText
を使用して描画している場合は、TextRenderer.MeasureText
を使用して測定します。
テキストがWindowsフォームコントロール内に表示される場合、TextRenderer
がUseCompatibleTextRendering
(デフォルト)に設定されていると、false
が使用されます。
質問の行の間を読むと、TextRenderer
イベントの外側にGraphics
インスタンスがないため、Paint
を使用しているようです。その場合は、自分で作成して測定を行うことができます。
using( Graphics g = someControl.CreateGraphics() )
{
SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}
グラフィックスインスタンスを作成するためのコントロールにアクセスできない場合は、これを使用して画面用のインスタンスを作成できます。これは、測定の目的でうまく機能します。
using( Graphics g = Graphics.FromHwnd(IntPtr.Zero) )
{
SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}
Paintイベントの外部でMeasureStringを使用するように次のクラスを作成しました。
public interface ITextMeasurer
{
SizeF MeasureString(string text, Font font, StringFormat format);
}
public class TextMeasurer : ITextMeasurer
{
private readonly Image _fakeImage;
private readonly Graphics _graphics;
public TextMeasurer()
{
_fakeImage = new Bitmap(1, 1);
_graphics = Graphics.FromImage(_fakeImage);
}
public SizeF MeasureString(string text, Font font, StringFormat format)
{
return _graphics.MeasureString(text, font, int.MaxValue, format);
}
}