PDC 2008

DirectWrite の紹介

更新日: 2009 年 4 月 28 日


ダウンロード

PDC08_Introducing_DirectWrite_JPN.docx (Word 形式、277 KB)


目次:

はじめに テキスト表示品質の向上 レンダリング システムからの独立 高品質の文字体裁
  1. 高度な文字体裁機能のサポート
  2. 各国語対応テキストのサポート
複数のレイヤーで構成された機能 ClearType によるテキスト レンダリングの向上 API の概要 DirectWrite を使用した "Hello World" の書式設定と描画 フォント システムへのアクセス テキスト レンダリング
  1. カスタム レンダリング モード
GDI との相互運用性 まとめ 付録: Win32 の移行



Sriram Subramanian
Microsoft Corporation
2008 年 10 月

対象:

Windows® 7

要約:

DirectWrite は、DirectX ファミリに新しく追加された API です。DirectWrite では、Win32 アプリケーションのテキスト表示品質を向上させる、OpenType フォントおよび ClearType レンダリングが使用されます。このホワイト ペーパーでは、DirectWrite API を使用して GDI アプリケーションや DirectX アプリケーションでテキストを表示する方法について説明します。

法的通知:

このドキュメントは暫定版であり、このソフトウェアの最終的な製品版の発売時に実質的に変更されることがあります。
このドキュメントに記載されている情報は、このドキュメントの発行時点におけるマイクロソフトの見解を反映したものです。変化する市場状況に対応する必要があるため、このドキュメントは、記載された内容の実現に関するマイクロソフトの確約とはみなされないものとします。また、発行以降に発表される情報の正確性に関して、マイクロソフトはいかなる保証もいたしません。
このホワイト ペーパーに記載された内容は情報の提供のみを目的としており、明示、黙示または法律の規定にかかわらず、これらの情報についてマイクロソフトはいかなる責任も負わないものとします。
お客様ご自身の責任において、適用されるすべての著作権関連法規に従ったご使用を願います。このドキュメントのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受けることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。ここでいう形態とは、複写や記録など、電子的な、または物理的なすべての手段を含みます。ただしこれは、著作権法上のお客様の権利を制限するものではありません。
マイクロソフトは、このドキュメントに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有する場合があります。別途マイクロソフトのライセンス契約上に明示の規定のない限り、このドキュメントはこれらの特許、商標、著作権、またはその他の無体財産権をお客様に許諾するものではありません。
別途記載されていない場合、このソフトウェアおよび関連するドキュメントで使用している会社、組織、製品、ドメイン名、電子メール アドレス、ロゴ、人物、場所、出来事などの名称は架空のものです。実在する商品名、団体名、個人名などとは一切関係ありません。
© 2008 Microsoft Corporation. All rights reserved.
Microsoft、MS-DOS、Windows、Windows NT、Windows Server、Windows Vista、Active Directory、ActiveSync、ActiveX、Direct3D、DirectDraw、DirectInput、DirectMusic、DirectPlay、DirectShow、DirectSound、DirectX、Expression、FrontPage、HighMAT、Internet Explorer、JScript、Microsoft Press、MSN、Outlook、PowerPoint、SideShow、Silverlight、Visual Basic、Visual C++、Visual InterDev、Visual J++、Visual Studio、WebTV、Windows Media、Win32、Win32s、および Zune は米国 Microsoft Corporation の米国またはその他の国における登録商標または商標です。
記載されている会社名、製品名には、各社の商標のものもあります。


1. はじめに

日常生活におけるコミュニケーションでは、常にテキストを使用しています。テキストは、増加の一途をたどる情報を消費するための主な方法です。これまで、テキストは、ドキュメント、新聞、書籍などの印刷物で使用されるものでしたが、次第に、Microsoft® Windows® PC 上のオンライン コンテンツに使用されるようになってきています。一般的な Windows ユーザーは、コンピューターの画面上に表示されたデータを読み取ることに多くの時間を費やしています。ネット サーフィン、電子メールの流し読み、レポートの構成、スプレッドシートへの記入、ソフトウェアの作成など、さまざまな作業を行っていますが、実際に行っているのは「読むこと」です。テキストやフォントは Windows のユーザー エクスペリエンスのほぼすべての部分に浸透していますが、ほとんどのユーザーにとって、画面上に表示されたものを読むことは、印刷物を読むことほど楽しいことではありません。

Windows アプリケーションの開発者にとって、テキストを処理するコードの作成は困難な作業です。というのも、読みやすくするための要件の増加、複雑な書式やレイアウトの制御、アプリケーションで表示する必要がある複数の言語に対するサポートに対応しなければならないからです。非常に基本的なテキスト処理システムでも、テキストの入力、レイアウト、表示、編集、およびコピーと貼り付けを行えるようにする必要があります。一般的に、Windows ユーザーは、このような基本的な機能以上を期待するため、単純なエディターであっても、複数のフォント、さまざまな段落スタイル、埋め込み画像、スペル チェックなどの機能をサポートする必要があります。また、最近の UI のデザインは、単一の書式とプレーン テキストに限定されることはなくなり、豊富なフォントやテキスト レイアウトを使用してより優れたエクスペリエンスを実現する必要もあります。

このドキュメントでは、DirectWrite によって、Windows アプリケーションの UI やドキュメントのテキスト表示品質がどのように向上するかについて説明します。

ページのトップへ


2. テキスト表示品質の向上

最近の Windows アプリケーションでは、その UI やドキュメント内のテキストに関する要件が複雑になっています。こうした要件には、読みやすさの向上、さまざまな言語やスクリプトのサポート、高度なレンダリング パフォーマンスなどがあります。さらに、ほとんどの既存のアプリケーションでは、Win32® のコード ベースへの既存の投資を今後も利用する方法を必要としています。

DirectWrite には、Windows アプリケーションの開発者がアプリケーション内のテキスト表示品質を向上できるようにする機能が 3 つ用意されています。この機能とは、レンダリング システムからの独立、高品質の文字体裁、および複数のレイヤーで構成された機能です。

a. レンダリング システムからの独立

DirectWrite は、特定のグラフィックス テクノロジには依存していないので、アプリケーションでは、そのニーズに最も適したレンダリング テクノロジを自由に使用できます。これにより、アプリケーションの一部は引き続き GDI でレンダリングし、その他の部分は Direct3D® や Direct2D でレンダリングすることができます。実際、アプリケーションでは、専用のレンダリング スタックを介して DirectWrite をレンダリングすることもできます。

ページのトップへ

b. 高品質の文字体裁

DirectWrite では、OpenType® フォント テクノロジの進化を活かして、Windows アプリケーション内で高品質の文字体裁を実現することができます。DirectWrite フォント システムでは、アプリケーションでフォントの処理に必要となる、フォントの列挙、代替、キャッシュを処理するためのサービスが提供されています。

DirectWrite で提供されている OpenType のサポートにより、開発者は、高度な文字体裁機能と各国対応テキストのサポートをアプリケーションに追加できます。

高度な文字体裁機能のサポート

DirectWrite を使用すると、アプリケーション開発者は、Win Forms や GDI では使用できなかった、OpenType フォントの機能のロックを解除できます。DirectWrite の IDWriteTypography オブジェクトでは、スタイル上の代替文字や巻きひげ文字など、OpenType フォントの高度な機能の多くを公開しています。Windows SDK には、Pericles フォントや Pescadero フォントなど、機能が充実した OpenType フォントのサンプル一式が用意されています。OpenType フォントの機能の詳細については、「OpenType フォントの機能」を参照してください。

各国語対応テキストのサポート

DirectWrite では、OpenType フォントを活用して、各国語対応テキストの幅広いサポートが可能になりました。サロゲート、BIDI、改行、UVS などの Unicode 機能がサポートされます。言語に合わせたスクリプトの記述、数字置換、グリフの形成により、スクリプト内のテキストのレイアウトとレンダリングは適切な状態になります。

現在サポートされているスクリプトは次のとおりです。

: * が付いたスクリプトについては、既定のシステム フォントがありません。アプリケーションでは、このようなスクリプトをサポートするフォントをインストールする必要があります。

  • アラビア語
  • アルメニア語
  • ベンガル語
  • 注音字母
  • ブライユ点字 *
  • カナダ先住民音節
  • チェロキー語
  • 中国語 (簡体字と繁体字)
  • キリル言語
  • コプト文字 *
  • デバナガリ文字
  • 古代エチオピア語
  • グルジア語
  • グラゴル文字 *
  • ギリシャ語
  • グジャラート語
  • グルムキー文字
  • ヘブライ語
  • 日本語
  • カナラ語
  • クメール語
  • 韓国語
  • ラオス語
  • ラテン語
  • マラヤラム語
  • モンゴル語
  • ミャンマー語
  • 新タイ ルー文字
  • オガム文字 *
  • オリヤー語
  • パスパ文字
  • ルーン文字 *
  • シンハラ語
  • シリア語
  • タイ ルー文字
  • タミール語
  • テルグ語
  • ターナ文字
  • タイ語
  • チベット語
  • イ文字

ページのトップへ

c. 複数のレイヤーで構成された機能

DirectWrite には、複数のレイヤーで構成された機能が用意されており、各レイヤーでは隣のレイヤーとシームレスに対話します。API の仕様により、アプリケーションでは、ニーズやスケジュールに応じて、自由かつ柔軟に、個々のレイヤーを採用することができます。こうしたレイヤーの関係を次の図に示します。

レイヤーの関係図

 

テキスト レイアウト API には、DirectWrite で提供している最高レベルの機能が用意されています。また、この API では、アプリケーションが多彩な書式のテキスト文字列の測定、表示、操作を行うためのサービスが提供されます。このテキスト レイアウト API は、現在 Win32 の DrawText によって、多彩な書式が設定されたテキストを使用した最新の UI を実現しているアプリケーションで使用できます。

独自のレイアウト エンジンを実装し、テキストを集中的に使用するアプリケーションでは、下位レイヤー (スクリプト プロセッサ) を使用することができます。スクリプト プロセッサでは、テキスト ブロックがスクリプト ブロックに分解され、スクリプトのテキストを適切な言語で正しく表示できるように、Unicode 表現からフォントの適切なグリフ表現へのマッピングが処理されます。テキスト レイアウト API レイヤーで使用されるレイアウト システムは、フォントとスクリプトを処理するシステムに基づいて構築されています。

グリフ レンダリング層は、機能の最下位のレイヤーで、独自のテキスト レイアウト エンジンを実装するアプリケーションにグリフ レンダリング機能を提供します。グリフ レンダリング層は、カスタム レンダラーを実装して、DirectWrite のテキスト書式設定 API のコールバック関数でグリフ描画動作を変更するアプリケーションにも役立ちます。

DirectWrite フォント システムは、DirectWrite の全機能レイヤーで使用できるため、アプリケーションではフォントやグリフの情報にアクセスできるようになります。このシステムは、一般的なフォント テクノロジやデータ形式を処理するよう設計されています。DirectWrite フォント モデルは、同じフォント ファミリ内のさまざまな太さ、スタイル、伸縮をサポートする、一般的な文字体裁の慣例に従っています。このモデル (WPF および CSS でも採用されています) では、太さ (太い、細いなど)、スタイル (標準、斜体など)、または伸縮 (狭い、縮小、広いなど) だけが異なるフォントは、同じフォント ファミリのメンバーであると見なされます。

ページのトップへ


3. ClearType によるテキスト レンダリングの向上

画面上での読みやすさの向上は、すべての Windows アプリケーションにとって重要な要件です。認知心理学の調査から、処理速度を上げるためには、すべての文字を正確に認識できる必要があるだけでなく、文字の間隔も重要であることが判明しました。均整がとれていない文字や単語は、見苦しいと認識され、読みやすさが低下します (Microsoft Advanced Reading Technologies グループに所属する Kevin Larson は、IEEE Spectrum で発行された、「The Technology of Text」(英語) という表題の興味深い記事を執筆しました)。

DirectWrite のテキストは、Microsoft® ClearType® を使用してレンダリングされるので、テキストのわかりやすさと読みやすさが向上します。ClearType では、最新の LCD ディスプレイで、各ピクセルで個別に制御できる RGB ストライプが採用されているという点が活用されます。DirectWrite では、個々の文字だけでなく、文字間隔も評価できる ClearType の最新の拡張機能を使用しています (ClearType は、Windows Presentation Foundation 搭載の Windows Vista® に最初に同梱されました)。この ClearType の拡張機能が開発されるまで、"読み取り" サイズが 10 ポイントまたは 12 ポイントのテキストを表示することは困難でした。設定可能な文字間隔は、1 ピクセルか 2 ピクセルのいずれかで、前者の場合は小さすぎて、後者の場合は大きすぎるということが往々にしてありました。サブピクセルの解像度が上がると、間隔を小数値で指定できるようになるため、ページ全体の均一性や均整が向上します。

次の 2 つの例では、サブピクセル ポジショニングを使用した場合にサブピクセルの境界でどのようにグリフを開始できるかを示しています。

サブピクセル ポジショニング未使用

上記の例は、サブピクセル ポジショニングを使用していない、GDI バージョンの ClearType レンダラーを使用してレンダリングされたものです。

次の例は、サブピクセル ポジショニングを使用している、DirectWrite バージョンの ClearType レンダラーを使用してレンダリングされたものです。

サブピクセル ポジショニング使用

2 つ目の画像では、文字 e と l の間隔が 1 つ目の画像より均等になっていることに注目してください。また、文字 l の縦線もがより自然になっています。

ClearType のサブピクセル ポジショニングにより、画面上の文字間隔は非常に正確になります。特に、サブピクセルとピクセルの差がグリフの幅に占める割合が大きい、小さいサイズの場合にはよくわかります。サブピクセル ポジショニングにより、テキストを理想的な解像度で測定し、LCD のカラー ストライプのサブピクセルの粒度で自然な位置にレンダリングできます。このテクノロジを使用して測定およびレンダリングされたテキストは、定義上、解像度に依存しません。つまり、まったく同じレイアウトのテキストをさまざまなディスプレイ解像度で実現できます。

GDI の ClearType レンダリングのどちらの特色とも異なり、サブピクセルの ClearType では、文字の幅が非常に正確になります。

テキスト レイアウト API では、既定で、サブピクセルによるテキスト レンダリングが採用されています。つまり、この API は、現在のディスプレイの解像度に関係なく理想的な解像度でテキストを測定し、サイズ変更されたグリフの送り幅と位置指定オフセットに基づいて、グリフの位置を生成します。

 

大きなサイズのテキストの場合、DirectWrite を使用すると、Y 軸に沿ったアンチエイリアス表示により、縁をより滑らかにして、フォント デザイナーが意図したとおりに文字をレンダリングできます。次のスクリーンショットでは、Y 軸方向のアンチエイリアス表示を示しています。

DirectWrite のテキストの位置指定とレンダリングには、既定で、サブピクセルの ClearType が使用されますが、他のレンダリング オプションも使用できます。

Y 軸方向のアンチエイリアス表示

既存のアプリケーションの多くは、GDI を使用して UI の大半をレンダリングします。また、アプリケーションによっては、テキストのレンダリングに引き続き GDI を使用する、システム編集コントロールを使用するものもあります。このようなアプリケーションに DirectWrite のテキストを追加すると、アプリケーション全体でテキストの表示の一貫性を保つため、サブピクセルの ClearType によるテキストの読みやすさを諦めることが必要になる場合があります。

こうした要件を満たすために、DirectWrite では、次のレンダリング オプションもサポートしています。

  • サブピクセルの ClearType (既定)
  • 水平と垂直の両方向のアンチエイリアス表示を使用したサブピクセルの ClearType
  • エイリアス表示のテキスト
  • GDI 固有の幅 (たとえば、Microsoft Word 全画面表示で使用されます)
  • GDI と互換性のある幅 (アジア系言語の埋め込みビットマップを含む)

このようなレンダリング モードはそれぞれ、DirectWrite API と Windows 7 付属の新しい ClearType チューナーを使用して細かく調整できます。

ページのトップへ


4. API の概要

IDWriteFactory インターフェイスは、DirectWrite 機能を使用する際に最初に使用するものです。ファクトリは、併用できる一連のオブジェクトを作成するルート オブジェクトです。

テキストの描画やヒット テストを実行する前に、指定された制約に合わせて適切にテキストの書式設定とレイアウトを行う必要があるため、書式設定やレイアウトの操作は必須要件になります。この目的で IDWriteFactory インターフェイスを使用して作成できる 2 つの主なオブジェクトは、IDWriteTextFormat と IDwriteTextLayout です。IDWriteTextFormat オブジェクトは、1 つの段落のテキストの書式設定情報を表します。IDwriteFactory::CreateTextLayout 関数は、入力文字列と関連する制約 (出力する必要がある空間のサイズなど) に加え、IDWriteTextFormat オブジェクトを受け取り、その後の操作で使用する、完全な分析と書式設定が行われた結果を IDWriteTextLayout オブジェクトとして返します。

その後、アプリケーションでは DrawTextLayout 関数を使用してテキストをレンダリングできます。この関数は、Direct2D に用意されていますが、GDI、Direct2D などのグラフィックス システムを使用してグリフをレンダリングできるコールバック関数を実装することでテキストをレンダリングすることもできます。テキストに設定された書式が 1 つの場合、Direct2D の DrawText 関数を使用すると、IDWriteTextLayout オブジェクトを作成する必要なく、簡単にテキストを描画することができます。

a. DirectWrite を使用した "Hello World" の書式設定と描画

次のサンプル コードでは、アプリケーションで IDWriteTextFormat オブジェクトを使用して 1 つの段落の書式を設定し、Direct2D の DrawText 関数を使用してその段落を描画する方法を示します。

HRESULT DrawHelloWorld(
    __in D2D1::IRenderTarget *pIRenderTarget
    )
{
    HRESULT hr = S_OK;
    com_ptr<D2D1::IFactory *> pIFactory;
    com_ptr<D2D1::ISolidColorBrush *> pIRedBrush;
    com_ptr<IDWriteTextFormat *> pITextFormat;
    com_ptr<IDWriteFactory *> pIDWriteFactory;
    IFC(DWriteCreateFactory(DWRITE_FACTORY_PROCESS, &pIDWriteFactory));
IFC(pIDWriteFactory->CreateTextFormat(
    L”Arial”, 
    NULL,
    DWRITE_FONT_WEIGHT_NORMAL, 
    DWRITE_FONT_STYLE_NORMAL, 
    DWRITE_FONT_STRETCH_NORMAL, 
    10.0f * 96.0f/72.0f, 
    L"en-US", 
    &pITextFormat));
    IFC(pIRenderTarget->CreateSolidColorBrush(
        D2D1:: ColorF(D2D1::ColorF::Red),
         &pIRedBrush));
    
   D2D1_RECT_F layoutRect = D2D1::RectF(0.f, 0.f, 100.f, 100.f);
    // 実際に、原点にテキストを描画します。
    IFC(pIRenderTarget->DrawText(
        L”Hello World”,
            wcslen(L”Hello World”),
        pITextFormat,
      layoutRect, 
        pIRedBrush));   
    RETURN(hr);
}

ページのトップへ

b. フォント システムへのアクセス

DirectWrite を使用すると、上記の例で IDWriteFormat オブジェクトを使用してテキスト文字列のフォント ファミリ名を指定する以外に、アプリケーションでは、フォントの列挙と、埋め込まれたドキュメントのフォントに基づいてカスタムのフォント コレクションを作成する機能により、使用するフォントをより細かく制御できます。

IDWriteFontCollection オブジェクトは、フォント ファミリのコレクションです。DirectWrite では、システム フォント コレクションと呼ばれる特殊なフォント コレクションを介して、システムにインストールされた一連のフォントへのアクセスが提供されます。このアクセスを取得するには、IDWriteFactory オブジェクトの GetSystemFontCollection メソッドを呼び出します。また、アプリケーションでは、アプリケーション定義のコールバックによって列挙された一連のフォント (アプリケーションによってインストールされるプライベート フォント、ドキュメントに埋め込まれたフォントなど) から、カスタム フォント コレクションを作成することもできます。

その後、アプリケーションは、GetFontFamily を呼び出して、コレクション内の特定の FontFamily オブジェクトにアクセスしてから、IDWriteFontFamily::GetFont を呼び出して、特定の IDWriteFont オブジェクトにアクセスできます。IDWriteFont オブジェクトは、フォント コレクション内の 1 つのフォントを表し、情報プロパティといくつかの基本的なフォント メトリックを公開します。

IDWriteFontFace は、1 つのフォントを表すもう 1 つのオブジェクトで、フォントの完全なメトリックを公開します。IDWriteFontFace オブジェクトは、フォント名から直接作成できます。そのため、アプリケーションでは、フォント コレクションを取得してそのコレクションにアクセスする必要はありません。これは、特定のフォントの詳細を照会する必要がある、Microsoft Word などのテキスト レイアウト アプリケーションで役立ちます。

次の図は、このようなオブジェクトの関係を示しています。

オブジェクトの関係

IDWriteFontFace オブジェクト

IDWriteFontFace オブジェクトは、フォントを表しますが、IDWriteFont オブジェクトよりも詳細なフォント情報を提供します。IDWriteFontFace オブジェクトのフォント メトリックとグリフ メトリックは、テキスト レイアウトを実装するアプリケーションで役立ちます。

ほとんどのメインストリーム アプリケーションでは、こうした API を直接使用するのではなく、IDWriteFont オブジェクトを使用したり、フォント ファミリ名を指定したりします。

次の表に、この 2 つのオブジェクトの使用シナリオを示します。

カテゴリ *Font *FontFace
フォントの選択ユーザー インターフェイスなどのユーザー操作をサポートする API (説明などの情報 API)  
フォント マッピングをサポートする API (ファミリ、スタイル、太さ、伸縮、文字の範囲)  
DrawText API  
レンダリングに使用される API  
テキスト レイアウト (グリフ メトリックなど) に使用される API  
UI コントロールやテキスト レイアウト (フォント全体のメトリック) 用の API

 

アプリケーションでフォントのダイアログ ボックスを (部分的に) 初期化する際に使用できるサンプル コードを次に示します。

void MyFontDialog::OnInitDialog(HWND hDlg)
{
    size_t familyCount;
    HRESULT hr = fontCollection_->GetFontFamilyCount(&familyCount);
    if (FAILED(hr))
        throw MyException(hr);
HWND familyListBox = GetDlgItem(hDlg, IDC_FONTFAMILYLIST);

// コレクション内のすべてのフォント ファミリを繰り返し処理します。
for (size_t familyIndex = 0; familyIndex &lt; familyCount; ++familyIndex)
{
    // フォント ファミリ オブジェクトを取得します。
    CComPtr&lt;IDWriteFontFamily&gt; fontFamily;
    hr = fontCollection_-&gt;GetFontFamily(familyIndex, &amp;fontFamily);
    if (FAILED(hr))
        throw MyException(hr);

    // フォント ファミリ名を取得します。
    CComPtr&lt;IDWriteLocalizedStrings&gt; familyNames;
    hr = fontFamily-&gt;GetFamilyNames(&amp;familyNames);
    if (FAILED(hr))
        throw MyException(hr);

    // 現在のロケールの名前を取得します。
    std::wstring familyName = GetDisplayName(familyNames);

    // ファミリ名をリスト ボックスに追加します。
    LRESULT itemIndex = SendMessage(familyListBox, LB_ADDSTRING, 0, (LPARAM)(familyName.c_str()));
    if (itemIndex == LB_ERRSPACE)
        throw std::bad_alloc();

    // リスト ボックスの項目はアルファベット順に並べ替えられるため、
    // itemIndex == familyIndex と想定することはできません。
    // そのため、familyIndex を項目データとして保存します。
    SendMessage(familyListBox, LB_SETITEMDATA, itemIndex, familyIndex);
}

}

void MyFontDialog::OnFamilySelected(HWND hDlg) { HWND fontListBox = GetDlgItem(hDlg, IDC_FONTLIST); SendMessage(faceList, LB_RESETCONTENT, 0, 0);

HWND familyListBox = GetDlgItem(hDlg, IDC_FONTFAMILYLIST);

LRESULT itemIndex = SendMessage(familyListBox, LB_GETCURSEL, 0, 0);
if (itemIndex != LB_ERR)
{
    // OnInitDialog は、各リスト項目のファミリ インデックスを項目データとして設定します。
    LRESULT familyIndex = SendMessage(familyListBox, LB_GETITEMDATA, itemIndex, 0);

    // コレクションからフォント ファミリを取得します。
    CComPtr&lt;IDWriteFontFamily&gt; fontFamily;
    hr = fontCollection_-&gt;GetFontFamily(familyIndex, &amp;fontFamily);
    if (FAILED(hr))
        throw MyException(hr);

    // フォント ファミリに含まれるフォント数を取得します。
    size_t fontCount;
    hr = fontFamily-&gt;GetFontCount(&amp;fontCount);
    if (FAILED(hr))
        throw MyException(hr);

    // フォントのリスト ボックスに各フォントを追加します。
    for (size_t fontIndex = 0; fontIndex &lt; fontCount; ++fontIndex)
    {
        // フォント オブジェクトを取得します。
        CComPtr&lt;IDWriteFont&gt; font;
        hr = fontFamily-&gt;GetFont(fontIndex, &amp;font);
        if (FAILED(hr))
            throw MyException(hr);

        // フォント フェイス名を取得します。
        CComPtr&lt;IDWriteLocalizedStrings&gt; faceNames;
        hr = font-&gt;GetFaceNames(&amp;faceNames);
        if (FAILED(hr))
            throw MyException(hr);

        // 現在のロケールの名前を取得します。GetDisplayName は、
        // アプリケーションによって記述された関数で、
        // ロケールに適切なローカライズされた名前を faceNames から 
        // 取得します。
        std::wstring faceName = GetDisplayName(faceNames);

        // フォント フェイス名をリスト ボックスに追加します。
        LRESULT itemIndex = SendMessage(fontListBox, LB_ADDSTRING, 0, (LPARAM)(faceName.c_str()));
        if (itemIndex == LB_ERRSPACE)
            throw std::bad_alloc();

    }
}

}

ページのトップへ

c. テキスト レンダリング

テキスト レンダリング API により、DirectWrite フォントのグリフを、Direct2D サーフェスまたは GDI デバイス非依存のビットマップにレンダリングしたり、アウトラインまたはビットマップに変換したりできます。

DirectWrite の ClearType レンダリングでは、以前 Windows に実装されたものに比べて鮮明度とコントラストが向上した、サブピクセル ポジショニングがサポートされています。また、DirectWrite では、ビットマップが埋め込まれたアジア系言語用フォントを含むシナリオや、ユーザーがすべての種類のフォント スムージングを無効にしているシナリオをサポートするために、エイリアス表示の白黒のテキストもサポートされています。

すべてのオプションは、DirectWrite API からアクセスできる、ClearType の使用可能なすべてのノブによって調整できます。また、これらのオプションは、Windows 7 の新しい ClearType チューナーのコントロール パネル アプレットでも公開されます。

グリフのレンダリングに使用できる API は 2 つあります。1 つは、Direct2D を使用してハードウェア アクセラレータによるレンダリングを提供し、もう 1 つは、GDI ビットマップへのソフトウェアによるレンダリングを提供します。IDWriteTextLayout オブジェクトを使用し、IDWriteTextRenderer コールバックを実装するアプリケーションでは、DrawGlyphRun コールバックに応じてこの関数のいずれかを呼び出すことができます。また、独自のレイアウトを実装するアプリケーションやグリフ レベルのデータを処理するアプリケーションでも、これらの API を使用できます。

  1. ID2D1DrawingSink::DrawGlyphRun 関数を使用したテキスト レンダリングに GPU を活用する
    アプリケーションでは、Direct2D API の DrawGlyphRun を使用して、GPU を使用したテキスト レンダリングをハードウェア アクセラレータにすることができます。ハードウェア アクセラレーターは、複数のグリフをグリフ実行に結合することから、連続するグリフのビットマップのフィルター処理、最終的な表示出力への ClearType ブレンド アルゴリズムの適用まで、テキスト レンダリング パイプラインのすべてのフェーズに影響します。この API は、最適なレンダリング パフォーマンスを実現するのに推奨されています。
  2. IDWriteBitmapRenderTarget::DrawGlyphRun 関数
    アプリケーションでは、IDWriteBitmapRenderTarget::DrawGlyphRun 関数を使用して、32 bpp ビットマップに連続するグリフをソフトウェアでレンダリングできます。IDWriteBitmapRenderTarget オブジェクトは、グリフのレンダリングに使用できる、ビットマップとメモリ DC をカプセル化します。この API は、GDI でレンダリングを行う既存のコード ベースがあり、GDI を引き続き使用するアプリケーションで役立ちます。
    GDI を使用する既存のテキスト レイアウト コードがアプリケーションに含まれており、その既存のレイアウト コードを保持しながら、グリフをレンダリングする最後の手順でのみ DirectWrite を使用する必要があるシナリオでは、IDWriteGdiInterop::CreateFontFaceFromHdc 関数によって、2 つの API 間の橋渡しが行われます。この関数を呼び出す前に、アプリケーションでは IDWriteGdiInterop::CreateFontFaceFromHdc 関数を使用して、DC からフォント フェイスへの参照を取得します。

: ほとんどのシナリオでは、アプリケーションは、グリフをレンダリングするこのような API を使用する必要はありません。アプリケーションでは、IDWriteTextLayout オブジェクトを作成したら、ID2D1DrawingSink::DrawTextLayout メソッドを呼び出してテキストをレンダリングできます。

カスタム レンダリング モード

ガンマ、ClearType レベル、ピクセル座標、拡張されたコントラストなど、多くのパラメーターがテキストのレンダリングに影響します。レンダリング パラメーターは、IDWriteRenderingParams パブリック インターフェイスを実装するオブジェクトによってカプセル化されます。レンダリング パラメーターのオブジェクトは、ハードウェアのプロパティや、Windows 7 の ClearType コントロール パネル アプレットで指定されたユーザーの基本設定に基づいて、自動的に初期化されます。通常、クライアントで DirectWrite のレイアウト API を使用すると、DirectWrite により、指定された測定モードに対応するレンダリング モードが自動的に選択されます。

さらに詳細な制御を必要とするアプリケーションでは、IDWriteFactory::CreateCustomRenderingParams 関数を使用して、異なるレンダリング オプションを実装できます。また、この関数を使用して、ガンマ、ClearType レベル、ピクセル座標、拡張されたコントラストを設定することもできます。

使用できるレンダリング オプションには、次のようなものがあります。

  • サブピクセルの ClearType
    アプリケーションでは、renderingMode パラメーターに DWRITE_RENDERING_MODE_CLEARTYPE を設定し、水平方向のアンチエイリアス表示が指定された ClearType レンダリングを指定します。
  • 水平と垂直の両方向のアンチエイアシングが指定されたサブピクセル ClearType
    アプリケーションでは、renderingMode パラメーターに DWRITE_RENDERING_MODE_CLEARTYPE_SYMMETRIC を設定し、水平と垂直の両方向のアンチエイリアス表示が指定された ClearType レンダリングを指定します。これにより、曲線や斜線は、ぼかしが強くなる可能性がありますが、滑らかに見えるようになります。また、これは、通常、16 ppem 以上のサイズで使用されます。
  • エイリアス表示テキスト
    エイリアス表示テキストを指定するには、renderingMode パラメーターに DWRITE_RENDERING_MODE_BILEVEL を設定します。
  • グレースケール テキスト
    グレースケール テキストを指定するには、pixelGeometry パラメーターに DWRITE_PIXEL_GEOMETRY_FLAT をに設定します。
  • GDI と互換性のある幅 (アジア系言語の埋め込みビットマップを含む)
    アプリケーションでは、renderingMode パラメーターに DWRITE_RENDERING_MODE_CLEARTYPE_COMPATIBLE を設定し、GDI と幅の互換性がある ClearType を指定します。
  • GDI 固有の幅
    アプリケーションでは、renderingMode パラメーターに DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL を設定し、GDI 固有の幅の ClearType を指定します。
  • アウトライン テキスト
    サイズが大きい場合、アプリケーションは、ビットマップにラスタライズするのではなく、フォント アウトラインを使用してレンダリングするのが適していることがあります。renderingMode パラメーターに DWRITE_RENDERING_MODE_OUTLINE を指定すると、レンダリング時に、ラスタライザーを無視して、直接アウトラインが使用されます。

ページのトップへ


5. GDI との相互運用性

IDWriteGdiInterop インターフェイスでは、GDI との相互運用性が提供されます。これにより、アプリケーションは、GDI コード ベースへの既存の投資を継続して活用し、レンダリングまたはレイアウトで選択的に DirectWrite を使用できるようになります。

アプリケーションが GDI フォント システムとの間で移行できるようにする API を次に示します。

  • CreateFontFromLOGFONT
    LOGFONT 構造体で指定されたプロパティに一致する IDWriteFont オブジェクトを作成します。
  • ConvertFontToLOGFONT
    指定された IDWriteFont オブジェクトの GDI と互換性のあるプロパティに基づいて、LOGFONT 構造体を初期化します。
  • ConvertFontFaceToLOGFONT
    指定された IDWriteFontFace オブジェクトの GDI と互換性のあるプロパティに基づいて、LOGFONT 構造体を初期化します。
  • CreateFontFaceFromHdc
    現在選択されている HFONT に対応する IDWriteFontface オブジェクトを作成します。

ページのトップへ


6. まとめ

読みやすさの向上は、画面上に表示されるデータと印刷物のどちらでも、ユーザーにとって大きな価値があります。DirectWrite では、アプリケーション開発者が Windows アプリケーションのテキスト表示品質を向上するのに役立つ操作性と複数層のプログラミング モデルが提供されています。アプリケーションでは、DirectWrite を使用して、テキスト レイアウト API で UI とドキュメントに多彩な書式が設定されたテキストをレンダリングできます。より複雑なシナリオでは、アプリケーションは、直接グリフを操作したり、フォントにアクセスしたりできます。また、高品質の文字体裁を実現するために DirectWrite の機能を使用することもできます。

DirectWrite の相互運用機能により、アプリケーション開発者は、既存の Win32® コード ベースを継続して使用しながら、アプリケーションで DirectWrite を選択的に採用することができます。

詳細については、Windows 7 および .NET Framework 3.5 Service Pack 1 用 Windows® ソフトウェア開発キット (SDK) のプレベータ版 (PDC の参加者に配布) と PDC 2008 の実習を参照してください。

ページのトップへ


7. 付録: Win32 の移行

Win32® アプリケーション コードを移行する開発者のために、次の表に、Win32 テキスト API とそれに相当する DirectWrite API を示しています。

GDI のテキスト API

説明

DirectWrite における同等のテキスト API

AddFontMemResourceEx (英語)

埋め込まれたフォントをシステム フォント テーブルに追加します。

CreateCustomFontFileReferece + CreateCustomFontCollection

AddFontResource (英語)

フォント リソースをシステム フォント テーブルに追加します。

これと同等のものはありません。 AddFontResource では、GDI フォントの "インストール" 手順の一環としてフォント リソースをシステム フォント コレクションに追加します。DirectWrite では、システム コレクションが最初に設定され、その更新が裏側で自動的に監視されるため、フォントをインストールする必要がなくなります。

AddFontResourceEx (英語)

プライベート フォントまたは列挙不可能なフォントをシステム フォント テーブルに追加します。

同上

CreateFont (英語)

論理フォントを作成します。

アプリケーションでは、論理フォントではなく、一連のフォント プロパティ (ファミリ名、太さ、スタイル、伸縮、サイズなど) を指定して、IDWriteTextFormat オブジェクトを作成できます。フォントを列挙する必要があるアプリケーションだけが、IDWriteFontCollection を介して IDWriteFont オブジェクトにアクセスします。

CreateFontIndirect (英語)

構造体から論理フォントを作成します。

同上

CreateFontIndirectEx (英語)

構造体から論理フォントを作成します。

同上

DrawText (英語)

四角形の中に、書式設定されたテキストを描画します。

IDWriteTextLayout::Draw

DrawTextEx (英語)

四角形の中に、書式設定されたテキストを描画します。

IDWriteTextLayout::Draw

EnumFontFamExProc (英語)

フォントを処理する EnumFontFamiliesEx 関数で使用される、アプリケーション定義のコールバック関数です。

IDWriteFontFace::GetSystemFontCollection を介した IDWriteFontCollection インターフェイス

EnumFontFamiliesEx (英語)

システム内にある、特定の特性を持つフォントをすべて列挙します。

IDWriteFontFace::GetSystemFontCollection を介した IDWriteFontCollection インターフェイス

ExtTextOut (英語)

文字列を描画します。

IDWriteTextLayout::Draw
または IDWriteRenderBitmapTarget::DrawGlyphRun

GetAspectRatioFilterEx (英語)

縦横比フィルター用の設定を取得します。

N/A

GetCharABCWidths (英語)

TrueType フォントから連続する文字の幅を取得します。

IDWriteFontFace::GetDesignGlyphMetrics

GetCharABCWidthsFloat (英語)

現在のフォントから連続する文字の幅を取得します。

IDWriteFontFace::GetDesignGlyphMetrics

GetCharABCWidthsI (英語)

TrueType フォントから、連続するグリフ インデックスの幅またはグリフ インデックスの配列の幅を取得します。

IDWriteFontFace::GetDesignGlyphMetrics

GetCharacterPlacement (英語)

文字列に関する情報を取得します。

IDWriteTextAnalyzer

GetCharWidth32 (英語)

現在のフォントから連続する文字の幅を取得します。

IDWriteFontFace::GetDesignGlyphMetrics または IDWriteTextLayout::GetMetrics

GetCharWidthFloat (英語)

現在のフォントから連続する文字の幅を小数値で取得します。

IDWriteFontFace::GetDesignGlyphMetrics または IDWriteTextLayout::GetMetrics

GetCharWidthI (英語)

現在のフォントから、連続するグリフ インデックスの幅またはグリフ インデックスの配列の幅を取得します。

IDWriteFontFace::GetDesignGlyphMetrics または IDWriteTextLayout::GetMetrics

GetFontData (英語)

TrueType フォントのメトリック データを取得します。

IDWriteFontFace::TryGetFontTable

GetFontLanguageInfo (英語)

表示コンテキスト用に選択されたフォントに関する情報を返します。

N/A

GetFontUnicodeRanges (英語)

フォントでサポートされている Unicode 文字を返します。

IDWriteFont::HasCharacter のループ

GetGlyphIndices (英語)

文字列をグリフ インデックスの配列に変換します。

IDWriteFontFace::GetGlyphIndices

GetGlyphOutline (英語)

TrueType フォントの文字のアウトラインまたはビットマップを取得します。

グリフ メトリック -- IDWriteFontFace::GetDesignGlyphMetrics、
実際のアウトライン情報 --IDwriteFontFace::GetGlyphRunOutline、
グリフ ビットマップ -- IDWriteRenderBitmapRenderTarget::DrawGlyphRun

GetKerningPairs (英語)

フォントの文字のカーニング ペアを取得します。

カーニングはレイアウトの文字体裁プロパティで行えます (DirectWrite 自体がカーニングを実行するため、この情報を返すためのメソッドはありません) 。

GetOutlineTextMetrics (英語)

TrueType フォントのテキスト メトリックを取得します。

IDWriteFontFace::GetMetrics

GetRasterizerCaps (英語)

TrueType フォントがインストールされているかどうかを返します。

N/A (TrueType フォントは、既定で、 Windows Vista および Windows 7 にインストールされています) 。

GetTabbedTextExtent (英語)

タブを含めた、文字列の幅と高さを計算します。

IDWriteTextLayout::GetMetrics

GetTextAlign (英語)

デバイス コンテキストのテキストの配置設定を取得します。

IDWriteTextFormat::GetTextAlignment

GetTextCharacterExtra (英語)

デバイス コンテキストの現在の文字間隔を取得します。

N/A

GetTextColor (英語)

デバイス コンテキストのテキストの色を取得します。

N/A (DirectWrite は、レンダリングとは無関係のため、色を認識しません。アプリケーション自体が色を追跡する必要があります) 。

GetTextExtentExPoint (英語)

スペースに収まる文字列の文字数を取得します。

IDWriteTextLayout::GetMetrics

GetTextExtentExPointI (英語)

スペースに収まるグリフ インデックスの数を取得します。

IDWriteTextLayout::GetMetrics

GetTextExtentPoint32 (英語)

テキストの文字列の幅と高さを計算します。

IDWriteTextLayout::GetMetrics

GetTextExtentPointI (英語)

グリフ インデックスの配列の幅と高さを計算します。

IDWriteTextLayout::GetMetrics

GetTextFace (英語)

デバイス コンテキストで選択されているフォント名を取得します。

IDWriteFont::GetFaceNames (すべての名前を返します)

GetTextMetrics (英語)

フォントのメトリックスをバッファに格納します。

IDWriteFontFace::GetMetrics

PolyTextOut (英語)

デバイス コンテキストのフォントとテキストの色を使用して、複数の文字列を描画します。

N/A。複数のレイアウト オブジェクトを作成します。

RemoveFontMemResourceEx (英語)

ソースがドキュメントに埋め込まれたフォントを、システム フォント テーブルから削除します。

関連オブジェクトの Iunknown::Release

RemoveFontResource (英語)

ファイル内のフォントをシステム フォント テーブルから削除します。

N/A

RemoveFontResourceEx (英語)

プライベート フォントまたは列挙不可能なフォントをシステム フォント テーブルから削除します。

N/A

SetMapperFlags (英語)

論理フォントを物理フォントにマップする際に使用されるアルゴリズムを変更します。

N/A

SetTextAlign (英語)

デバイス コンテキストのテキスト配置フラグを設定します。

IDWriteTextFormat::SetTextAlignment

SetTextCharacterExtra (英語)

文字間隔を設定します。

N/A

SetTextColor (英語)

デバイス コンテキストのテキストの色を設定します。

アプリケーションは、Draw 呼び出しのいずれかで色を指定する必要があります。

SetTextJustification (英語)

システムが文字列のブレーク文字に追加する間隔を指定します。

N/A。配置と文字間隔は、このリリースではサポートされていません。

TabbedTextOut (英語)

指定された値までタブを展開し、文字列を指定の場所に書き込みます。

IDWriteTextLayout::Draw

TextOut (英語)

文字列を指定の場所に書き込みます。

IDWriteTextLayout::Draw

ページのトップへ