QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

C# 文字列描画時の占有領域のサイズを知りたい(Graphicsオブジェクト)

Q1.下記例の"本日は晴天なり"が占有する方形領域の高さと幅のサイズは?
Q2.下記例の"本日は晴天なり"と"1234567890"の改行ピッチは?
Q3.幅ピッチ固定のフォント(例 MS ゴシック)の場合、既定の幅ピッチを取得する方法は?

 Grahicsオブジェクトに対してDrawStringを使って文字列を描画する時に文字列が実際に描画される領域のサイズを知りたいです。PrintDocumentで帳票を作成する時に、印刷物を定規で測ってレイアウト調整をしていました。

// ソースコード例
// WindowsFormにPrintDocumentとButtonを貼り付け、
// 下記のソースコードを追加すると
// 左上に"本日は晴天なり"次の行に"1234567890"が印刷されます。

using System.Drawing;
using System.Drawing.Printing;
....省略

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics;
Font font = new Font("MSP ゴシック", 32);
Brush brush = new SolidBrush(Color.Black);
PointF pointF = new PointF(100f, 200f);
g.DrawString("本日は晴天なり\r\n1234567890\r\n", font, brush, pointF);
}

    private void button1_Click(object sender, EventArgs e)
    {
        this.printDocument1.Print();
    }

質問者:ひろし

回答

今日は

GraphicsにはMeasureStringが有ると思います。

投稿者:rvmx

編集 履歴 (0)

メモリの話かと思ったがそっちかよww

占有領域のサイズ

なんて書くより「描画される文字列の幅」とかそういう表現にしれww

投稿者:ぶさいくろう

編集 履歴 (0)

質問の回答ではありませんが関連情報として挙げておきます。
DrawString のオーバーロードのうち StringFormat を引数に取るものを使えば
指定領域内に文字列を描画することができます。
帳票ならこちらを使う手もありますね。

投稿者:KI

編集 履歴 (0)

いや、ぶさいくろう氏。
逆に突っ込んでしまってすまないが、勘違いするのはかまわないとはいえ、「描画時」「領域」「サイズ」と来たら普通に通じると思うぞ。別にわかりにくいタイトルではない。現に私は勘違いしなかったし、ぶさいくろう氏の書き込みを見て「ああ、そう取るんだ」と初めて思ったぐらいだ。

占有領域というと厳密には確かにレイアウトな話で描画から類推するのは難しいかも知れないが大抵セットなので勘違いするほうが特殊だろう。まぁ、その者のバックグラウンドに依存するので一概には言えないことではあるが。

それと幅「だけ」ではないのでその表現はNGだ。MesureStringの戻り値はSizeFであるし。

投稿者:ya

編集 履歴 (0)

私は "占有領域" だけで、メモリ関連の話だと思いました。
その前の "描画時" は 「タイミングに過ぎない」 と思いました。

わかりにくいタイトルというより、付けにくいタイトルですね。
「Graphics から文字列を描画した時の文字列が描画される領域を事前に取得したい」

まあ、内容を読めばわかるので良いでしょうけど。
これに限らず件名に困る場面はあるでしょうね。(わからないことであればなおさら)

_________________C# と VB.NET の入門サイト
じゃんぬねっと日誌

投稿者:じゃんぬねっと

編集 履歴 (0)

確かに仰るとおりだね。
ごめんなさい。

投稿者:ぶさいくろう

編集 履歴 (0)

日本語は元々「縦書き」なので幅が一定ですが、元から横書きな文化であるところに「幅は?」と求めるのが無理なように思う。
幅が一定のフォントは、タイプライターのためだけなので、そっちの方がむしろ“例外”なのでしょう。

国語のノートはマスが書いてある(幅も高さも一定)けど、英語のノートは横線が引かれているだけだったよね(高さは一定だが、幅は不定)。


投稿者:Jitta

編集 履歴 (0)

タイトルについては私は特に問題ないと思います。
Graphics、サイズ、領域という単語が含まれる場面では、
Regionの方の意味合いでの領域をイメージしますので。
幅や高さというキーワードは、あったらなおよかったかもしれませんが、
タイトルの長さを考えると省略したとしても仕方ないところかなと思います。

ひろしさんの書き込み (2007-04-28 16:30) より:

Q1.下記例の"本日は晴天なり"が占有する方形領域の高さと幅のサイズは?

Q2.下記例の"本日は晴天なり"と"1234567890"の改行ピッチは?

Q3.幅ピッチ固定のフォント(例 MS ゴシック)の場合、既定の幅ピッチを取得する方法は?

さて、本題です。
Q1 → 既に回答のあるとおり、Graphics.MeagureStringメソッドでよいでしょう。
Q2 → 改行ピッチは行間の長さということでよいですか?
2行分の高さ - 1行分の高さ x 2 でどうでしょうか?
Q3 → 既定の幅ピッチとは何でしょうか?最大幅でよければ、
Wの幅をMeagureStringで求めるとかどうでしょうか。

投稿者:よねKEN

編集 履歴 (0)

Q3 → 既定の幅ピッチとは何でしょうか?最大幅でよければ、

Wの幅をMeagureStringで求めるとかどうでしょうか。

かなり蛇足になるけど、
私の場合、LaTEX触ってた頃にemの意味を知ってから、大文字のMの幅を使ってますね。
EMの説明(wikipedia.org)
#ちなみに高さはXを使う(ゆえに単位はex)ってどこかで見いたけど忘れた。

[ メッセージ編集済み 編集者: かずくん 編集日時 2007-05-01 12:41 ]

投稿者:かずくん

編集 履歴 (0)

ご回答ありがとうございます。
MeasureStringで解決できました。

投稿者:ひろし

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。