Partager via


Conteneurs Graphics imbriqués

Windows GDI+ fournit des conteneurs que vous pouvez utiliser pour remplacer ou augmenter temporairement une partie de l’état dans un objet Graphics . Vous créez un conteneur en appelant la méthode Graphics::BeginContainer d’un objet Graphics . Vous pouvez appeler Graphics::BeginContainer à plusieurs reprises pour former des conteneurs imbriqués.

Transformations dans les conteneurs imbriqués

L’exemple suivant crée un objet Graphics et un conteneur dans cet objet Graphics . La transformation mondiale de l’objet Graphics est une traduction de 100 unités dans la direction x et de 80 unités dans la direction y. La transformation mondiale du conteneur est une rotation de 30 degrés. Le code effectue l’appel

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

Deux reprises. Le premier appel à Graphics::D rawRectangle se trouve à l’intérieur du conteneur ; autrement dit, l’appel se trouve entre les appels à Graphics::BeginContainer et Graphics::EndContainer. Le deuxième appel à Graphics::D rawRectangle se situe après l’appel à 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);

Dans le code précédent, le rectangle dessiné à l’intérieur du conteneur est d’abord transformé par la transformation du monde du conteneur (rotation), puis par la transformation de monde de l’objet Graphics (traduction). Le rectangle dessiné à l’extérieur du conteneur est transformé uniquement par la transformation du monde de l’objet Graphics (traduction). L’illustration suivante montre les deux rectangles.

capture d’écran d’une fenêtre avec deux rectangles rouges centrés sur le même point, mais avec des rotations différentes

 

Découpage dans les conteneurs imbriqués

L’exemple suivant illustre la façon dont les conteneurs imbriqués gèrent les régions de découpage. Le code crée un objet Graphics et un conteneur dans cet objet Graphics . La zone de découpage de l’objet Graphics est un rectangle et la zone de découpage du conteneur est une ellipse. Le code effectue deux appels à la méthode Graphics::D rawLine . Le premier appel à Graphics::D rawLine se trouve à l’intérieur du conteneur, et le deuxième appel à Graphics::D rawLine se trouve en dehors du conteneur (après l’appel à Graphics::EndContainer). La première ligne est coupée par l’intersection des deux régions de découpage. La deuxième ligne est découpée uniquement par la zone de découpage rectangulaire de l’objet 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);

L’illustration suivante montre les deux lignes coupées.

illustration d’une ellipse à l’intérieur d’un rectangle, avec une ligne coupée par l’ellipse et l’autre par le rectangle

Comme le montrent les deux exemples précédents, les transformations et les régions de découpage sont cumulatives dans des conteneurs imbriqués. Si vous définissez les transformations mondiales du conteneur et de l’objet Graphics , les deux transformations s’appliquent aux éléments dessinés à l’intérieur du conteneur. La transformation du conteneur sera appliquée en premier, et la transformation de l’objet Graphics sera appliquée en second. Si vous définissez les zones de découpage du conteneur et de l’objet Graphics , les éléments dessinés à l’intérieur du conteneur sont coupés par l’intersection des deux régions de découpage.

Paramètres de qualité dans les conteneurs imbriqués

Les paramètres de qualité ( SmoothingMode, TextRenderingHint et similaires) dans les conteneurs imbriqués ne sont pas cumulatifs ; au lieu de cela, les paramètres de qualité du conteneur remplacent temporairement les paramètres de qualité d’un objet Graphics . Lorsque vous créez un conteneur, les paramètres de qualité de ce conteneur sont définis sur les valeurs par défaut. Par exemple, supposons que vous ayez un objet Graphics avec un mode de lissage SmoothingModeAntiAlias. Lorsque vous créez un conteneur, le mode de lissage à l’intérieur du conteneur est le mode de lissage par défaut. Vous êtes libre de définir le mode de lissage du conteneur, et tous les éléments dessinés à l’intérieur du conteneur seront dessinés en fonction du mode que vous définissez. Les éléments dessinés après l’appel à Graphics::EndContainer sont dessinés selon le mode de lissage (SmoothingModeAntiAlias) qui était en place avant l’appel à Graphics::BeginContainer.

Plusieurs couches de conteneurs imbriqués

Vous n’êtes pas limité à un seul conteneur dans un objet Graphics . Vous pouvez créer une séquence de conteneurs, chacun imbriqué dans le précédent, et spécifier la transformation du monde, la région de découpage et les paramètres de qualité de chacun de ces conteneurs imbriqués. Si vous appelez une méthode de dessin à partir du conteneur le plus interne, les transformations sont appliquées dans l’ordre, en commençant par le conteneur le plus interne et en se terminant par le conteneur le plus externe. Les éléments dessinés à l’intérieur du conteneur le plus interne seront coupés par l’intersection de toutes les régions de découpage.

L’exemple suivant crée un objet Graphics et définit son indicateur de rendu de texte sur TextRenderingHintAntiAlias. Le code crée deux conteneurs, l’un imbriqué dans l’autre. L’indicateur de rendu du texte du conteneur externe est défini sur TextRenderingHintSingleBitPerPixel et l’indicateur de rendu de texte du conteneur interne est défini sur TextRenderingHintAntiAlias. Le code dessine trois chaînes : l’une du conteneur interne, l’autre du conteneur externe et l’autre de l’objet Graphics lui-même.

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);

L’illustration suivante montre les trois chaînes. Les chaînes dessinées à partir du conteneur interne et de l’objet Graphics sont lissées par anticrénelage. La chaîne dessinée à partir du conteneur externe n’est pas lissée par anticrénelage en raison du paramètre TextRenderingHintSingleBitPerPixel.

illustration d’un rectangle contenant la même chaîne qu’il y a ; seuls les caractères de la première et de la dernière ligne sont lisses