Partager via


Conteneurs graphiques intégrés

GDI+ fournit de 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 BeginContainer d'un objet Graphics. Vous pouvez appeler BeginContainer à plusieurs reprises pour constituer des conteneurs intégrés. Chaque appel à BeginContainer doit être conjugué à celui à EndContainer.

Transformations dans les conteneurs intégrés

L'exemple suivant crée un objet et un conteneur Graphics dans cet objet Graphics. La transformation universelle de l'objet Graphics est une translation de 100 unités dans la direction x et de 80 unités dans la direction y. La transformation universelle du conteneur est une rotation de trente degrés. Le code passe l'appel DrawRectangle(pen, -60, -30, 120, 60) deux fois. Le premier appel à DrawRectangle se trouve *dans le conteneur *; autrement dit, l'appel se trouve entre les appels à BeginContainer et à EndContainer. Le second appel à DrawRectangle se trouve après l'appel à EndContainer.

Dim graphics As Graphics = e.Graphics
Dim pen As New Pen(Color.Red)
Dim graphicsContainer As GraphicsContainer
graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3)

graphics.TranslateTransform(100, 80)

graphicsContainer = graphics.BeginContainer()
graphics.RotateTransform(30)
graphics.DrawRectangle(pen, - 60, - 30, 120, 60)
graphics.EndContainer(graphicsContainer)

graphics.DrawRectangle(pen, - 60, - 30, 120, 60)
[C#]
Graphics graphics = e.Graphics;
Pen pen = new Pen(Color.Red);
GraphicsContainer graphicsContainer;
graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3);

graphics.TranslateTransform(100, 80);

graphicsContainer = graphics.BeginContainer();
graphics.RotateTransform(30);
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 modifié d'abord par la transformation universelle du conteneur (rotation), puis par la transformation universelle de l'objet Graphics (translation). Le rectangle dessiné à l'extérieur du conteneur est transformé uniquement par la transformation universelle de l'objet Graphics (translation). L'illustration suivante montre les deux rectangles.

Détourage dans les conteneurs imbriqués

L'exemple suivant montre la façon dont les conteneurs imbriqués traitent les régions de détourage. Le code crée un objet et un conteneur Graphics dans cet objet Graphics. La région de détourage de l'objet Graphics est un rectangle et celle du conteneur une ellipse. Le code fait deux appels à la méthode DrawLine. Le premier appel à DrawLine est à l'intérieur du conteneur tandis que le second est à l'extérieur (après l'appel à EndContainer). Le premier trait est détouré par l'intersection des deux régions de détourage. Le second trait est détouré par la région de détourage rectangulaire de l'objet Graphics.

Dim graphics As Graphics = e.Graphics
Dim graphicsContainer As GraphicsContainer
Dim redPen As New Pen(Color.Red, 2)
Dim bluePen As New Pen(Color.Blue, 2)
Dim aquaBrush As New SolidBrush(Color.FromArgb(255, 180, 255, 255))
Dim greenBrush As New SolidBrush(Color.FromArgb(255, 150, 250, 130))
      
graphics.SetClip(New Rectangle(50, 65, 150, 120))
graphics.FillRectangle(aquaBrush, 50, 65, 150, 120)
      
graphicsContainer = graphics.BeginContainer()
' Create a path that consists of a single ellipse.
Dim path As New GraphicsPath()
path.AddEllipse(75, 50, 100, 150)
      
' Construct a region based on the path.
Dim [region] As New [Region](path)
graphics.FillRegion(greenBrush, [region])

graphics.SetClip([region], CombineMode.Replace)
graphics.DrawLine(redPen, 50, 0, 350, 300)
graphics.EndContainer(graphicsContainer)

graphics.DrawLine(bluePen, 70, 0, 370, 300)
[C#]
Graphics graphics = e.Graphics;
GraphicsContainer graphicsContainer;
Pen redPen = new Pen(Color.Red, 2);
Pen bluePen = new Pen(Color.Blue, 2);
SolidBrush aquaBrush = new SolidBrush(Color.FromArgb(255, 180, 255, 255));
SolidBrush greenBrush = new SolidBrush(Color.FromArgb(255, 150, 250, 130));

graphics.SetClip(new Rectangle(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 = new GraphicsPath();
path.AddEllipse(75, 50, 100, 150);

// Construct a region based on the path.
Region region = new Region(path);
graphics.FillRegion(greenBrush, region);

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

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

L'illustration suivante montre les deux traits détourés.

Comme dans les deux exemples précédents, les transformations et les régions de détourage se cumulent dans les conteneurs imbriqués. Si vous définissez les transformations universelles du conteneur et de l'objet Graphics, les deux transformations s'appliqueront aux éléments dessinés à l'intérieur du conteneur. La transformation du conteneur s'applique en premier, suivie de celle de l'objet Graphics. Si vous définissez les régions de détourage du conteneur et de l'objet Graphics, les éléments dessinés à l'intérieur du conteneur seront détourés par l'intersection des deux régions de détourage.

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

Les paramètres de qualité (SmoothingMode, TextRenderingHint et équivalents) des conteneurs imbriqués ne sont pas cumulatifs ; au contraire, les paramètres de qualité du conteneur remplacent temporairement les paramètres de qualité d'un objet Graphics. Lorsque vous créez un conteneur, ses paramètres de qualité prennent les valeurs par défaut. Supposez, par exemple, que vous disposiez d'un objet Graphics doté d'un mode lissage AntiAlias. Lorsque vous créez un conteneur, le mode lissage à l'intérieur du conteneur est celui par défaut. Vous avez toute latitude pour définir le mode lissage du conteneur et tous les éléments dessinés dans le conteneur le seront tracés d'après votre sélection. Les éléments dessinés après l'appel à EndContainer seront tracés en fonction du mode de lissage (AntiAlias) qui était en place avant l'appel à BeginContainer.

Plusieurs couches de conteneurs imbriqués

Dans un objet Graphics, vous n'êtes pas limité à un conteneur. Vous pouvez créer une séquence de conteneurs imbriqués les uns à la suite des autres et spécifier la transformation universelle, la région de détourage ainsi que les paramètres de qualité de chacun de ces conteneurs incorporés. Si vous appelez une méthode de dessin du conteneur le plus interne, les transformations seront appliquées dans l'ordre, à partir du conteneur le plus interne en passant par le conteneur le plus externe. Les éléments dessinés dans le conteneur le plus interne seront détourés par l'intersection de toutes les régions de détourage.

L'exemple suivant crée un objet Graphics et affecte à sa propriété de restitution de texte la valeur AntiAlias. Le code crée deux conteneurs imbriqués l'un dans l'autre. La propriété de restitution de texte du conteneur externe est défini sur SingleBitPerPixel tandis que celui du conteneur interne est défini sur AntiAlias. Le code dessine trois chaînes : la première dans le conteneur interne, la seconde dans le conteneur externe et la dernière dans l'objet Graphics lui-même.

Dim graphics As Graphics = e.Graphics
Dim innerContainer As GraphicsContainer
Dim outerContainer As GraphicsContainer
Dim brush As New SolidBrush(Color.Blue)
Dim fontFamily As New FontFamily("Times New Roman")
Dim font As New Font( _
   fontFamily, _
   36, _
   FontStyle.Regular, _
   GraphicsUnit.Pixel)

graphics.TextRenderingHint = TextRenderingHint.AntiAlias

outerContainer = graphics.BeginContainer()

   graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel

   innerContainer = graphics.BeginContainer()
      graphics.TextRenderingHint = TextRenderingHint.AntiAlias
      graphics.DrawString( _
         "Inner Container", _
         font, _
         brush, _
         New PointF(20, 10))
   graphics.EndContainer(innerContainer)
      
   graphics.DrawString("Outer Container", font, brush, New PointF(20, 50))
      
graphics.EndContainer(outerContainer)
      
graphics.DrawString("Graphics Object", font, brush, New PointF(20, 90))
[C#]
Graphics graphics = e.Graphics;
GraphicsContainer innerContainer;
GraphicsContainer outerContainer;
SolidBrush brush = new SolidBrush(Color.Blue);
FontFamily fontFamily = new FontFamily("Times New Roman");
Font font = new Font(fontFamily, 36, FontStyle.Regular, GraphicsUnit.Pixel);

graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

outerContainer = graphics.BeginContainer();

   graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;

   innerContainer = graphics.BeginContainer();
      graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
      graphics.DrawString(
         "Inner Container",
         font,
         brush,
         new PointF(20, 10));
   graphics.EndContainer(innerContainer);

   graphics.DrawString(
      "Outer Container",
      font,
      brush,
      new PointF(20, 50));

graphics.EndContainer(outerContainer);

graphics.DrawString(
   "Graphics
   Object",
   font,
   brush,
   new PointF(20, 90));

L'illustration suivante montre les trois chaînes. Les chaînes dessinées dans le conteneur interne et dans l'objet Graphics sont lissées par l'anticrénelage. La chaîne dessinée dans le conteneur externe n'est pas lissée par l'anticrénelage car la propriété TextRenderingHint est définie sur SingleBitPerPixel.