次の方法で共有


入れ子になったグラフィックス コンテナー

Windows GDI+ には、Graphics オブジェクトの状態の一部を一時的に置換または拡張するために使用できるコンテナーが用意されています。 Graphics オブジェクトの Graphics::BeginContainer メソッドを呼び出して、コンテナーを作成します。 Graphics::BeginContainer を繰り返し呼び出して、入れ子になったコンテナーを形成できます。

入れ子になったコンテナーの変換

次の例では、Graphics オブジェクトとその Graphics オブジェクト内にコンテナーを作成します。 Graphics オブジェクトのワールド変換は、x 方向に 100 単位、y 方向に 80 単位の平行移動です。 コンテナーのワールド変換は 30 度回転です。 コードが呼び出しを行う

DrawRectangle(&pen, -60, -30, 120, 60)

二度。 Graphics::D rawRectangle の最初の呼び出しは、コンテナー 内でされます。つまり、Graphics::BeginContainerGraphics::EndContainerの呼び出しの間に呼び出しが行われます。 Graphics::D rawRectangle への 2 回目の呼び出しは、Graphics::EndContainerの呼び出しの後です。

Graphics           graphics(hdc);
Pen                pen(Color(255, 255, 0, 0));
GraphicsContainer  graphicsContainer;

graphics.TranslateTransform(100.0f, 80.0f);

graphicsContainer = graphics.BeginContainer();
   graphics.RotateTransform(30.0f);
   graphics.DrawRectangle(&pen, -60, -30, 120, 60);
graphics.EndContainer(graphicsContainer);

graphics.DrawRectangle(&pen, -60, -30, 120, 60);

前のコードでは、コンテナー内から描画された四角形は、最初にコンテナーのワールド変換 (回転) によって変換され、次に Graphics オブジェクトのワールド変換 (変換) によって変換されます。 コンテナーの外側から描画された四角形は、Graphics オブジェクトのワールド変換 (平行移動) によってのみ変換されます。 次の図は、2 つの四角形を示しています。

2 つの赤い四角形が同じポイントの中央に配置されているが、回転が異なるウィンドウのスクリーン ショット

 

入れ子になったコンテナーでのクリッピング

次の例は、入れ子になったコンテナーがクリッピング領域を処理する方法を示しています。 このコードにより、Graphics オブジェクトと、その Graphics オブジェクト内にコンテナーが作成されます。 Graphics オブジェクトのクリッピング領域は四角形で、コンテナーのクリッピング領域は楕円です。 このコードは、Graphics::D rawLine メソッドを 2 回呼び出します。 Graphics::D rawLine の最初の呼び出しはコンテナー内にあり、Graphics::D rawLine の 2 回目の呼び出しはコンテナーの外部にあります (Graphics::EndContainerの呼び出しの後)。 最初の行は、2 つのクリッピング領域の交差部分によってクリップされます。 2 行目は、Graphics オブジェクトの四角形のクリッピング領域によってのみクリップされます。

Graphics           graphics(hdc);
GraphicsContainer  graphicsContainer;
Pen                redPen(Color(255, 255, 0, 0), 2);
Pen                bluePen(Color(255, 0, 0, 255), 2);
SolidBrush         aquaBrush(Color(255, 180, 255, 255));
SolidBrush         greenBrush(Color(255, 150, 250, 130));

graphics.SetClip(Rect(50, 65, 150, 120));
graphics.FillRectangle(&aquaBrush, 50, 65, 150, 120);

graphicsContainer = graphics.BeginContainer();
   // Create a path that consists of a single ellipse.
   GraphicsPath path;
   path.AddEllipse(75, 50, 100, 150);

  // Construct a region based on the path.
   Region region(&path);
   graphics.FillRegion(&greenBrush, &region);

   graphics.SetClip(&region);
   graphics.DrawLine(&redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);

graphics.DrawLine(&bluePen, 70, 0, 370, 300);

次の図は、2 つのクリップされた行を示しています。

四角形内の楕円の 図。一方の線は楕円で、もう一方は四角形によってクリップ

前の 2 つの例に示すように、入れ子になったコンテナーでは変換とクリッピング領域が累積されます。 コンテナーと Graphics オブジェクトのワールド変換を設定すると、両方の変換がコンテナー内から描画された項目に適用されます。 コンテナーの変換が最初に適用され、Graphics オブジェクトの変換が 2 番目に適用されます。 コンテナーのクリッピング領域と Graphics オブジェクトを設定すると、コンテナー内から描画された項目は、2 つのクリッピング領域の積集合によってクリップされます。

入れ子になったコンテナーの品質設定

入れ子になったコンテナーの品質設定 (SmoothingModeTextRenderingHintなど) は累積されません。代わりに、コンテナーの品質設定によって、Graphics オブジェクトの品質設定が一時的に置き換えられます。 新しいコンテナーを作成すると、そのコンテナーの品質設定が既定値に設定されます。 たとえば、smoothingModeAntiAliasのスムージング モードを持つ Graphics オブジェクトがあるとします。 コンテナーを作成する場合、コンテナー内のスムージング モードが既定のスムージング モードになります。 コンテナーのスムージング モードは自由に設定でき、コンテナー内から描画されるすべての項目は、設定したモードに従って描画されます。 Graphics::EndContainer の呼び出し後に描画された項目は、Graphics::BeginContainerの呼び出しの前に配置されたスムージング モード (SmoothingModeAntiAlias) に従って描画されます。

入れ子になったコンテナーの複数のレイヤー

Graphics オブジェクト内のコンテナーは 1 つに限定されません。 前の手順で入れ子になったコンテナーのシーケンスを作成できます。また、入れ子になった各コンテナーのワールド変換、クリッピング領域、品質設定を指定できます。 最も内側のコンテナー内から描画メソッドを呼び出すと、最も内側のコンテナーから始まり、最も外側のコンテナーで終わる順に変換が適用されます。 最も内側のコンテナー内から描画された項目は、すべてのクリッピング領域の交差部分によってクリップされます。

次の例では、Graphics オブジェクトを作成し、そのテキスト レンダリング ヒントを TextRenderingHintAntiAliasに設定します。 このコードでは、2 つのコンテナーが作成されます。1 つはもう 1 つのコンテナー内に入れ子になります。 外部コンテナーのテキスト レンダリング ヒントは TextRenderingHintSingleBitPerPixelに設定され、内部コンテナーのテキスト レンダリング ヒントは textRenderingHintAntiAliasに設定されます。 このコードでは、内部コンテナーから 1 つ、外側のコンテナーから 1 つ、Graphics オブジェクト自体から 1 つという 3 つの文字列を描画します。

Graphics graphics(hdc);
GraphicsContainer innerContainer;
GraphicsContainer outerContainer;
SolidBrush brush(Color(255, 0, 0, 255));
FontFamily fontFamily(L"Times New Roman");
Font font(&fontFamily, 36, FontStyleRegular, UnitPixel);

graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);

outerContainer = graphics.BeginContainer();

   graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel);

   innerContainer = graphics.BeginContainer();
      graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
      graphics.DrawString(L"Inner Container", 15, &font,
         PointF(20, 10), &brush);
   graphics.EndContainer(innerContainer);

   graphics.DrawString(L"Outer Container", 15, &font, PointF(20, 50), &brush);

graphics.EndContainer(outerContainer);

graphics.DrawString(L"Graphics Object", 15, &font, PointF(20, 90), &brush);

次の図は、3 つの文字列を示しています。 内部コンテナーと Graphics オブジェクトから描画された文字列は、アンチエイリアシングによって平滑化されます。 TextRenderingHintSingleBitPerPixel 設定のため、外部コンテナーから描画された文字列はアンチエイリアシングによって平滑化されません。

同じ文字列を含む四角形の図。最初と最後の行の文字のみが滑らかな