Share via


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

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::BeginContainer と Graphics::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 つのコンテナーが作成されます。 外側のコンテナーのテキスト レンダリング ヒントは 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 設定のため、外部コンテナーから描画された文字列はアンチエイリアシングによって平滑化されません。

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