Compartir a través de


Contenedores de gráficos anidados

Windows GDI+ proporciona contenedores que puedes usar para reemplazar o aumentar temporalmente parte del estado en un objeto Graphics . Para crear un contenedor, llame al método Graphics::BeginContainer de un objeto Graphics . Puede llamar a Graphics::BeginContainer repetidamente para formar contenedores anidados.

Transformaciones en contenedores anidados

En el ejemplo siguiente se crea un objeto Graphics y un contenedor dentro de ese objeto Graphics . La transformación mundial del objeto Graphics es una traducción de 100 unidades en la dirección x y 80 unidades en la dirección y. La transformación global del contenedor es una rotación de 30 grados. El código realiza la llamada

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

Dos veces. La primera llamada a Graphics::D rawRectangle está dentro del contenedor; es decir, la llamada está entre las llamadas a Graphics::BeginContainer y Graphics::EndContainer. La segunda llamada a Graphics::D rawRectangle es después de la llamada a 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);

En el código anterior, el rectángulo dibujado desde dentro del contenedor se transforma primero por la transformación mundial del contenedor (rotación) y, a continuación, por la transformación del mundo del objeto Graphics (traducción). El rectángulo dibujado desde fuera del contenedor solo se transforma mediante la transformación mundial del objeto Graphics (traducción). En la ilustración siguiente se muestran los dos rectángulos.

captura de pantalla de una ventana con dos rectángulos rojos centrados en el mismo punto, pero con rotaciones diferentes

 

Recorte en contenedores anidados

En el ejemplo siguiente se muestra cómo los contenedores anidados controlan las regiones de recorte. El código crea un objeto Graphics y un contenedor dentro de ese objeto Graphics . La región de recorte del objeto Graphics es un rectángulo y la región de recorte del contenedor es una elipse. El código realiza dos llamadas al método Graphics::D rawLine . La primera llamada a Graphics::D rawLine está dentro del contenedor y la segunda llamada a Graphics::D rawLine está fuera del contenedor (después de la llamada a Graphics::EndContainer). La primera línea se recorta mediante la intersección de las dos zonas de recorte. La segunda línea solo se recorta mediante la región de recorte rectangular del 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, &region);

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

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

En la ilustración siguiente se muestran las dos líneas recortadas.

ilustración de una elipse dentro de un rectángulo, con una línea recortada por la elipse y la otra por el rectángulo

Como se muestran en los dos ejemplos anteriores, las transformaciones y las zonas de recorte se acumulan en contenedores anidados. Si establece las transformaciones del mundo del contenedor y el objeto Graphics , ambas transformaciones se aplicarán a los elementos dibujados desde dentro del contenedor. La transformación del contenedor se aplicará primero y la transformación del objeto Graphics se aplicará en segundo lugar. Si establece las regiones de recorte del contenedor y el objeto Graphics , los elementos dibujados desde dentro del contenedor se recortarán mediante la intersección de las dos regiones de recorte.

Configuración de calidad en contenedores anidados

Configuración de calidad ( SmoothingMode, TextRenderingHint y similar) en contenedores anidados no son acumulativas; en su lugar, la configuración de calidad del contenedor reemplaza temporalmente la configuración de calidad de un objeto Graphics . Al crear un contenedor, la configuración de calidad de ese contenedor se establece en los valores predeterminados. Por ejemplo, supongamos que tiene un objeto Graphics con un modo de suavizado de SmoothingModeAntiAlias. Al crear un contenedor, el modo de suavizado dentro del contenedor es el modo de suavizado predeterminado. Puede establecer el modo de suavizado del contenedor y los elementos extraídos desde dentro de este se dibujarán según el modo establecido. Los elementos dibujados después de la llamada a Graphics::EndContainer se dibujarán según el modo de suavizado (SmoothingModeAntiAlias) que estaba en su lugar antes de la llamada a Graphics::BeginContainer.

Varias capas de contenedores anidados

No se limita a un contenedor de un objeto Graphics . Puede crear una secuencia de contenedores, cada uno anidado en el anterior, y puede especificar la transformación global, la zona de recorte y la configuración de calidad de cada uno de esos contenedores anidados. Si llama a un método de dibujo desde dentro del contenedor más interno, las transformaciones se aplicarán en orden, empezando por el contenedor más interno y finalizando con el contenedor más externo. Los elementos dibujados desde dentro del contenedor más interno se recortarán mediante la intersección de todas las zonas de recorte.

En el ejemplo siguiente se crea un objeto Graphics y se establece su sugerencia de representación de texto en TextRenderingHintAntiAlias. El código crea dos contenedores, uno anidado dentro del otro. La sugerencia de representación de texto del contenedor externo se establece en TextRenderingHintSingleBitPerPixel y la sugerencia de representación de texto del contenedor interno se establece en TextRenderingHintAntiAlias. El código dibuja tres cadenas: una del contenedor interno, otra del contenedor externo y otra del propio objeto 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);

En la siguiente ilustración se muestran las tres cadenas. Las cadenas extraídas del contenedor interno y el objeto Graphics se suavizan mediante suavizado de suavizado. La cadena dibujada desde el contenedor externo no se suaviza mediante suavizado debido a la configuración TextRenderingHintSingleBitPerPixel.

ilustración de un rectángulo que contiene la misma cadena allí veces; solo los caracteres de las primeras y últimas líneas son suaves.