Contêineres gráficos aninhados
O Windows GDI+ fornece contêineres que você pode usar para substituir temporariamente ou aumentar parte do estado em um objetoGraphics. Você cria um contêiner chamando o Graphics::BeginContainer método de um objeto Graphics. Você pode chamar Graphics::BeginContainer repetidamente para formar contêineres aninhados.
Transformações em contêineres aninhados
O exemplo a seguir cria um objeto Graphics e um contêiner dentro desse objeto Graphics. A transformação mundial do objeto Graphics é uma tradução de 100 unidades na direção x e 80 unidades na direção y. A transformação mundial do contentor é uma rotação de 30 graus. O código faz a chamada
DrawRectangle(&pen, -60, -30, 120, 60)
duas vezes. A primeira chamada para Graphics::D rawRectangle é dentro do contêiner; ou seja, a chamada está entre as chamadas para Graphics::BeginContainer e Graphics::EndContainer. A segunda chamada para Graphics::D rawRectangle é após a chamada para 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);
No código anterior, o retângulo desenhado de dentro do contêiner é transformado primeiro pela transformação mundial do contêiner (rotação) e, em seguida, pela transformação mundial do objeto Graphics (tradução). O retângulo desenhado de fora do contêiner é transformado apenas pela transformação do mundo do objeto Graphics (tradução). A ilustração a seguir mostra os dois retângulos.
Clipping em contêineres aninhados
O exemplo a seguir ilustra como os contêineres aninhados lidam com regiões de recorte. O código cria um objeto Graphics e um contêiner dentro desse objeto Graphics. A região de recorte do objeto Graphics é um retângulo e a região de recorte do contêiner é uma elipse. O código faz duas chamadas para o Graphics::D rawLine método. A primeira chamada para Graphics::D rawLine está dentro do contêiner e a segunda chamada para Graphics::D rawLine está fora do contêiner (após a chamada para Graphics::EndContainer). A primeira linha é cortada pela intersecção das duas regiões de recorte. A segunda linha é cortada apenas pela região de recorte retangular do objeto 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);
A ilustração a seguir mostra as duas linhas cortadas.
Como mostram os dois exemplos anteriores, as transformações e as regiões de recorte são cumulativas em contêineres aninhados. Se você definir as transformações de mundo do contêiner e o objeto Graphics, ambas as transformações serão aplicadas aos itens extraídos de dentro do contêiner. A transformação do contêiner será aplicada primeiro, e a transformação do objeto Graphics será aplicada em segundo lugar. Se você definir as regiões de recorte do contêiner e o objeto Graphics, os itens extraídos de dentro do contêiner serão cortados pela interseção das duas regiões de recorte.
Configurações de qualidade em contêineres aninhados
As configurações de qualidade (SmoothingMode, TextRenderingHinte similares) em contêineres aninhados não são cumulativas; em vez disso, as configurações de qualidade do contêiner substituem temporariamente as configurações de qualidade de um objeto Graphics. Quando você cria um novo contêiner, as configurações de qualidade para esse contêiner são definidas como valores padrão. Por exemplo, suponha que você tenha um objeto Graphics com um modo de suavização de SmoothingModeAntiAlias. Quando você cria um contêiner, o modo de suavização dentro do contêiner é o modo de suavização padrão. Você é livre para definir o modo de suavização do recipiente, e quaisquer itens retirados de dentro do recipiente serão desenhados de acordo com o modo que você definir. Os itens desenhados após a chamada para Graphics::EndContainer serão desenhados de acordo com o modo de suavização (SmoothingModeAntiAlias) que estava em vigor antes da chamada para Graphics::BeginContainer.
Várias camadas de contêineres aninhados
Você não está limitado a um contêiner em um objeto Graphics. Você pode criar uma sequência de contêineres, cada um aninhado no anterior, e pode especificar a transformação mundial, a região de recorte e as configurações de qualidade de cada um desses contêineres aninhados. Se você chamar um método de desenho de dentro do contêiner mais interno, as transformações serão aplicadas em ordem, começando com o contêiner mais interno e terminando com o contêiner mais externo. Os itens retirados de dentro do recipiente mais interno serão cortados pela interseção de todas as regiões de recorte.
O exemplo a seguir cria um objeto Graphics e define sua dica de renderização de texto como TextRenderingHintAntiAlias. O código cria dois contêineres, um aninhado no outro. A dica de renderização de texto do contêiner externo é definida como TextRenderingHintSingleBitPerPixele a dica de renderização de texto do contêiner interno é definida como TextRenderingHintAntiAlias. O código desenha três cadeias de caracteres: uma do contêiner interno, uma do contêiner externo e uma do Graphics objeto em si.
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);
A ilustração a seguir mostra as três cadeias de caracteres. As cadeias de caracteres extraídas do contêiner interno e do objeto Graphics são suavizadas pela suavização de serrilhado. A cadeia de caracteres extraída do contêiner externo não é suavizada pela suavização de borda devido à configuração TextRenderingHintSingleBitPerPixel.