Contenitori di oggetti Graphics annidati
Windows GDI+ fornisce contenitori che è possibile usare per sostituire o aumentare temporaneamente parte dello stato in un oggetto Graphics . Per creare un contenitore, chiamare il metodo Graphics::BeginContainer di un oggetto Graphics . È possibile chiamare grafica::BeginContainer ripetutamente per formare contenitori annidati.
Trasformazioni nei contenitori annidati
Nell'esempio seguente vengono creati un oggetto Graphics e un contenitore all'interno dell'oggetto Graphics . La trasformazione globale dell'oggetto Graphics è una traslazione di 100 unità nella direzione x e 80 unità nella direzione y. La trasformazione globale del contenitore è una rotazione a 30 gradi. Il codice effettua la chiamata
DrawRectangle(&pen, -60, -30, 120, 60)
Due volte. La prima chiamata a Graphics::D rawRectangle si trova all'interno del contenitore; ovvero tra le chiamate a Graphics::BeginContainer e Graphics::EndContainer. La seconda chiamata a Graphics::D rawRectangle è dopo la chiamata 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);
Nel codice precedente, il rettangolo disegnato dall'interno del contenitore viene trasformato prima dalla trasformazione globale del contenitore (rotazione) e quindi dalla trasformazione globale dell'oggetto Graphics (traslazione). Il rettangolo disegnato dall'esterno del contenitore viene trasformato solo dalla trasformazione globale dell'oggetto Graphics (traslazione). La figura seguente mostra i due rettangoli.
Ritaglio in contenitori annidati
Nell'esempio seguente viene illustrato come i contenitori annidati gestiscono le aree di ritaglio. Il codice crea un oggetto Graphics e un contenitore all'interno di tale oggetto Graphics . L'area di ritaglio dell'oggetto Graphics è un rettangolo e l'area di ritaglio del contenitore è un'ellisse. Il codice effettua due chiamate al metodo Graphics::D rawLine . La prima chiamata a Graphics::D rawLine si trova all'interno del contenitore e la seconda chiamata a Graphics::D rawLine si trova all'esterno del contenitore (dopo la chiamata a Graphics::EndContainer). La prima riga viene ritagliata dall'intersezione delle due aree di ritaglio. La seconda riga viene ritagliata solo dall'area di ritaglio rettangolare dell'oggetto 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, ®ion);
graphics.SetClip(®ion);
graphics.DrawLine(&redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);
graphics.DrawLine(&bluePen, 70, 0, 370, 300);
La figura seguente mostra le due linee ritagliate.
Come mostrano i due esempi precedenti, le trasformazioni e le aree di ritaglio sono cumulative in contenitori annidati. Se si impostano le trasformazioni del contenitore e dell'oggetto Graphics , entrambe le trasformazioni verranno applicate agli elementi disegnati dall'interno del contenitore. La trasformazione del contenitore verrà applicata per prima e la trasformazione dell'oggetto Graphics verrà applicata seconda. Se si impostano le aree di ritaglio del contenitore e dell'oggetto Graphics , gli elementi disegnati dall'interno del contenitore verranno ritagliati dall'intersezione delle due aree di ritaglio.
Impostazioni di qualità nei contenitori annidati
Le impostazioni di qualità ( SmoothingMode, TextRenderingHint e like) nei contenitori annidati non sono cumulative; le impostazioni di qualità del contenitore sostituiscono temporaneamente le impostazioni di qualità di un oggetto Graphics . Quando si crea un nuovo contenitore, le impostazioni di qualità per tale contenitore vengono impostate sui valori predefiniti. Si supponga, ad esempio, di avere un oggetto Graphics con una modalità smoothing di SmoothingModeAntiAlias. Quando si crea un contenitore, la modalità di smoothing all'interno del contenitore è la modalità di smoothing predefinita. È possibile impostare la modalità di smoothing del contenitore e tutti gli elementi disegnati dall'interno del contenitore verranno disegnati in base alla modalità impostata. Gli elementi creati dopo la chiamata a Graphics::EndContainer verranno disegnati in base alla modalità smoothing (SmoothingModeAntiAlias) che era stata eseguita prima della chiamata a Graphics::BeginContainer.
Diversi livelli di contenitori annidati
Non si è limitati a un contenitore in un oggetto Graphics . È possibile creare una sequenza di contenitori, ognuno annidato nell'oggetto precedente ed è possibile specificare la trasformazione globale, l'area di ritaglio e le impostazioni di qualità di ognuno di questi contenitori annidati. Se si chiama un metodo di disegno dall'interno del contenitore più interno, le trasformazioni verranno applicate in ordine, a partire dal contenitore più interno e terminando con il contenitore più esterno. Gli elementi disegnati dall'interno del contenitore più interno verranno ritagliati dall'intersezione di tutte le aree di ritaglio.
Nell'esempio seguente viene creato un oggetto Graphics e viene impostato il relativo hint per il rendering del testo su TextRenderingHintAntiAlias. Il codice crea due contenitori, uno annidato all'interno dell'altro. L'hint per il rendering del testo del contenitore esterno è impostato su TextRenderingHintSingleBitPerPixel e l'hint per il rendering del testo del contenitore interno è impostato su TextRenderingHintAntiAlias. Il codice disegna tre stringhe: una dal contenitore interno, una dal contenitore esterno e una dall'oggetto Graphics stesso.
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);
La figura seguente mostra le tre stringhe. Le stringhe disegnate dal contenitore interno e l'oggetto Graphics vengono smussate dall'antialiasing. La stringa disegnata dal contenitore esterno non viene smussata dall'antialiasing a causa dell'impostazione TextRenderingHintSingleBitPerPixel.