web-dev-qa-db-ja.com

TextRenderer.MeasureTextとGraphics.MeasureStringのサイズが一致しません

これは丸めの問題ではありません。違い〜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と一致する必要があります。

27
Aseem Gautam

TextRendererはGDIを使用してテキストをレンダリングしますが、GraphicsはGDI +を使用します。2つは少し異なる方法でテキストをレイアウトするため、サイズが異なります。

どちらを使用するかは、最終的に実際にテキストを描画するために何を使用するかによって異なります。 GDI + Graphics.DrawStringで描画している場合は、Graphics.MeasureStringを使用して測定します。 GDI TextRenderer.DrawTextを使用して描画している場合は、TextRenderer.MeasureTextを使用して測定します。

テキストがWindowsフォームコントロール内に表示される場合、TextRendererUseCompatibleTextRendering(デフォルト)に設定されていると、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);
}
58
Sven

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);
        }
    }
1
Aseem Gautam