Direct2D ジオメトリとその操作
Charles Petzold
コード サンプルのダウンロード
高校の幾何学は、2 種類に分類できます。ユークリッド幾何学は、構造、法則、および証明を重視しますが、分析幾何学は座標系の点を使って数値で幾何学的図形を描きます。この座標系は、分析幾何学の創始者であるルネ デカルトにちなんでデカルト座標系とよく呼ばれます。
コンピューター グラフィックスのベクトル分野全体の基盤は分析幾何学なので、ID2D1Geometry という名前のインターフェイス (およびその 6 つの派生インターフェイス) が Direct2D ベクトル グラフィックスの中心に位置付けられているのは適切と言えます。
前回のコラム (msdn.microsoft.com/magazine/dn342879) では、Windows 8 で実行するフィンガー ペインティング アプリで ID2D1PathGeometry を使った線のレンダリング方法について説明しました。今回は、その前段階に戻ってジオメトリについてさらに詳しく説明し、特に操作ジオメトリで異なるジオメトリを作成するための、ID2D1Geometry で定義している興味深いメソッドをいくつか調べます。
Windows ランタイム (WinRT) のジオメトリを使い慣れている場合でも、WinRT Geometry クラスでは公開されていない機能が ID2D1Geometry では提供されています。
概要
ジオメトリは、基本的には座標点の集合です。これらの座標点は特定のデバイスに関連付けられていないため、ジオメトリは本質的にデバイスから独立したオブジェクトです。このため、デバイスから独立した Direct2D ファクトリである ID2D1Factory オブジェクトのメソッドを呼び出して、さまざまな種類のジオメトリを作成します。図 1 に、6 種類のジオメトリ作成メソッドと、作成されるオブジェクトのインターフェイス型を示しています。
図 1 6 種類のジオメトリ メソッドとインターフェイス
ID2D1Factory メソッド | 作成されるオブジェクト (ID2D1Geometry から派生) |
CreateRectangleGeometry | ID2D1RectangleGeometry |
CreateRoundedRectangleGeometry | ID2D1RoundedRectangleGeometry |
CreateEllipseGeometry | ID2D1EllipseGeometry |
CreatePathGeometry | ID2D1PathGeometry |
CreateTransformedGeometry | ID2D1TransformedGeometry |
CreateGeometryGroup | ID2D1GeometryGroup |
CreatePathGeometry を除けば、これらのメソッドは不変オブジェクトを作成します。つまり、オブジェクトを作成するために必要なすべての情報を作成メソッドに渡すことになり、作成後にはジオメトリを一切変更できません。
ID2D1PathGeometry オブジェクトが異なっている唯一の理由は、CreatePathGeometry メソッドが本質的に空のオブジェクトを返すためです。これにデータを格納する方法については、後で説明します。
CreateTransformedGeometry メソッドは、既存の ID2D1Geometry オブジェクトとアフィン変換行列を受け取ります。作成されるジオメトリは、この行列によって変換、スケール調整、回転、または傾斜されています。CreateGeometryGroup メソッドは、ID2D1Geometry オブジェクトの配列を受け取り、すべての個別ジオメトリを合成したジオメトリを作成します。
DirectX にアクセスする Windows ストア アプリの作成で Visual Studio の Direct2D (XAML) プロジェクト テンプレートを使用する場合、通常はレンダリング クラスで CreateDeviceIndependentResources のオーバーライド中にジオメトリ オブジェクトを作成し、Render のオーバーライド中を中心に、プログラムの有効期間を通してこれらのジオメトリ オブジェクトを使用します。
ID2D1RenderTarget インターフェイス (ID2D1DeviceContext などのインターフェイスの派生元) は、DrawGeometry メソッドと FillGeometry メソッドという、描画サーフェイスでジオメトリをレンダリングする 2 つのメソッドを定義します。
DrawGeometry メソッドは、特定のブラシ、ストロークの太さ、およびストロークのスタイルを使ってジオメトリの直線と曲線を描画し、直線、点線、破線、またはカスタムの破線パターンの線を描画できるようにします。FillGeometry メソッドは、ジオメトリの囲まれた領域を、ブラシやオプションの不透明度マスクで塗りつぶします。クリッピング用のジオメトリも使用でき、その場合はジオメトリを含む D2D1_LAYER_PARAMETERS 構造体を使ってレンダリング ターゲットで PushLayer を呼び出すことになります。
場合によっては、ジオメトリにアニメーションを適用する必要があります。最も効率的な方法は、ジオメトリをレンダリングする前にレンダリング ターゲットにマトリックス変換を適用する方法です。しかし、これでは不十分な場合は、レンダリング クラスの Update メソッドなどでジオメトリを再作成する必要が生じます (アウトセットで多数のジオメトリを作成して保存することもあります)。ジオメトリを再作成するとレンダリングのオーバーヘッドが増加しますが、再作成が必要な場合もあります。ただし、ほとんどの場合、ジオメトリを再作成する必要がなければ再作成しないでください。
ジオメトリ シンク
ID2D1PathGeometry オブジェクトは、直線と曲線の集合です。特に、楕円の円周上の曲線である 3 次ベジエ曲線や 2 次ベジエ曲線と弧が含まれています。開発者は、これらの直線と曲線を接続するかどうか、囲まれた領域を定義するかどうかを制御できます。
直線と曲線のパス ジオメトリを塗りつぶすには、ID2D1GeometrySink 型オブジェクトを使用します。この分野でのシンクは、ジオメトリを洗うための "流し" ではありません。これは容器の一種、つまり後でパス ジオメトリで保持する直線と曲線を入れておく場所と考えてください。
パス ジオメトリの構築方法は、次のとおりです。
- ID2D1Factory オブジェクトで CreatePathGeometry メソッドを呼び出して、ID2D1PathGeometry オブジェクトを作成します。
- ID2D1PathGeometry で Open メソッドを呼び出して、新しい ID2D1GeometrySink オブジェクトを取得します。
- ID2D1GeometrySink で複数のメソッドを呼び出して、パス ジオメトリに直線と曲線を追加します。
- ID2D1GeometrySink で Close メソッドを呼び出します。
ID2D1PathGeometry は、ID2D1GeometrySink オブジェクトで Close メソッドを呼び出すまでは使用できません。Close メソッドを呼び出すと ID2D1PathGeometry は不変になります。つまり、どのような方法でも内容を変更できず、Open メソッドを再度呼び出すことはできません。ジオメトリ シンクは意味がなくなっているため、取り除くことができます。
一覧の 3 つ目の項目には、たいていは最も詳細なコードを使用します。パス ジオメトリは図の集合です。それぞれの図は、線分と呼ばれる接続された直線と曲線の連なりです。ID2D1GeometrySink で関数を呼び出す場合は、まず省略可能な SetFillMode メソッドを呼び出して、囲まれた領域の塗りつぶしに使用するアルゴリズムを指定します。続いて、パス ジオメトリの接続された直線と曲線の連なりごとに、次の手順を実行します。
- BeginFigure メソッドを呼び出し、最初の点と、囲まれた領域を塗りつぶすかどうかを示します。
- 名前が Add で始まるメソッドを呼び出して、接続された直線、ベジエ曲線、および弧を図に追加します。
- EndFigure メソッドを呼び出し、最後の点を最初の点に自動的に直線で接続するかどうかを示します。
ID2D1GeometrySink のドキュメントを参照する際は、ID2D1SimplifiedGeometrySink から派生するインターフェイスに注意してください。このインターフェイスは、特に重要なメソッドを実際に定義しています。詳細については、後ほど説明します。
ID2D1PathGeometry の内容はパスを定義すると不変になるため、ID2D1PathGeometry を変更する必要がある場合は、ジオメトリを再作成し、パス定義のプロセスをやり直す必要があります。ただし、追加の図を既存のパス ジオメトリの最初か最後に追加するだけの場合は、手順を省略できます。新しいパス ジオメトリを作成して図を追加でき、続いて新しい ID2D1GeometrySink で既存のパス ジオメトリの Stream 関数を呼び出すことで、既存のパス ジオメトリの内容を新しいパス ジオメトリに転送できます。その後、シンクを閉じる前に図を追加できます。
描画と塗りつぶし
これで、コードを示す準備ができました。ダウンロード可能な GeometryExperimentation プロジェクトは、Visual Studio 2012 で Windows ストアの Direct2D (XAML) テンプレートを使用して作成しました。SimpleTextRenderer クラスの名前を GeometryVarietiesRenderer に変更し、サンプルのテキスト レンダリングに関連付けられたコードとマークアップをすべて削除しました。
XAML ファイルでは、さまざまなジオメトリ レンダリング手法のために多数のラジオ ボタンを定義しました。それぞれのラジオ ボタンは、このプロジェクトで定義した RenderingOption 列挙体のメンバーに関連付けられています。Render オーバーライドの大規模な switch-case ステートメントでは、この RenderingOption 列挙体のメンバーを使用してコードの実行内容を制御します。
ジオメトリの作成はすべて CreateDeviceIndependentResources のオーバーライド中に行います。プログラムで作成するジオメトリの 1 つは、五ぼう星です。図 2に、このジオメトリを作成する多少一般化したメソッドを示します。これは、直線の線分が 4 本ある 1 つの図で構成されていますが、最後の点は自動的に最初の点に接続されます。
図 2 五ぼう星ジオメトリを作成するメソッド
HRESULT GeometryVarietiesRenderer::CreateFivePointedStar(
float radius, ID2D1PathGeometry** ppPathGeometry)
{
if (ppPathGeometry == nullptr)
return E_POINTER;
HRESULT hr = m_d2dFactory->CreatePathGeometry(ppPathGeometry);
ComPtr geometrySink;
if (SUCCEEDED(hr))
{
hr = (*ppPathGeometry)->Open(&geometrySink);
}
if (SUCCEEDED(hr))
{
geometrySink->BeginFigure(Point2F(0, -radius),
D2D1_FIGURE_BEGIN_FILLED);
for (float angle = 2 * XM_2PI / 5;
angle < 2 * XM_2PI; angle += 2 * XM_2PI / 5)
{
float sin, cos;
D2D1SinCos(angle, &sin, &cos);
geometrySink->AddLine(Point2F(radius * sin, -radius * cos));
}
geometrySink->EndFigure(D2D1_FIGURE_END_CLOSED);
hr = geometrySink->Close();
}
return hr;
}
図 3 に、CreateDeviceIndependentResources メソッドの大部分を示します (コードを単純にするために、正常な範囲から逸脱した HRESULT 値の処理は削除しました)。このメソッドでは、まず矩形波に似たジオメトリ、五ぼう星を作成する呼び出し、および無限大記号を作成する別のメソッドの呼び出しを作成します。これらのジオメトリのうち 2 つを変換してから、3 つすべてのジオメトリを CreateGeometryGroup メソッド (図 3の下部で呼び出しています) で、m_geometryGroup という名前のメンバーにまとめます。
図 3 CreateDeviceIndependentResources オーバーライドの大部分
void GeometryVarietiesRenderer::CreateDeviceIndependentResources()
{
DirectXBase::CreateDeviceIndependentResources();
// Create square-wave geometry
HRESULT hr = m_d2dFactory->CreatePathGeometry(&m_squareWaveGeometry);
ComPtr geometrySink;
hr = m_squareWaveGeometry->Open(&geometrySink);
geometrySink->BeginFigure(Point2F(-250, 50),
D2D1_FIGURE_BEGIN_HOLLOW);
geometrySink->AddLine(Point2F(-250, -50));
geometrySink->AddLine(Point2F(-150, -50));
geometrySink->AddLine(Point2F(-150, 50));
geometrySink->AddLine(Point2F(-50, 50));
geometrySink->AddLine(Point2F(-50, -50));
geometrySink->AddLine(Point2F( 50, -50));
geometrySink->AddLine(Point2F( 50, 50));
geometrySink->AddLine(Point2F(150, 50));
geometrySink->AddLine(Point2F(150, -50));
geometrySink->AddLine(Point2F(250, -50));
geometrySink->AddLine(Point2F(250, 50));
geometrySink->EndFigure(D2D1_FIGURE_END_OPEN);
hr = geometrySink->Close();
// Create star geometry and translate it
ComPtr starGeometry;
hr = CreateFivePointedStar(150, &starGeometry);
hr = m_d2dFactory->CreateTransformedGeometry(starGeometry.Get(),
Matrix3x2F::Translation(0, -200),
&m_starGeometry);
// Create infinity geometry and translate it
ComPtr infinityGeometry;
hr = CreateInfinitySign(100, &infinityGeometry);
hr = m_d2dFactory->CreateTransformedGeometry(infinityGeometry.Get(),
Matrix3x2F::Translation(0, 200),
&m_infinityGeometry);
// Create geometry group
CreateGeometryGroup();
...
}
CreateDeviceIndependentResources メソッドは、丸い端と結合操作で 2 つのストローク スタイルも作成します。1 つは実線で、もう 1 つは点線のストローク スタイルです。
CreateDeviceResources メソッドは、描画用の黒いブラシと塗りつぶし用の赤いブラシの 2 つのブラシを作成します。
プログラムを起動したら、最初のラジオ ボタンを確認して、DrawGeometry メソッドを呼び出します。
m_d2dContext->DrawGeometry(m_geometryGroup.Get(),
m_blackBrush.Get());
図 4に結果を示します。風変わりなグラフィックス マニア集団のロゴのようになりました。
図 4 GeometryExperimentation の起動画面
レンダリングを簡略化するためにこのプログラムでは 3 つのジオメトリをまとめたため、すべてのジオメトリが同じブラシでレンダリングされます。実際のプログラムでは、多数の個別のジオメトリを保持し、すべてのジオメトリに別々の色を付けることも考えられます。
最初のいくつかのオプションは、太いストロークやスタイルが設定された線 (点線など) を使用するとジオメトリがどのように描画されるかを示しています (プログラム全体でストロークの太さとして 1、10、および 20 ピクセルを使用したので、容易に見分けられるでしょう)。
XAML でパス ジオメトリとアニメーションを表示する場合、個人的には、XAML ベースのアニメーションをストロークのスタイルのダッシュ オフセットに適用して、ジオメトリの周囲に沿って点を動かすことが好みです。DirectX でも ([Animated Dot Offset] オプションが示すように) 同様の効果を適用できますが、画面を更新するたびに ID2D1StrokeStyle オブジェクトを明示的に再作成する必要があります。この処理は、Update メソッドで実行します。
ジオメトリの囲まれた領域は、ブラシで塗りつぶすこともできます。
m_d2dContext->FillGeometry(m_geometryGroup.Get(),
m_redBrush.Get());
この結果を図 5に示します。矩形波には囲まれた領域がありません。塗りつぶしモードを Alternate というアルゴリズムに設定しているため、五ぼう星の内側の五角形は塗りつぶされません。図 5 の左下に表示されている 1 組のラジオ ボタンを使用して [Winding Fill Mode] を選択すれば、五角形を塗りつぶせます。塗りつぶしモードは ID2D1GeometryGroup の作成時に指定する必要があるため、2 つのラジオ ボタンのどちらかがクリックされたら m_geometryGroup オブジェクトを再作成する必要があります。ジオメトリ グループ内でジオメトリどうしが重なり合う場合、交差する領域もこの塗りつぶしモードに基づいて塗りつぶされます。
図 5 ジオメトリの塗りつぶし
多くの場合は、ジオメトリの描画と塗りつぶしの両方を行う必要があります。一般に、ストローク全体を表示し続けるために、FillGeometry メソッドを呼び出してから DrawGeometry メソッドを呼び出す必要があります。
簡素化したジオメトリと簡素化処理
アプリで ID2D1PathGeometry を動的に (おそらくユーザー入力に基づいて) 作成し、パス ジオメトリに "問い合わせ" て、すべての図と線分を抽出する場合を考えてみましょう。おそらく、抽出した情報は PathGeometry、PathFigure、LineSegment、および BezierSegment という一連の標準的なタグとして XAML 形式で保存する必要があります。
一見したところ、これが実現可能な処理とは思えないでしょう。ID2D1PathGeometry には GetFigureCount メソッドと GetSegmentCount メソッドがありますが、これらの図と線分を実際に抽出するメソッドはありません。
しかし、Stream メソッドを思い出してください。このメソッドは、ID2D1GeometrySink を受け取り、このシンクにパス ジオメトリの内容をコピーします。ここで重要なのは、ID2D1GeometrySink インターフェイスを実装する独自のクラスを作成し、このクラスのインスタンスを Stream メソッドに渡すことです。このカスタム クラスで、BeginFigure、AddLine などのすべての呼び出しを処理し、これらの呼び出しを使って必要な操作をすべて実行できます。
もちろん、このようなクラスは簡単には作成できません。ID2D1GeometrySink に加えて、ID2D1SimplifiedGeometrySink と IUnknown のすべてのメソッドを実装する必要があります。
ただし、この作業を多少簡略化する方法があります。ID2D1Geometry インターフェイスは、Simplify という名前のメソッドを定義しています。このメソッドは、あらゆるジオメトリを直線と 3 次ベジエ スプラインのみが含まれた "簡素化した" ジオメトリに変換します。この処理が可能なのは、2 次ベジエ スプラインと弧を 3 次ベジエ スプラインで近似できるためです。つまり、カスタム クラスで必要な作業は ID2D1SimplifiedGeometrySink メソッドと IUnknown メソッドの実装だけです。カスタム クラスのインスタンスを任意のジオメトリの Simplify メソッドに渡せば十分です。
また、Simplify メソッドを使用すると、ジオメトリの簡素化した内容を新しいパス ジオメトリにコピーできます。この処理を実行する GeometryExperimentation のコードは、次のとおりです (HRESULT のチェックは省略しています)。
m_d2dFactory->CreatePathGeometry(&m_simplifiedGeometry);
ComPtr geometrySink;
m_simplifiedGeometry->Open(&geometrySink);
m_geometryGroup->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
IdentityMatrix(), geometrySink.Get());
geometrySink->Close();
Simplify メソッドの最初の引数は、簡素化したパス ジオメトリに 3 次ベジエと直線の両方が必要なことを示している点に注目してください。これを直線だけに限定して、ベジエ曲線を一連の直線で近似することもできます。この処理を、"フラット化" と呼びます。高い精度でフラット化を実行した場合は視覚的に区別できなくなりますが、フラット化の許容値を指定して、ベジエ曲線をそれほど精密に近似しないようにすることもできます。GeometryExperimentation に含まれる、"著しく簡素化した" ジオメトリを作成するコードは次のとおりです。
m_d2dFactory->CreatePathGeometry(&m_grosslySimplifiedGeometry);
m_grosslySimplifiedGeometry->Open(&geometrySink);
m_geometryGroup->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
IdentityMatrix(), 20, geometrySink.Get());
geometrySink->Close();
星と矩形波は同じように表示されますが、無限大記号はそれほど滑らかではなくなりました (図 6参照)。既定では、フラット化の許容値は 0.25 です。
図 6 著しくフラット化した無限大記号
その他のジオメトリ操作
ID2D1Geometry インターフェイスは、Simplify と同様に新しいジオメトリを計算して ID2D1SimplifiedGeometrySink に書き込むメソッドを、さらに 3 つ定義しています。ここでは、Outline メソッドと Widen メソッドについて説明しますが、CombineWithGeometry メソッドについての説明は省略します (このメソッドは複数の重なり合うジオメトリに対して興味深い処理を実行するだけで、今回のプログラムでは使用しないためです)。
先ほどご覧のとおり、パス ジオメトリには線分の交点があります。無限大記号には、中央に 1 か所線分の交点があり、五ぼう星には多くの交点があります。ID2D1Geometry で定義している Outline メソッドは、既存のパス ジオメトリに基づいて、これらの交点を削除しながら囲まれた領域をそのまま維持し、新しいパス ジオメトリを作成します。
ジオメトリ グループを輪郭で表現したパス ジオメトリに変換する GeometryExperimentation のコードは、次のとおりです。
m_d2dFactory->CreatePathGeometry(&m_outlinedGeometry);
m_outlinedGeometry->Open(&geometrySink);
m_geometryGroup->Outline(IdentityMatrix(), geometrySink.Get());
geometrySink->Close();
この m_outlinedGeometry オブジェクトは m_geometryGroup と同じ塗りつぶし領域を定義しています。違いは、m_geometryGroup を [Alternate Fill Mode] と [Winding Fill Mode] のどちらを指定して作成したかどうかです。
元のジオメトリ グループには、五ぼう星に 1 つ、矩形波に 1 つ、および無限大記号に 1 つで計 3 つの図がありますこのジオメトリ グループを [Alternate Fill Mode] で作成した場合、輪郭のジオメトリには、五ぼう星に 5 つ、矩形波に 1 つ、無限大記号に 2 つで計 8 つの図が含まれますが、見た目は同じように思えます。一方、ジオメトリ グループを [Winding Fill Mode] で作成した場合、輪郭のジオメトリには計 4 つの図が含まれます。つまり、無限大記号には [Alternate Fill Mode] の場合と同様に 2 つの図がありますが、五ぼう星の内側がすべて塗りつぶされているため、五ぼう星には 1 つの図だけが含まれています (図 7参照)。
図 7 輪郭のパス ジオメトリ
こうしたジオメトリをゼロから定義することは数学的にかなり難しい一方、Outline メソッドを使用すると非常に簡単になります。Outline メソッドで定義したパス ジオメトリには線分の交点が含まれないため、塗りつぶしモードの影響を受けません。
すべてのメソッドの中で最も興味深いと言えるメソッドは、Widen メソッドです。Widen メソッドのしくみを理解するために、2 つの点を結ぶ直線が 1 本だけ含まれたパス ジオメトリについて考えてみましょう。このジオメトリを描画すると、ストロークが特定の太さの線になるため、実際には塗りつぶされた四角形のようにレンダリングされます。丸い端が線のスタイルに含まれている場合、この四角形は 2 つの塗りつぶされた半円で装飾されます。
Widen メソッドは、このレンダリングされたオブジェクトの輪郭を描画するパス ジオメトリを計算します。このため、DrawGeometry メソッドと同様に、Widen メソッドには目的のストロークの太さとストロークのスタイルを指定する引数が必要です。GeometryExperimentation プロジェクトのコードを次に示します。
m_d2dFactory->CreatePathGeometry(&m_widenedGeometry);
m_widenedGeometry->Open(&geometrySink);
m_geometryGroup->Widen(20, m_roundedStrokeStyle.Get(),
IdentityMatrix(), geometrySink.Get());
geometrySink->Close();
ストロークの太さを 20 ピクセルに指定していることに注意してください。続いて、プログラムは 1 ピクセルのストロークの太さを使用して、この拡張したジオメトリを描画します。
m_d2dContext->DrawGeometry(m_widenedGeometry.Get(),
m_blackBrush.Get(), 1);
結果を図 8 に示します。この処理で作成した図形は非常に興味深いものです。まるで、線の描画アルゴリズムの内部をのぞき込んでいるかのようです。
図 8 拡張したパス ジオメトリ
GeometryExperimentation プログラムは、拡張したパス ジオメトリを塗りつぶすこともできます。
m_d2dContext->FillGeometry(m_widenedGeometry.Get(),
m_redBrush.Get());
特定のストロークの幅とストロークのスタイルで拡張したパス ジオメトリを塗りつぶすと、この幅とスタイルで元のパスのストロークを描画した場合と同じ見た目になります。GeometryExperimentation の [Draw Rounded Wide Stroke] オプションと [Fill Widened] オプションの唯一の視覚的な違いは、色です。これは、描画には黒を使用し、塗りつぶしには赤を使用するためです。
拡張したパス ジオメトリを塗りつぶして描画することも考えられますが、内側の図形を削除する方が人気が高いでしょう。この処理はきわめて簡単です。次のように、拡張したパス ジオメトリに Outline メソッドを適用するだけです。
m_d2dFactory->CreatePathGeometry(&m_outlinedWidenedGeometry);
m_outlinedWidenedGeometry->Open(&geometrySink);
m_widenedGeometry->Outline(IdentityMatrix(), geometrySink.Get());
geometrySink->Close();
これで、拡張した輪郭のパス ジオメトリを塗りつぶして描画すると、図 9のような画像が生成されます。内側の図形が生成されず、このプログラムでレンダリングされる他の図形とは大きく異なる見た目で、思い切ってコードをゼロから作成した場合のいずれの図形とも異なります。
図 9 描画して塗りつぶし、拡張した輪郭のパス ジオメトリ
その他の操作
ジオメトリ データを ID2D1SimplifiedGeometrySink に書き込むメソッドはもう 1 つありますが、よく探さなければ見つからないでしょう。Direct2D インターフェイスにこのメソッドは含まれていません。このメソッドは、DirectWrite に含まれていて、具体的には、IDWriteFontFace の GetGlyphRunOutline メソッドです。この強力なメソッドは、テキスト文字の輪郭からパス ジオメトリを生成します。無視するにはもったいないほどおもしろいメソッドですので、お見逃しなく。
Charles Petzold は MSDN マガジンの記事を長期にわたって担当しており、Windows 8 向けのアプリ開発についての書籍『Programming Windows, 6th edition』 (O'Reilly Media、2012 年) の著者でもあります。彼の Web サイトは charlespetzold.com(英語) です。
この記事のレビューに協力してくれた技術スタッフの Wessam Bahnassi (In|Framez Technology)、Worachai Chaoweeraprasit (マイクロソフト)、Anthony Hodsdon (マイクロソフト)、および Michael B. McLaughlin (Bob Taco Industries) に心より感謝いたします。
Anthony Hodsdon は、Windows 7 で Direct2D が誕生して以来、Direct2D チームで開発者を務めてきました。職業柄、彼は幾何学 (分析およびユークリッド)、数値アルゴリズムなどに注目しています。
Worachai Chaoweeraprasit は、Direct2D と DirectWrite の開発を指揮しています。すばらしい文字体裁と驚くほど速いグラフィックスの愛好家でもあります。余暇には、ブロックを動かすよりも簡単なプログラミングの方法を 3 年生の子供に教えたことがあります。彼の教えによると、このプログラミング方法は C という名前です。
Michael B. McLaughlin は、Visual C++ MVP であり、マイクロ ISV およびコンサルティング企業、Bob Taco Industries の経営者です。また、以前に XNA/DirectX MVP を受賞したことがあり、元弁護士でもあります。彼の Web サイトは bobtacoindustries.com(英語) で、Twitter のハンドルネームは @mikebmcl(英語) です。
Wessam Bahnassi は、コンピューター グラフィックスとゲームに情熱を燃やすソフトウェア エンジニアです。彼は、Electronic Arts でリード レンダリング エンジニアリングを 7 年間務めていました。現在は、In|Framez Technology Corp. のリード プログラマと Arabic Game Developer Network の監督者を務めており、2003 年から DirectX MVP であり、現在は Visual C++ MVP にもなりました。