テキストのレンダリング
Windows フォーム コントロールにおいて複雑なスクリプトを使用した、国際的に通用するアプリケーションの作成
Miguel A. Lacouture
この記事で取り上げる話題:
- TextRenderer クラスと Graphics クラス
- IDeviceContext の使用
- TextRenderer を使用した印刷
- Graphics から TextRenderer への移行
この記事で使用する技術:
- Windows フォーム、.NET Framework 2.0、GDI+
サンプルコードのダウンロード: TextRendering.exe (154KB)
翻訳元: Build World-Ready Apps Using Complex Scripts In Windows Forms Controls (英語)
目次
- TextRenderer クラス
- IDeviceContext インターフェイス
- TextRenderer の制限事項
- TextRenderer の使用
- UseCompatibleTextRendering
- TextRenderer を使用した印刷
- TextFormatFlags ユーティリティ
- まとめ
ソフトウェア開発会社が、世界各国の顧客に対応したいと考えた場合、各国語対応ソフトウェアの開発は、その会社が満たすべき要件の 1 つになります。テキスト レンダリング ライブラリは、テキストのレンダリングおよび多国語ロケール (言語パッケージ) のサポートという点でより優れている必要があります。それは、Windows フォームの System.Drawing.Graphics クラスがいくつかの制約を設けている点でもあります。このクラスは、GDI+ をベースとし、現在は複雑なスクリプトに対して制約付きのサポートを提供しています。
System.Windows.Forms.TextRenderer クラスは、Windows フォーム コントロールでの複雑なスクリプトに対して、Windows オペレーティング システムに対して期待されるものと同じレベルのサポートを提供するために開発されたクラスです。この TextRenderer は、GDI テキスト レンダリング API をベースにします。また、この API は、Windows Unicode スクリプト プロセッサ (Uniscribe) を使用します。
図 1 は、複雑なスクリプトに対する完全サポートを使用した場合と使用しない場合に書かれたシンハラ語の断片を示しています。Graphics クラスが使用されている最初の行のいくつかの文字は、正しくレンダリングされていません。そのような文字を 2 行目の文字と比較してみてください。2 行目には、TextRenderer を使用する完全スクリプト サポートを使用してレンダリングされたテキストが示されています。 (複雑なスクリプトの詳細は、サイドバー「複雑なスクリプトとは何か」を参照してください。)
図 1 テキストのレンダリングでの相違
System.Drawing.Graphics |
System.Windows.Forms.TextRenderer |
文字形状は正確にレンダリングされません。 | 完全スクリプト サポートのもとでは、文字は正しい形状になります。 |
1. TextRenderer クラス
Microsoft .NET Framework 2.0 の新機能である System.Windows.Forms.TextRenderer クラスには、MeasureText および DrawText の 2 つのオーバーロード静的メソッドのみが入っています。その名前が示すとおり、一方のメソッドはテキストのサイズを測定するのに使用され、もう一方は、デバイスコンテキストでテキストを描画するのに使用されます。この 2 つの新しいタイプは、TextRenderer クラスと一緒に導入されました。それらは、System.Windows.Forms.TextFormatFlags 列挙および System.Drawing.IDeviceContext インターフェイスです。
Win32 DrawTextEx 機能をよくご存じの場合、TextFormatFlags 列挙の値と、ネイティブの DrawTextEx 機能の dwDTFormat パラメータに対して定義されている値との間には、たくさんの共通点があることに気付かれると思います。それは偶然の一致ではありません。TextRenderer は実際には DrawTextEx を包むラッパーであり、DrawTextEx でサポートされているフォーマット オプションの大半は、TextRenderer でもサポートされています。TextFormatFlags 列挙体は、テキストをデバイスコンテキストで構成し、測定し、そして描画する方法を規制するフォーマット オプションを定義しています。
ネイティブの DrawTextEx 機能と TextRenderer メソッドの間には少数の相違点があります。たとえば、ネイティブ フォーマット オプション DT_CALCRECT および DT_TABSTOP は、TextFormatFlags にはありません。TextRenderer は MeasureText を持っているので、テキストの測定に使用される DT_CALCRECT オプションは必要ありません。タブ ストップを設定する DT_TABSTOP オプションは、現在は TextRenderer ではサポートされていません。 DrawTextEx でタブ ストップ長を設定するには、DRAWTEXTPARAMS パラメータを使用します。また、それによって、ユーザーはテキストの余白を指定できます。この特殊なパラメータに対応するパラメータは TextRenderer にはありませんが、TextFormatFlags.ExpandTabs フラグを指定すれば、テキスト内でのタブの拡張が可能になります。
ネイティブの DrawTextEx 機能とは違って、TextRenderer は、カスタムのテキスト余白を指定する方法を公開していませんが、TextFormatFlags.NoPadding、TextFormatFlags.GlyphOverhangPadding、および TextFormatFlags.LeftAndRightPadding などの、テキスト余白の指定目的で TextFormatFlags で定義されている特定のフラグに応じて、TextRenderer はテキスト余白を自動的に追加することができます。
図 2 は、そのようなフラグの使用法を示しています。テキストを描画するには、フラグを使用し、Times New Roman family から作成されたフォントを使用します。右側のテキストは、イタリック スタイルで描画されています。テキストを囲んでいる四角形は、テキストの長方形の境界であり、そのサイズは、上記のフラグを使用したテキストの測定によって判別されます。
図 2 埋め込みフラグを使用したテキストの描画
TextFormatFlags.NoPadding | ||
TextFormatFlags.GlyphOverhangPadding | ||
TextFormatFlags.LeftAndRightPadding |
ただし、図 2 には問題があります。NoPadding フラグを指定してレンダリングされたイタリックのテキストをご覧ください。左下および右上の領域で、境界ボックスから絵文字がはみ出していることに注意してください。境界ボックスを切り取ると、それらの部分は描画されません。文字によっては、ある特定のフォントとスタイルを使用して、テキスト ブロックの先頭あるいは末尾に配置すると、このような問題が起きます。この問題に対処するために、GlyphOverhangPadding フラグが、TextFormatFlags での既定の埋め込み値として用意されています。GlyphOverhangPadding を指定すると、フォントのサイズとスタイルに基づいて左と右の余白が TextRenderer によって計算されます。
たとえばボタンなどのコントロールを描画するときは、余分なテキスト余白がいくらかあったほうが、コントロール内のテキストの見栄えが改善されることがあります。ボタンのサイズを急いで計算するときは特にそうです。 LeftAndRightPadding フラグはその目的で用意されています。
TextFormatFlags 列挙もまた、PreserveGraphicsClipping および PreserveGraphicsTranslateTransform フラグを定義しています。これらのフラグは、Graphics クラスとの相互運用性を改善するのに役立ちますが、これが必要になるのは、何らかの座標変換およびカスタムのクリッピング情報が Graphics オブジェクトに対して適用される場合のみです。GDI+ から GDI に遷移すると、その情報は失われてしまいます。これらのフラグを設定した場合、TextRenderer によって GDI デバイスコンテキストに対してその情報がもう一度適用されます。Graphics オブジェクトで自動的に保存されるもう 1 つ別のプロパティに Graphics.TextRenderingHint があります。これは、使用するフォントの品質を選択するのに役に立ちます。
TextRenderer に対する TextFormatFlags 列挙の関係は、Graphics に対する System.Drawing.StringFormat クラスの関係と同じです。両者とも、テキストをレイアウトする方法を定義します。TextFormatFlags 列挙内のフラグと、StringFormat クラス内のフラグの間に厳密なマッピングはありませんが、かなり正確な近似値を得ることができます。図 3 は、そのようなフォーマット タイプの値どうしの関係を示しています。
図 3 StringFormat および TextFormatFlags からのマッピング値
StringFormat プロパティ値 | TextFormatFlags フラグ値 |
横方向の配置 | |
Alignment.Near | Left |
Alignment.Center | HorizontalCenter |
Alignment.Far | Right |
縦方向の配置 | |
LineAlignment.Near | Top |
LineAlignment.Center | VerticalCenter |
LineAlignment.Far | Bottom |
省略符号 | |
Trimming.EllipsisCharacter | EndEllipsis |
Trimming.EllipsisWord | WordEllipsis |
Trimming.EllipsisPatd | PatdEllipsis |
Trimming.Character | N/A |
Trimming.Word | N/A |
Trimming.None | <既定の動作> |
ホット キー プレフィックス | |
HotkeyPrefix.None | NoPrefix |
HotkeyPrefix.Show | <既定の動作> |
HotkeyPrefix.Hide | HidePrefix |
N/A | PrefixOnly |
テキストの埋め込み | |
FormatFlags.FitBlackBox * | NoPadding |
N/A | LeftAndRightPadding |
テキストの折り返し | |
FormatFlags.NoWrap | SingleLine |
<既定の動作> | WordBreak |
FormatFlags.LineLimit | WordBreak | TextBoxControl |
N/A | NoFullWidtdCharacterBreak |
その他のフラグ | |
FormatFlags.DirectionRightToLeft | RightToLeft |
FormatFlags.NoClip | NoClipping |
FormatFlags.DisplayFormatControl | N/A |
FormatFlags.NoFontFallBack | N/A |
FormatFlags.MeasureTrailingSpaces | N/A |
FormatFlags.DirectionVertical | N/A |
N/A | PreserveGraphicsClipping |
N/A | PreserveGraphicsTranslateTransform |
N/A | ExternalLeading |
N/A | Internal |
N/A | ModifyString |
SetTabStops メソッド | ExpandTabs |
* 実際には NoFitBlackBox を意味します。 |
この記事の後半で取り上げる TextFormatFlags ユーティリティは、TextFormatFlags の値に基づいて StringFormat オブジェクトを作成し (この逆も行えます) 、それを C# コードとしてクリップボードにコピーすることができます。
ページのトップへ
2. IDeviceContext インターフェイス
IDeviceContext は、ネイティブなデバイスコンテキスト (HDC) の取得と解放に関する契約を定義するときに使用されます。
IDeviceContext インターフェイスは 2 つの理由で装備されています。第 1 の理由は、Graphics クラスとのシームレスな対話をお膳立てするためです。TextRenderer メソッドに渡されるたいていのパラメータのタイプは、System.Drawing 名前空間に由来します。それで、整合性を保つために、Graphics ステートレス モデルが TextRenderer 内に保存されています。Graphics クラスはこのインターフェイスを実装しているので、TextRenderer メソッドで直接使用することができます。
IDeviceContext インターフェイスの 2 番目の理由は、TextRenderer への呼び込みの前に、デバイスコンテキストのカスタム初期化を行えるようにするためです。傾斜テキストの描画など、TextRenderer ではサポートされていないいくつかの機能が Graphics 内にあります。実際、IDeviceContext では、基盤をなす技法 (GDI および GDI+) のどちらにも同等の機能が存在する (常にそうとは限りません) という前提のもとで、欠落している機能のサポートを実装することはできます。このインターフェイスは、System.Windows.Forms.VisualStyles API でも使用されます。これは新規の API であり、.NET Framework 2.0 より導入されています。これは、ビジュアル スタイルを使用してコントロールおよびその他の UI 要素をレンダリングするときに使用されます。
図 4 は、図 2 のテキストをレンダリングするために使用されたコードを示しています。このコードは、Graphics オブジェクトが表すデバイスコンテキストでテキストを正しくレンダリングするために必要なステップを示しています。値 Size.Empty は、テキストの測定時に提案されたサイズとして使用されていることに注意してください。これは、規制する制約事項はないことと、ボックス サイズはテキストに最も合ったものでなければならないことを TextRenderer に伝える 1 つの方法です。同じことを伝える別の方法として、幅と高さを可能な限り最大限に設定した制約のないサイズを渡します。
図 4 TextRenderer を使用したテキストのレンダリング
Size PaintText(Graphics g, string txt, Font font,
Point pt, TextFormatFlags flags) {
Size size = TextRenderer.MeasureText(g, txt,
font, Size.Empty, flags);
Rectangle box = new Rectangle(pt, size);
g.DrawRectangle(Pens.Black, box);
TextRenderer.DrawText(g, txt, font, box,
SystemColors.ControlText, flags);
return size;
}
ページのトップへ
3. TextRenderer の制限事項
TextRenderer クラスは、Windows フォーム コントロールでのテキストのレンダリング用に設計されました (ディスプレイ デバイスコンテキスト タイプ)。ちなみに、TextRenderer クラスは、Graphics クラスとは違って、装置を限定しない描画用のクラスではありません。それは、他のデバイスコンテキスト タイプでは使用できないという意味ではなく、一部の作業をあらかじめ完了しておく必要があるということです。たとえば、TextRenderer を印刷で使用する場合、プリンタの解像度に基づいてすべてのパラメータ値を正しくスケーリングしておかなければなりません。 (これについては、この記事の後半でさらに詳しく取り上げます。) おそらくこれが、TextRenderer が System.Drawing 名前空間ではなく、System.Windows.Forms 名前空間の下に出現する主な理由であると思われます。
TextRenderer は、傾斜したテキストのレンダリングをサポートしません。それに対する単純な対処法として、テキストをビットマップで描画してから、そのビットマップを必要なだけ回転します。テキストをビットマップにレンダリングすると、透過性は失われることに注意してください。この解決策はすべてのクラスで功を奏するとは限りませんが、テキストを置こうとしているビットマップの背景色として、テキストのレンダリング先のビットマップ イメージの背景で使用するのと同じ色を使用することをお勧めします。
上述の通り、TextRenderer ではカスタムのタブ長を指定できません。それに対する解決策としては、.NET Framework の充実した文字列フォーマット オプションを活用して、所定のタブ長およびロケーションを指定して文字列をフォーマットしてから、TextRenderer に引き渡します。
ページのトップへ
4. TextRenderer の使用
TextRenderer には、コントロールでのテキストの描画にとっていくつかの利点があります。これを使用すれば、複雑なスクリプトのサポートを無償で受けることができ、しかも、同じレンダリング エンジンの使用によって、コントロールでテキストを表示して、UI 全体にわたって一貫性のあるテキスト レイアウトを整えることができます。.NET Framework 2.0 では、すべてのコントロールは、既定では GDI を使用してテキストをレンダリングしますが、実際には、テキストボックスやリスト ビューのように、GDI+ を使用してテキストをレンダリングできないコントロールもあります。
複雑なスクリプトと同様に、Graphics に付帯する特定の制限事項を TextRenderer で修正できるケースは他にもあります。たとえば、実行時に外字 (EUDC) を作成するときに、GDI+ を使用できません。なぜなら、GDI+ はフォントをロックするので、新しい文字を追加できないからです。心にとめておくべき重要な点として、ある 1 つのクラスを使用してテキストを測定してから、別のクラスを使用してそれを描画しないようにします。もしそうした場合、この 2 つのクラスでは、テキストのレイアウト アルゴリズムがそれぞれ異なるため、テキストのクリッピングといった問題が生じることがあります。必ず、Graphics.MeasureString は、Graphics.DrawString と一緒に使用し、TextRenderer.MeasureText は、TextRender-er.DrawText と一緒に使用します。 (アプリケーションで TextRenderer への切り替えに手間をかける価値があるかどうかを思案している場合は、サイド バー「切り替えるべきか」のいくつかのアドバイスを参照してください)。
5. UseCompatibleTextRendering
.NET Framework 2.0 のすべての Windows フォーム コントロールには、Windows の場合と同じレベルの複雑なスクリプトに対するサポートが用意されています。前のリリースでは、少数の Windows フォーム コントロールが、GDI+ から継承された複雑なスクリプトに対する制限事項のもとで、Graphics クラスを使用してテキストをレンダリングできるだけでした。現在は、そのようなコントロールでも、既定で TextRenderer クラスを使用してテキストをレンダリングできるようになりました。前のリリースとの互換性を保つために、そのようなコントロールには、UseCompatibleTextRendering という新しいプロパティが装備されています。このプロパティを真に設定すると、前のリリースの場合と同様に、Graphics クラスを使用してテキストがレンダリングされます。この新しいプロパティを装備されたコントロールは、ボタン、オプション ボタン、チェック ボックス、チェック リスト ボックス、グループ ボックス、ラベル、およびプロパティ グリッドです。
互換性を保つために、UseCompatibleTextRendering プロパティは既定では偽に設定されているので、前のリリースの .NET Framework で作成したアプリケーションを .NET Framework 2.0 で実行した場合、そのアプリケーションに変わりはないように見えます。
新規のアプリケーションは、プロセスで最初のフォームを実行する前に、静的な Application.SetUseCompatibleTextRenderingDefault メソッドを呼び出すことによって、このプロパティの既定値を変更することができます。Windows フォーム用の Visual Studio デザイナは、Main メソッド内でこのメソッドの呼び出しを生成します。
この機能の副次作用として、現在、その他の Windows UI に対する Windows フォーム アプリケーションのコントロールの整合性が向上したように見えます。それは、これらのコントロールはすべて、同じテキスト レンダリング エンジン (GDI) を共用するからです。
ページのトップへ
6. TextRenderer を使用した印刷
System.Drawing.Printing を使用して操作する場合、通常は、PrintDocument オブジェクトの PrintPage イベントの処理に注目が集まります。コントロールの Paint イベントの処理時に PaintEventArgs から取得した Graphics オブジェクトを使用するときと同じやり方で、PrintPageEventArgs の Graphics オブジェクトを使用することができます。多くの場合、一般的な描画方式を使用することができます。たとえば、フォーム、プリンタ、および印刷プレビューのダイアログ ボックス内での描画方式を使用します。そうすれば、ユーザーが画面上で見るものと、印刷ページの内容を確実に整合させることができます。
ただし、この技法は、TextRenderer では功を奏しません。その理由は、PrintPageEventArgs オブジェクト内の Graphics オブジェクトは、プリンタの解像度を指定してセットアップされていて、異なる座標単位でも稼働するからです。この場合は通常、1 インチの数百分の 1 の座標単位に合わせて設定されます。それは、Graphics オブジェクトの場合はどのように動作するのでしょうか。そこが、GDI+ が威力を発揮する分野です。GDI+ は装置を限定しないグラフィックス ライブラリであるので、そのような場合に単位を正しくスケーリングする方法を心得ています。TextRenderer では、すべての単位が 100% と想定されます。言い換えると、スケーリングを必要としません。
印刷 API と一緒に TextRenderer が稼働するようにするには、単位のスケーリングをあらかじめ実行しておく必要があります。図 5 は、印刷ライブラリから Graphics オブジェクトを取り出したときに、TextRenderer で使用するポイントとフォントをどのようにスケーリングするかを示しています。装置の解像度を使用して、1 インチの百分の 1 単位からピクセルに単位が変換されます。その解像度は、Graphics オブジェクトの DpiX および DpiY プロパティから取得されます。
図 5 フォントおよびポイントのスケーリング
private Point ScalePoint( Graphics g, ref Point p ) {
return new Point(
(int) Math.Ceiling( p.X / 100f * g.DpiX ),
(int) Math.Ceiling( p.Y / 100f * g.DpiY ) );
}
private Font ScaleFont( Graphics g, Font font ) {
return new Font(
font.FontFamily, font.SizeInPoints / 72f *
g.DpiY, font.Style, GraphicsUnit.Pixel,
font.GdiCharSet, font.GdiVerticalFont );
}
図 6 では、PrintPage イベントの printDoc_Print-Page イベント ハンドラ メソッド内の印刷フラグは真に設定されていて、Paint イベントの control_Paint イベント ハンドラ メソッドでは偽に設定されています。PaintWorker メソッドはこのフラグを検査し、印刷の場合には、図 5 のスケーリング メソッドを呼び出します。
図 6 ディスプレイあるいはプリンタ用の Paint メソッド
private void PaintWorker( Graphics g ) {
Point pt = new Point(10, 10);
Font f = this.Font;
if( this.printing ) {
pt = ScalePoint(g, ref pt);
f = ScaleFont(g, f);
}
TextRenderer.DrawText(g, Text, f, pt, SystemColors.ControlText);
if( f != this.Font) f.Dispose();
}
private void control_Paint( object sender, PaintEventArgs e ) {
this.printing = false;
PaintWorker( e.Graphics );
}
void printDoc_PrintPage( object sender, PrintPageEventArgs e ) {
this.printing = true;
PaintWorker( e.Graphics );
}
このアプローチを使用すれば、印刷および印刷プレビューでの TextRenderer の使用時に起きる問題は解決しますが、Graphics クラスの場合と同じ WYSIWYG 結果を得られるとは限りません。その主な理由は、GDI の文字間隔と語の中断のアルゴリズムは線形方式ではないからです。スケーリングされた値を使用してレンダリングされたテキストは、別のレイアウトになってしまうことがあります。また別の理由として、値のスケーリング時に精度が失われてしまったり、スケーリング後のフォントが、意図していたスケーリングとは異なる可能性があるからです。このような事態に陥るのは、意図していたスケール後のフォントは存在せず、フォントマッピングのアルゴリズムによって、最も近いと判断されたものが選択されるからです。
ページのトップへ
7. TextFormatFlags ユーティリティ
図 7 は、TextFormatFlags ユーティリティの UI を示しています。このイメージでは、メイン フォームの最上部に小さなウィンドウがあることに注意してください。描画面と呼ばれるこのウィンドウは、TextRenderer クラスおよび Graphics クラスでそれぞれレンダリングされたテキストを比較するために使用します。テキスト フォーマットは、オプション フォーマットから選択することができます。TextFormatFlags オプションは、左のパネルから選択し、StringFormat オプションは、右のパネルから選択します。
図 7 TextFormatFlags ユーティリティ
このツールで最も興味深い機能の 1 つとして、次のように、他の API のオプションに基づいて 1 つの API からテキスト フォーマット オプションを選択してから、C# コードとしてその情報をクリップボードにコピーできます。
TextFormatFlags textFlags = TextFormatFlags.NoPrefix |
TextFormatFlags.WordBreak | TextFormatFlags.ExpandTabs;
StringFormat strFormat = new StringFormat();
strFormat.FormatFlags =
StringFormatFlags.MeasureTrailingSpaces;
テキスト フォーマット オプションは、1 つの API から他の API への 100% のマッピングは行いませんが、このツールは、そのような API どうしの間の遷移を行う足がかりとしてきわめて有能な働きをします。このツールは、基盤の技法の行動についての理解を深めるのに使用されたので、TextRenderer クラスの開発時には非常に役に立ちました。このツールは、MSDNMagazine Web サイトからダウンロードすることができます。
ページのトップへ
8. まとめ
グローバリゼーションに対応する必要のあるアプリケーションでは、さまざまなスクリプトを使用するテキストのレンダリングに対して、少なくとも基盤のオペレーティング システムと同じレベルのサポートを提供する必要があります。.NET Framework 2.0 での System.Windows.Forms.TextRenderer クラスの登場によって、アプリケーションが対象とするプラットフォームの場合と同じレベルの、複雑なスクリプトに対するサポートを Windows フォーム アプリケーションに対してより簡単に提供できるようになりました。現在、UseCompatibleTextRendering プロパティを真に設定することで、すべての Windows フォーム コントロールが、基礎をなす同じテキスト レンダリング エンジンを使用してテキストをレンダリングできるようになったので、ユーザー インターフェイスは、外観と読みやすさの点で整合性がさらに強化されました。
ページのトップへ
複雑なスクリプトとは何か
Windows オペレーティング システムがサポートするスクリプトの中で、テキストの編集および表示のときに特別な処理を必要とするものがいくつかあります。その理由は、文字が書かれるコンテキストに応じて、その文字がそれぞれ異なる形状をとることがあるからです。それ以外に、そのようなスクリプト中の文字は、英語で見られる左から右へといった、シンプルな直線的な連続配置でレイアウトされません。
たとえばアラビア語のスクリプトは、右寄せされて、右から左 (RTL) へ向かって読まれます。さらに、アラビア語は文字形状言語です。すなわち、語の中での文字の位置や、前後にどのような文字が付いているかに応じて、それぞれ異なった表現でその文字を表わすことができます。このようなスクリプトの場合、語および行の中断、およびテキストの位置調整に対して複雑なセマンティクスも必要になります。このようなスクリプトで必要になるテキスト処理の複雑さが、これを複雑なスクリプトと呼ぶ理由です。
ページのトップへ
切り替えを行うべきか
Graphics の使用を継続するか、あるいは TextRenderer の使用に切り替えたほうが良いのか、確信を持てないのではないでしょうか。正しい答は、各自の状況によって異なります。検討すべきいくつかの点を以下に示してあります。
TextRenderer の利点をアプリケーションで活用できますか。前記の項をお読みになった後で、TextRenderer の利点をアプリケーションで活用できないと判断した場合、既に実装およびテスト済みの Graphics クラスを引き続き使用してください。
変更を行う余裕はありますか。行う必要のあることがいくつかあります。まず、Application.SetUseCompatibleTextRenderingDefault を呼び出してから、フォームを作成します。次に、Graphics.MeasureString および Graphics.DrawString の呼び出しを、TextRenderer.MeasureText および TextRenderer.DrawText の呼び出しにそれぞれ置き換えます。Graphics 呼び出しを置き換える際の一番大きな課題は、StringFormat オプションに基づいてどのような一連の TextFormatFlags を使用するかの決断です。これを簡単に処理できるようにするために、この後で説明するとおり、TextFormatFlags ユーティリティの助けを借りることができます。
中断される変更をテストする余裕はありますか。文字スペースや語の中断などの、テキストのメトリックを計算する方法は、GDI と GDI+ とでは同じではなく、場合によっては顕著な相違があることもあります。フォントおよびそのすべての変種 (書体、サイズ、ファミリなど)、装置の解像度、およびシステムのテキスト オプション (テキストの表示効果など) を含め、テキストのレンダリング方法に影響を与える要因はいくつかあります。また、StringFormat オプションと TextFormatFlags オプションの間には、完全なマッピングはありません。テキストの切り取りやレイアウトの変更は、テキスト レンダリング エンジンの切り替え時に注目する変更の中断の最も一般的なケースです。
ページのトップへ
Miguel A. Lacouture は、Windows フォーム チームのソフトウェア設計エンジニアであり、Microsoft には 7 年間在籍しています。同氏の連絡先は、mlacouture@msn.com です。
この記事は、MSDN マガジン - 2006 年 3 月からの翻訳です。
QJ: 060302
ページのトップへ