まず、これは適切に解決するのがかなり難しい問題です。これを解決する既存のコントロール( RichTextBoxなど)を見つけようとする方がよい場合があります。
とはいえ、これを実行したい場合は、これが多かれ少なかれこの問題を解決する正しい方法ですが、MeasureStringのドキュメントを見ると、表示されている動作が意図的なものであることがわかります。
MeasureStringメソッドは、個々の文字列で使用するように設計されており、文字列の前後に少量の余分なスペースが含まれているため、グリフをオーバーハングさせることができます。また、DrawStringメソッドは、表示品質を最適化するためにグリフポイントを調整し、 MeasureStringによって報告されるよりも狭い文字列を表示する場合があります。レイアウト内の隣接する文字列に適したメトリックを取得するには(たとえば、フォーマットされたテキストを実装する場合)、MeasureCharacterRangesメソッドまたはStringFormatを受け取るMeasureStringメソッドの1つを使用して、 GenericTypographicを渡し
ます。また、グラフィックのTextRenderingHintがAntiAliasである
ことを確認してください。
したがって、代わりにGraphics.MeasureCharacterRangesメソッドを使用する必要があるように思えます。
これは私が準備したサンプルで、いくつかのテキストを2つの異なる色でレンダリングします。試してみるには、新しいフォームに貼り付けるだけです
protected override void OnPaint(PaintEventArgs e)
{
// This is where we wish to print our string
var region = new RectangleF(50, 50, 200, 50);
// This is the font we wish to use
var font = new Font("Times New Roman", 16.0F);
// Draw a string for comparison
DrawString(e.Graphics, "RedBlack", font, Brushes.Black, new RectangleF(50, 150, 200, 50));
// Draw the first string and keep a track of the Region it was rendered in
var first = DrawString(e.Graphics, "Red", font, Brushes.Red, region);
// Adjust the region we wish to print
region = new RectangleF(region.X + first.GetBounds(e.Graphics).Width, region.Y, region.Width, region.Height);
// Draw the second string
DrawString(e.Graphics, "Black", font, Brushes.Black, region);
base.OnPaint(e);
}
private Region DrawString(Graphics g, string s, Font font, Brush brush, RectangleF layoutRectangle)
{
var format = new StringFormat();
format.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, s.Length) });
g.DrawString(s, font, brush, layoutRectangle, format);
return g.MeasureCharacterRanges(s, font, layoutRectangle, format)[0];
}
これはそれがどのように見えるかです

クリッピングに注意する必要があることに注意してください。GDIはデフォルトでレンダリングされたテキストを新しい行に「ラップ」しますが、これは機能しなくなり、次のようになります。

また、異なるフォント/フォントサイズでテキストを印刷しようとすると、それらの各フォントの「下部」が期待どおりに整列しません。それに対処するためのヒントについては、一般的なベースラインでのテキストのフォーマットを見てみてください。