Condividi tramite


Contenitori grafici 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 metodoGraphics::BeginContainerdi un oggetto Graphics. È possibile chiamare Graphics::BeginContainer ripetutamente per formare contenitori annidati.

Trasformazioni in contenitori annidati

Nell'esempio seguente viene creato un oggettoGraphicse un contenitore all'interno di tale oggetto Graphics. La trasformazione globale dell'oggetto grafica è 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 viene all'interno del contenitore; ovvero, la chiamata è 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.

schermata di una finestra con due rettangoli rossi centrati sullo stesso punto, ma con rotazioni diverse

 

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 del 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, &region);

   graphics.SetClip(&region);
   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.

illustrazione di un'ellisse all'interno di un rettangolo, con una linea ritagliata dall'ellisse e l'altra dal rettangolo

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 l'oggetto Graphics, entrambe le trasformazioni verranno applicate agli elementi disegnati dall'interno del contenitore. La trasformazione del contenitore verrà applicata per prima e verrà applicata la trasformazione dell'oggetto grafica. Se si impostano le aree di ritaglio del contenitore e l'oggetto Graphics, gli elementi disegnati dall'interno del contenitore verranno ritagliati dall'intersezione delle due aree di ritaglio.

Impostazioni di qualità nei contenitori annidati

Impostazioni di qualità ( SmoothingMode, TextRenderingHinte simili) nei contenitori annidati non sono cumulativi; piuttosto, 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à di 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 disegnati dopo la chiamata a Graphics::EndContainer verranno disegnati in base alla modalità di smoothing (SmoothingModeAntiAlias) che era attiva prima della chiamata a Graphics::BeginContainer.

Diversi livelli di contenitori annidati

Non si è limitati a un contenitore in un oggettoGraphics. È possibile creare una sequenza di contenitori, ognuno annidato nel 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 oggettoGraphicse 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 TextRenderingHintSingleBitPerPixele 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 oggetto 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 sono smussate dall'antialiasing. La stringa disegnata dal contenitore esterno non viene smussata dall'antialiasing a causa dell'impostazione TextRenderingHintSingleBitPerPixel.

illustrazione di un rettangolo contenente la stessa stringa; solo i caratteri nelle prime e ultime righe sono uniformi