Geschachtelte Grafikcontainer
Windows GDI+ stellt Container bereit, die Sie verwenden können, um einen Teil des Zustands in einem Grafikobjekt vorübergehend zu ersetzen oder zu erweitern. Sie erstellen einen Container, indem Sie die Graphics::BeginContainer-Methode eines Graphics-Objekts aufrufen. Sie können Graphics::BeginContainer wiederholt aufrufen, um geschachtelte Container zu bilden.
Transformationen in geschachtelten Containern
Im folgenden Beispiel werden ein Graphics-Objekt und ein Container innerhalb dieses Graphics-Objekts erstellt. Die Welttransformation des Graphics-Objekts ist eine Übersetzung von 100 Einheiten in x-Richtung und 80 Einheiten in y-Richtung. Die globale Transformation des Containers ist eine Drehung um 30 Grad. Der Code führt den Aufruf aus.
DrawRectangle(&pen, -60, -30, 120, 60)
Zweimal. Der erste Aufruf von Graphics::D rawRectangle befindet sichim Container. Das heißt, der Aufruf befindet sich zwischen den Aufrufen von Graphics::BeginContainer und Graphics::EndContainer. Der zweite Aufruf von Graphics::D rawRectangle erfolgt nach dem Aufruf von 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);
Im vorherigen Code wird das rechteck, das aus dem Container gezeichnet wurde, zuerst durch die Welttransformation des Containers (Drehung) und dann durch die Welttransformation des Graphics-Objekts (Übersetzung) transformiert. Das rechteck, das von außerhalb des Containers gezeichnet wird, wird nur durch die Welttransformation des Graphics-Objekts (Übersetzung) transformiert. Die folgende Abbildung zeigt die beiden Rechtecke.
Clipping in geschachtelten Containern
Im folgenden Beispiel wird veranschaulicht, wie geschachtelte Container Clippingbereiche behandeln. Der Code erstellt ein Graphics-Objekt und einen Container innerhalb dieses Graphics-Objekts . Der Clippingbereich des Graphics-Objekts ist ein Rechteck, und der Beschneidungsbereich des Containers ist eine Ellipse. Der Code führt zwei Aufrufe an die Graphics::D rawLine-Methode aus. Der erste Aufruf von Graphics::D rawLine befindet sich innerhalb des Containers, und der zweite Aufruf von Graphics::D rawLine befindet sich außerhalb des Containers (nach dem Aufruf von Graphics::EndContainer). Die erste Linie wird am Schnittpunkt der beiden Clippingbereiche beschnitten. Die zweite Zeile wird nur durch den rechteckigen Beschneidungsbereich des Graphics-Objekts beschnitten .
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);
Die folgende Abbildung zeigt die beiden abgeschnittenen Linien.
Wie in den beiden vorherigen Beispielen zu sehen, sind Transformationen und Clippingbereiche in geschachtelten Containern kumulativ. Wenn Sie die Welttransformationen des Containers und des Graphics-Objekts festlegen, gelten beide Transformationen für Elemente, die aus dem Container gezeichnet werden. Die Transformation des Containers wird zuerst angewendet, und die Transformation des Graphics-Objekts wird als zweites angewendet. Wenn Sie die Beschneidungsbereiche des Containers und des Grafikobjekts festlegen, werden elemente, die aus dem Container gezeichnet wurden, durch die Schnittmenge der beiden Beschneidungsbereiche beschnitten.
Qualitätseinstellungen in geschachtelten Containern
Qualitätseinstellungen ( SmoothingMode, TextRenderingHint usw.) in geschachtelten Containern sind nicht kumulativ; Stattdessen ersetzen die Qualitätseinstellungen des Containers vorübergehend die Qualitätseinstellungen eines Grafikobjekts . Wenn Sie einen neuen Container erstellen, sind die Qualitätseinstellungen für diesen Container auf Standardwerte festgelegt. Angenommen, Sie verfügen über ein Graphics-Objekt mit dem Glättungsmodus SmoothingModeAntiAlias. Wenn Sie einen Container erstellen, ist der Glättungsmodus innerhalb des Containers der Standardglättungsmodus. Sie können den Glättungsmodus des Containers festlegen, sodass für alle Elemente, die im Rahmen des Containers gezeichnet werden, der von Ihnen festgelegten Modus verwendet wird. Elemente, die nach dem Aufruf von Graphics::EndContainer gezeichnet wurden, werden entsprechend dem Glättungsmodus (SmoothingModeAntiAlias) gezeichnet, der vor dem Aufruf von Graphics::BeginContainer vorhanden war.
Mehrere Ebenen geschachtelter Container
Sie sind nicht auf einen Container in einem Graphics-Objekt beschränkt. Sie können eine Reihe von Containern erstellen, die im jeweils vorherigen Container geschachtelt sind, und die globale Transformation, den Clippingbereich und die Qualitätseinstellungen jedes dieser geschachtelten Container angeben. Wenn Sie eine Zeichenmethode aus dem innersten Container aufrufen, werden die Transformationen der Reihe nach angewendet – vom innersten bis zum äußersten Container. Elemente, die im Rahmen des innersten Containers gezeichnet werden, werden am Schnittpunkt aller Clippingbereiche beschnitten.
Im folgenden Beispiel wird ein Graphics-Objekt erstellt und dessen Textrenderinghinweis auf TextRenderingHintAntiAlias festgelegt. Durch den Code werden zwei ineinander geschachtelte Container erstellt. Der Textrenderinghinweis des äußeren Containers ist auf TextRenderingHintSingleBitPerPixel festgelegt, und der Textrenderinghinweis des inneren Containers ist auf TextRenderingHintAntiAlias festgelegt. Der Code zeichnet drei Zeichenfolgen: eine aus dem inneren Container, eine aus dem äußeren Container und eine aus dem Graphics-Objekt selbst.
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);
Die folgende Abbildung zeigt die drei Zeichenfolgen. Die aus dem inneren Container und dem Graphics-Objekt gezeichneten Zeichenfolgen werden durch Antialiasing geglättet. Die aus dem äußeren Container gezeichnete Zeichenfolge wird aufgrund der Einstellung TextRenderingHintSingleBitPerPixel nicht durch Antialiasing geglättet.