중첩된 그래픽 컨테이너
Windows GDI+는 그래픽 개체에서 상태의 일부를 일시적으로 바꾸거나 보강하는 데 사용할 수 있는 컨테이너를 제공합니다. 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에 대한 두 번째 호출은 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 개체(변환)의 월드 변환에 의해서만 변환됩니다. 다음 그림에서는 두 사각형을 보여 줍니다.
중첩된 컨테이너에서 클리핑
다음 예제에서는 중첩된 컨테이너가 클리핑 영역을 처리하는 방법을 보여 줍니다. 이 코드는 Graphics 개체와 해당 Graphics 개체 내에 컨테이너를 만듭니다. Graphics 개체의 클리핑 영역은 사각형이며 컨테이너의 클리핑 영역은 타원입니다. 이 코드는 Graphics::D rawLine 메서드를 두 차례 호출합니다. Graphics::D rawLine에 대한 첫 번째 호출은 컨테이너 내에 있으며 Graphics::D rawLine에 대한 두 번째 호출은 Graphics::EndContainer 호출 후 컨테이너 외부에 있습니다. 첫 번째 줄은 두 클리핑 영역의 교차에 의해 잘립니다. 두 번째 줄은 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, ®ion);
graphics.SetClip(®ion);
graphics.DrawLine(&redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);
graphics.DrawLine(&bluePen, 70, 0, 370, 300);
다음 그림에서는 잘린 두 줄을 보여 줍니다.
앞의 두 예제에서 보여주듯이, 변환 및 클리핑 영역은 중첩된 컨테이너에서 누적됩니다. 컨테이너와 Graphics 개체의 월드 변환을 설정하면 컨테이너 내부에서 가져온 항목에 두 변환이 모두 적용됩니다. 컨테이너의 변환이 먼저 적용되고 Graphics 개체의 변환이 두 번째로 적용됩니다. 컨테이너 및 Graphics 개체의 클리핑 영역을 설정하면 컨테이너 내부에서 가져온 항목이 두 클리핑 영역의 교차점에 의해 잘립니다.
중첩 컨테이너의 품질 설정
중첩된 컨테이너의 품질 설정( SmoothingMode, TextRenderingHint 등)은 누적되지 않습니다. 오히려 컨테이너의 품질 설정이 일시적으로 Graphics 개체의 품질 설정을 대체합니다. 새 컨테이너를 만들 때 해당 컨테이너의 품질 설정이 기본값으로 설정됩니다. 예를 들어 부드러운 모드의 SmoothingModeAntiAlias가 있는 Graphics 개체가 있다고 가정합니다. 컨테이너를 만들 때 컨테이너 내의 평활 모드는 기본 평활 모드입니다. 컨테이너의 평활 모드를 자유롭게 설정할 수 있으며, 컨테이너 내부에서 가져온 모든 항목은 설정한 모드에 따라 그려집니다. Graphics::EndContainer 호출 후에 그려진 항목은 Graphics::BeginContainer를 호출하기 전에 배치된 다듬기 모드(SmoothingModeAntiAlias)에 따라 그려집니다.
중첩된 컨테이너의 여러 레이어
Graphics 개체에서 하나의 컨테이너로 제한되지 않습니다. 앞에서는 각각 중첩된 컨테이너 시퀀스를 만들 수 있으며, 이러한 중첩된 컨테이너 각각의 월드 변환, 클리핑 영역 및 품질 설정을 지정할 수 있습니다. 맨 안쪽에 있는 컨테이너 내에서 그리기 메서드를 호출하면 가장 안쪽 컨테이너에서 시작해서 가장 바깥쪽 컨테이너로 끝나는 순서대로 변환이 적용됩니다. 가장 안쪽 컨테이너 내부에서 가져온 항목은 모든 클리핑 영역의 교차점에 의해 잘립니다.
다음 예제에서는 Graphics 개체를 만들고 텍스트 렌더링 힌트를 TextRenderingHintAntiAlias로 설정합니다. 코드는 하나가 다른 컨테이너 내에 중첩된 방식으로, 두 개의 컨테이너를 생성합니다. 외부 컨테이너의 텍스트 렌더링 힌트는 TextRenderingHintSingleBitPerPixel로 설정되고 내부 컨테이너의 텍스트 렌더링 힌트는 TextRenderingHintAntiAlias로 설정됩니다. 코드는 세 개의 문자열을 그립니다. 하나는 내부 컨테이너에서, 하나는 외부 컨테이너에서, 다른 하나는 Graphics 개체 자체에서 가져옵니다.
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);
다음 그림은 세 개의 문자열을 보여줍니다. 내부 컨테이너와 Graphics 개체에서 가져온 문자열은 앤티앨리어싱으로 부드럽게 됩니다. TextRenderingHintSingleBitPerPixel 설정으로 인해 외부 컨테이너에서 가져온 문자열은 앤티앨리어싱으로 인해 부드럽게 처리되지 않습니다.