Sdílet prostřednictvím


Vnořené grafické kontejnery

Windows GDI+ poskytuje kontejnery, které můžete použít k dočasnému nahrazení nebo rozšíření části stavu v objektu Graphics. Kontejner vytvoříte voláním Graphics::BeginContainer metoda Graphics objektu. Můžete volat Graphics::BeginContainer opakovaně vytvářet vnořené kontejnery.

Transformace v vnořených kontejnerech

Následující příklad vytvoří objekt Graphics a kontejner v rámci tohoto objektu Graphics. Svět transformace objektu Graphics je překlad 100 jednotek ve směru x a 80 jednotek ve směru y. Světová transformace kontejneru je 30stupňová rotace. Kód provede volání.

DrawRectangle(&pen, -60, -30, 120, 60)

dvakrát. První volání Graphics::D rawRectangle je uvnitř kontejneru; to znamená, že volání je mezi voláními Graphics::BeginContainer a Graphics::EndContainer. Druhé volání Graphics::D rawRectangle je po volání 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);

V předchozím kódu se obdélník nakreslený uvnitř kontejneru transformuje jako první světovou transformací kontejneru (otočení) a pak světovou transformací objektu Graphics objektu (překladu). Obdélník nakreslený z vnějšího kontejneru je transformován pouze světovou transformací objektu Graphics objektu (překlad). Následující obrázek znázorňuje dva obdélníky.

snímek obrazovky okna se dvěma červenými obdélníky uprostřed stejného bodu, ale s různými otočeními

 

Výřez v vnořených kontejnerech

Následující příklad ukazuje, jak vnořené kontejnery zpracovávají oblasti výřezu. Kód vytvoří objekt Graphics a kontejner v rámci daného objektu Graphics. Oblast výřezu objektu Graphics je obdélník a oblast výřezu kontejneru je tři tečky. Kód provádí dvě volání metody Graphics::D rawLine. První volání Graphics::D rawLine je uvnitř kontejneru a druhé volání Graphics::D rawLine je mimo kontejner (po volání Graphics::EndContainer). První řádek se vystřihuje průsečíkem dvou oblastí výřezu. Druhý řádek je oříznut pouze obdélníkovou oblastí výřezu Graphics objektu.

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);

Následující obrázek znázorňuje dvě oříznuté čáry.

ilustraci tří teček uvnitř obdélníku s oříznutou o jednu čáru třemi tečkami a druhou obdélníkovou

Jak ukazují dva předchozí příklady, transformace a oblasti výřezu jsou kumulativní v vnořených kontejnerech. Pokud nastavíte světové transformace kontejneru a objekt Graphics objekt, použijí se obě transformace u položek nakreslených z kontejneru. Nejprve se použije transformace kontejneru a použije se druhá transformace objektu Graphics. Pokud nastavíte oblasti výřezu kontejneru a objekt Graphics objektu, položky nakreslené z kontejneru se vystřihnou průnikem obou oblastí výřezu.

Nastavení kvality v vnořených kontejnerech

Nastavení kvality ( SmoothingMode, TextRenderingHinta podobně) v vnořených kontejnerech nejsou kumulativní; nastavení kvality kontejneru dočasně nahradí nastavení kvality objektu Graphics. Při vytváření nového kontejneru se nastavení kvality pro tento kontejner nastaví na výchozí hodnoty. Předpokládejme například, že máte objekt Graphics s režimem vyhlazování SmoothingModeAntiAlias. Při vytváření kontejneru je režim vyhlazování uvnitř kontejneru výchozím režimem vyhlazování. Můžete nastavit režim vyhlazování kontejneru a všechny položky nakreslené z kontejneru budou nakresleny podle vámi nastaveného režimu. Položky vykreslené po volání Graphics::EndContainer budou vykresleny podle režimu vyhlazování (SmoothingModeAntiAlias), který byl zaveden před voláním Graphics::BeginContainer.

Několik vrstev vnořených kontejnerů

Nejste omezeni na jeden kontejner v objektu Graphics. Můžete vytvořit posloupnost kontejnerů, z nichž každý je vnořený v předchozím kroku, a můžete určit světovou transformaci, výřez oblasti a nastavení kvality každého z těchto vnořených kontejnerů. Pokud zavoláte metodu kreslení z vnitřního kontejneru, transformace se použijí v pořadí, počínaje nejvnitřnějším kontejnerem a končícím vnějším kontejnerem. Položky nakreslené z vnitřního kontejneru se vystřihnou průnikem všech oblastí výřezu.

Následující příklad vytvoří objekt Graphics a nastaví jeho nápovědu pro vykreslování textu na TextRenderingHintAntiAlias. Kód vytvoří dva kontejnery, jeden vnořený uvnitř druhého. Nápověda pro vykreslování textu vnějšího kontejneru je nastavena na TextRenderingHintSingLeBitPerPixela vykreslení textu nápovědy vnitřního kontejneru je nastaveno na TextRenderingHintAntiAlias. Kód nakreslí tři řetězce: jeden z vnitřního kontejneru, jeden z vnějšího kontejneru a druhý z objektu Graphics samotný objekt.

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);

Následující obrázek znázorňuje tři řetězce. Řetězce nakreslené z vnitřního kontejneru a objekt Graphics jsou vyhlazovány antialiasingem. Řetězec nakreslený z vnějšího kontejneru není vyhlazován antialiasingem kvůli nastavení TextRenderingHintSingLeBitPerPixel.

obrázek obdélníku, který tam obsahuje stejný řetězec; pouze znaky v prvních a posledních řádcích jsou hladké