Partager via


Utilisation de conteneurs graphiques imbriqués

Mise à jour : novembre 2007

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

Transformations dans les conteneurs imbriqués

L'exemple suivant crée un objet Graphics et un conteneur dans cet objet. 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 effectue l'appel DrawRectangle(pen, -60, -30, 120, 60) deux fois. Le premier appel à DrawRectangle est effectué à l'intérieur du conteneur, soit entre les appels à BeginContainer et EndContainer. Le second appel à DrawRectangle est effectué 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)

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.

Conteneurs imbriqués

Découpage dans les conteneurs imbriqués

L'exemple suivant montre la façon dont les conteneurs imbriqués traitent les régions de découpage. Le code crée un objet Graphics et un conteneur dans cet objet. La région de découpage 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 effectué à l'intérieur du conteneur et le deuxième appel à DrawLine à l'extérieur du conteneur (après l'appel à EndContainer). Le premier trait est découpé par l'intersection des deux régions de découpage. Le second trait est découpé par la région de découpage 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)

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écoupés.

Conteneur imbriqué

Comme dans les deux exemples précédents, les transformations et les régions de découpage 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écoupage du conteneur et de l'objet Graphics, les éléments dessinés à l'intérieur du conteneur seront dé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 é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é du mode de 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écoupage ainsi que les paramètres de qualité de chacun de ces conteneurs imbriqué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écoupés par l'intersection de toutes les régions de découpage.

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 a la valeur SingleBitPerPixel tandis que celui du conteneur interne a la valeur 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 = _
System.Drawing.Text.TextRenderingHint.AntiAlias

outerContainer = graphics.BeginContainer()

graphics.TextRenderingHint = _
    System.Drawing.Text.TextRenderingHint.SingleBitPerPixel

innerContainer = graphics.BeginContainer()
graphics.TextRenderingHint = _
    System.Drawing.Text.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))

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 = System.Drawing.Text.TextRenderingHint.AntiAlias;

outerContainer = graphics.BeginContainer();

graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;

innerContainer = graphics.BeginContainer();
graphics.TextRenderingHint = System.Drawing.Text.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 a la valeur SingleBitPerPixel.

Conteneurs imbriqués

Voir aussi

Concepts

Gestion de l'état d'un objet graphique

Référence

Graphics