失敗
.NET 2.0 で追加された TextRenderer クラスの MeasureText メソッドを使用すると、描画する文字列の幅を計測することができます。
このメソッドで1文字分の文字幅を計測したのですが、正しく計測できません。計測結果が、実際よりもかなり大きな値になってしまうのです。
環境
このレポートは、以下の環境について記述したものです。
| OS | Windows XP SP 2 |
| .NET | .NET Framework 2.0 |
原因
TextRenderer.MeasureText メソッドのデフォルト動作では、グリフ (フォントに含まれる描画内容の最小単位) の突出部がはみ出ないように、文字列の外側に余白が追加されます。 このため、計測される値が実際の値よりも大きくなってしまいました。
解決策
TextRenderer.MeasureText メソッドは、複数のシグネチャにオーバーロードされています。
半角/全角に関わらず、RichTextBox に設定されたフォントを使用するには、DualFont を無効にする必要があります。 余白を省いて、文字幅を計測するには、以下のシグネチャを使用します。
TextRenderer.MeasureText (IDeviceContext, String, Font, Size, TextFormatFlags)
IDeviceContext … 文字列を計測するデバイス・コンテキスト。
String … 計測する文字列。
Font … 計測する文字列に適用されるフォント。
Size … 初期の外接する四角形のサイズ。
TextFormatFlags … 計測する文字列に適用される書式。
(1) 余白を取り除いて、文字幅のみを計測する
以下に、TextBox の先頭一文字の幅を計測するコードを示します。
// textBox1 の先頭一文字を取得
string s = this.textBox1.Text.Substring(0, 1);
// Graphics オブジェクトの作成
Graphics g = this.textBoxEditor1.CreateGraphics();
// 初期の外接する四角形のサイズ
Size proposedSize = new Size(int.MaxValue, int.MaxValue);
// 余白を取り除く
TextFormatFlags flags = TextFormatFlags.NoPadding;
// サイズの計測
Size size = TextRenderer.MeasureText(g, s, this.textBoxEditor1.Font, proposedSize, flags);
Console.WriteLine("高さ:" + size.Height + ", 幅:" + size.Width);
g.Dispose();
補足
■ .NET 1.0, 1.1 で文字幅を計測するには
TextRenderer クラスは .NET 2.0 で追加されたものです。 .NET 1.0, 1.1 で文字幅を計測するには、Graphics.MeasureCharacterRanges メソッドや Graphics.MeasureString メソッドを使用してください。
なお、Graphics.MeasureString メソッドは、グリフの突出部がはみ出ないように、文字列の外側に余白が追加されます。 TextRenderer.MeasureText メソッドとは異なり、余白部分を取り除いて計測することはできませんので、ご注意ください。
