C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 文字を決まった枠内に収めて描画するには?


(過去ログ 109 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■64647 / inTopicNo.1)  文字を決まった枠内に収めて描画するには?
  
□投稿者/ ゆま (3回)-(2012/12/13(Thu) 13:42:58)

分類:[C#] 

「日本語と中国語が混在したMSゴシック12ポイント」のテキストの1文字1文字を
16x16のマス目に収めるにはどうすればよいでしょうか?
(アンチエイリアスなし)

DrawStringでピクチャーボックスに描画すると、幅がずれたり、下に飛び出したりしてしまいます。
(でも、テキストボックスに表示すると、綺麗に16x16の枠内に収まっています)

収めたい文字は、下記です。
Ag○定おはよう
  ↑○は中国の漢字が入ります。Unicodeで8BBEです。この文字が下に飛び出してしまい、以降の文字もずれてしまいます。

引用返信 編集キー/
■64648 / inTopicNo.2)  Re[1]: 文字を決まった枠内に収めて描画するには?
□投稿者/ ビート (1回)-(2012/12/13(Thu) 15:29:40)
No64647 (ゆま さん) に返信
> DrawStringでピクチャーボックスに描画すると、幅がずれたり、下に飛び出したりしてしまいます。
> (でも、テキストボックスに表示すると、綺麗に16x16の枠内に収まっています)

テキストボックスでは、日本語フォントのMS ゴシックを設定したとしても、フォントリンク機能で、中国語が適切なフォントに設定されるようですが、
グラフィックスでDrawStringを行う場合、このフォントリンクがうまくいかないのかも知れません。
試しに、文字をひとつずつDrawStringし、その際に日本語文字と中国語文字でDrawStringするフォントを変えるとどうでしょうか?
(中国語文字の場合は相応のフォントを使い、それ以外はMS ゴシックを使う)
引用返信 編集キー/
■64650 / inTopicNo.3)  Re[1]: 文字を決まった枠内に収めて描画するには?
□投稿者/ 魔界の仮面弁士 (111回)-(2012/12/13(Thu) 16:13:32)
No64647 (ゆま さん) に返信
> 中国語が混在した
簡体字(GB2312)ですか? 繁体字(Big5)ですか?
あるいは中国語以外も混じりますか?


> MSゴシック
「MS ゴシック」もしくは「MS Gothic」であって、
「MSゴシック」では無いように思います。
結果的には MS ゴシック が代替フォントに選ばれるでしょうけれどね。


> Unicodeで8BBEです。
これですね。
http://www.fileformat.info/info/unicode/char/8bbe/index.htm

そもそもMS ゴシックには、このグリフが登録されていないはずなので、
ゴシック系なら SimHei あたりで代用してみては如何でしょう。

まぁ、今度は日本語の方に問題が生じるでしょうから、実際には
文字ごとに異なるフォントを割り当てた方が良いかもしれませんが。


無理に MS ゴシック で表示させようとすると、
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
に従って、予期せぬフォントにリンクされる可能性があります。

実際、当方環境では MingLiU (繁体字・明朝系フォント)にリンクされてしまい、
ゴシック系フォントのはずが明朝系で描画されるという、不恰好な結果になってしまいました。


> でも、テキストボックスに表示すると、綺麗に16x16の枠内に収まっています
TextBox は GDI で描画されますが、PictureBox は GDI+ だからでしょう。

そのため、Graphics クラスの DrawString メソッドと
TextRenderer クラスの DrawText メソッドでは、
出力結果が異なる可能性があります。
http://msdn.microsoft.com/ja-jp/library/a3a2bads%28vs.90%29.aspx
引用返信 編集キー/
■64651 / inTopicNo.4)  Re[2]: 文字を決まった枠内に収めて描画するには?
□投稿者/ ゆま (4回)-(2012/12/13(Thu) 17:25:03)
ビートさま

ご返信ありがとうございます。

試しに中国語1文字かつ中国語フォントで描画してみたところ、
別の問題が発生してしまいました。

文字にアンチエイリアスがかかってしまうようになりました。
下のコードも試してみましたが、アンチエイリアスが消せませんでした。
pictureBox1.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;

引用返信 編集キー/
■64652 / inTopicNo.5)  Re[2]: 文字を決まった枠内に収めて描画するには?
□投稿者/ ゆま (5回)-(2012/12/13(Thu) 17:33:10)
魔界の仮面弁士さま

ご返信ありがとうございます。

下記に回答させていただきます。

> 簡体字(GB2312)ですか? 繁体字(Big5)ですか?
> あるいは中国語以外も混じりますか?
GB2312というコードのみです。
中国語のみです。

>>Unicodeで8BBEです。
> これですね。
> http://www.fileformat.info/info/unicode/char/8bbe/index.htm
その文字です。

>>でも、テキストボックスに表示すると、綺麗に16x16の枠内に収まっています
> TextBox は GDI で描画されますが、PictureBox は GDI+ だからでしょう。
PictureBoxに対して、GDIで描画することはできますでしょうか?
(GDIは初めて聞く言葉なので、今は理解が浅いです)

> ゴシック系なら SimHei あたりで代用してみては如何でしょう。
SimHeiでテキストボックスに例文の中国語を表示すると、テキストボックス上でもアンチエイリアスがかかるようになってしまいました。
上記のご説明からGDIでアンチエイリアスをオフにして表示はできますでしょうか?
テキストボックスにそれらしきプロパティは見つけられませんでした。



引用返信 編集キー/
■64654 / inTopicNo.6)  Re[3]: 文字を決まった枠内に収めて描画するには?
□投稿者/ 魔界の仮面弁士 (112回)-(2012/12/13(Thu) 20:56:43)
No64652 (ゆま さん) に返信
> PictureBoxに対して、GDIで描画することはできますでしょうか?

可能ですよ。

先の回答の最後でも、URL を紹介しながら少し触れていますが、
たとえば「TextRenderer クラス」は、コントロールのためのテキストを
表現するために用意された物です。

また、アンマネージの GDI API (TextOutW API など)を使う手法もあります。

(ちなみに、コントロールそのものを描画したいのであれば、
TextBoxRenderer クラス/ControlPaint クラスというものがあります)

なお Label 等では、「UseComapatibleTextRendering プロパティ」にて
GDI+ (Graphics クラス等)によるテキスト描画を用いるか、
GDI (TextRenderer クラス等)によるテキスト描画を用いるかを
切り替えられるようになっています。また、上記設定の規定値を
「Application.SetCompatibleTextRenderingDefault メソッド」で
あらかじめ設定しておくこともできます。



> (GDIは初めて聞く言葉なので、今は理解が浅いです)
GDI : Graphics Device Interface は、16bit 版 Windows の頃から
使われてきた描画命令です。

Win16 API では GDI.DLL、Win32/Win64 では GDI32.DLL が主要ライブラリであり、
たとえば TextOutW API での テキスト描画なども GDI API の一種です。


一方、GDI+ (ジーディーアイプラス)の主要ライブラリは、
GdiPlus.DLL です。.NET においては、GDI+ API をカプセル化して、
System.Drawing.Graphics などから扱えるようになっています。


違いについては、先に紹介した URL を参照してみてください。



> 上記のご説明からGDIでアンチエイリアスをオフにして表示はできますでしょうか?
> テキストボックスにそれらしきプロパティは見つけられませんでした。

できないことも無いですが、そのためにはコントロールパネルにて、
画面のアンチエイリアス設定をオフにする必要があるでしょうから、
OS 全体に影響を与えることになってしまうかと思います。
http://support.microsoft.com/kb/306527/ja
http://windows.microsoft.com/ja-JP/windows7/make-text-easier-to-read-using-cleartype



手元の環境で実際に試してみました。口頭では説明しにくいので画像にしています。

http://www.vb-user.net/junk/replySamples/2012.12.13.20.25/11.png
http://www.vb-user.net/junk/replySamples/2012.12.13.20.25/12.png
http://www.vb-user.net/junk/replySamples/2012.12.13.20.25/21.png
http://www.vb-user.net/junk/replySamples/2012.12.13.20.25/22.png


4 枚画像がありますが、これはコントロールのレンダリング方法を変更したものです。

SetCompatibleTextRenderingDefault が false なら 1x.png、true なら 2x.png。
OS のアンチエイリアス設定を有効にしたままのものが x1.png、無効にしたものが x2.png です。

Graphics クラスのプロパティ設定は、SmoothingMode = None、
TextRenderingHint = ClearTypeGridFit にしています。


描画内容は、赤文字が Graphics.DrawString、黒文字が TextRenderer.DrawText です。
画面構成は、左列が Label、中列が TextBox、右列が PicureBox で、
使用フォントは、
 上段:MS ゴシック(日本語) 12Pt … 下記 f1
 中段:MingLiU      (繁体字) 12Pt … 下記 f2
 下段:SimHei       (簡体字) 12Pt … 下記 f3
としています。


const byte ANSI_CHARSET        =   0;    const byte JOHAB_CHARSET       = 130;
const byte DEFAULT_CHARSET     =   1;    const byte HEBREW_CHARSET      = 177;
const byte SYMBOL_CHARSET      =   2;    const byte ARABIC_CHARSET      = 178;
const byte SHIFTJIS_CHARSET    = 128;    const byte GREEK_CHARSET       = 161;
const byte HANGEUL_CHARSET     = 129;    const byte TURKISH_CHARSET     = 162;
const byte HANGUL_CHARSET      = 129;    const byte VIETNAMESE_CHARSET  = 163;
const byte GB2312_CHARSET      = 134;    const byte THAI_CHARSET        = 222;
const byte CHINESEBIG5_CHARSET = 136;    const byte EASTEUROPE_CHARSET  = 238;
const byte OEM_CHARSET         = 255;    const byte RUSSIAN_CHARSET     = 204;
const byte MAC_CHARSET         =  77;    const byte BALTIC_CHARSET      = 186;

Font f1 = new Font("MS ゴシック", 12.0, FontStyle.Regular, GraphicsUnit.Point, SHIFTJIS_CHARSET);
Font f2 = new Font("MingLiU", 12.0, FontStyle.Regular, GraphicsUnit.Point, CHINESEBIG5_CHARSET);
Font f3 = new Font("SimHei", 12.0, FontStyle.Regular, GraphicsUnit.Point, GB2312_CHARSET);
Font f4 = new Font("Consolas", 12.0, FontStyle.Regular, GraphicsUnit.Point, ANSI_CHARSET);
Font f5 = new Font("Marlett", 12.0, FontStyle.Regular, GraphicsUnit.Point, SYMBOL_CHARSET);
Font f6 = new Font("Arial Unicode MS", 12.0, FontStyle.Regular, GraphicsUnit.Point, SHIFTJIS_CHARSET);
Font f6 = new Font("Arial Unicode MS", 12.0, FontStyle.Regular, GraphicsUnit.Point, GB2312_CHARSET);

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -