2

Wordのようなプログラムを開発しています。そのためには、文字列を同じ「行」に書き込む必要があります。また、各単語/文字/文を別々にフォーマットし、色、サイズ、フォントなどを制御する機能も必要です.

したがって、文字列のピクセルの長さと高さを計算して、それらを行に配置する必要があります。しかし、関数には問題があります(Graphics) MeasureString。この関数は、文字列の前後に余分な長さを置きます。この関数には、空白に関する問題もあります。

別の StringFormater を試してみましたが、返される長さが長すぎるか、十分ではありません。

オブジェクトにさまざまな形式の文字列を書き込む関数、Graphicsまたは文字列の正確なピクセル長を計算する関数は存在しますか?

4

2 に答える 2

4

まず、これは適切に解決するのがかなり難しい問題です。これを解決する既存のコントロール( RichTextBoxなど)を見つけようとする方がよい場合があります。

とはいえ、これを実行したい場合は、これが多かれ少なかれこの問題を解決する正しい方法ですが、MeasureStringのドキュメントを見ると、表示されている動作が意図的なものであることがわかります。

MeasureStringメソッドは、個々の文字列で使用するように設計されており、文字列の前後に少量の余分なスペースが含まれているため、グリフをオーバーハングさせることができます。また、DrawStringメソッドは、表示品質を最適化するためにグリフポイントを調整し、 MeasureStringによって報告されるよりも狭い文字列を表示する場合があります。レイアウト内の隣接する文字列に適したメトリックを取得するには(たとえば、フォーマットされたテキストを実装する場合)、MeasureCharacterRangesメソッドまたはStringFormatを受け取るMeasureStringメソッドの1つを使用して、 GenericTypographicを渡し ます。また、グラフィックのTextRenderingHintAntiAliasである ことを確認してください

したがって、代わりに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はデフォルトでレンダリングされたテキストを新しい行に「ラップ」しますが、これは機能しなくなり、次のようになります。

行の折り返しが正しくないフォームのスクリーンショット

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

于 2012-08-07T10:59:43.790 に答える
0

MeasureString は、この問題を解決する正しい方法です。この側の下部にあるサンプルを見てください http://msdn.microsoft.com/de-de/library/957webty(v=vs.80).aspx他の方法はないと言うからです。

于 2012-08-07T10:41:05.047 に答える