巢狀圖形容器
Windows GDI+ 提供容器,可讓您用來暫時取代或增強 Graphics 物件中狀態的一部分。 您可以呼叫Graphics物件的Graphics::BeginContainer方法來建立容器。 您可以重複呼叫 Graphics::BeginContainer 來形成巢狀容器。
巢狀容器中的轉換
下列範例會在該Graphics物件內建立Graphics物件和容器。 Graphics物件的世界轉換是 x 方向的轉譯 100 單位,而 Y 方向為 80 單位。 容器的世界轉換是 30 度旋轉。 程式碼進行呼叫
DrawRectangle(&pen, -60, -30, 120, 60)
兩次。 第一次呼叫 Graphics::D rawRectangle 位於 容器內;也就是說,呼叫 Graphics::BeginContainer 和 Graphics::EndContainer之間的呼叫。 第二次呼叫 Graphics::D rawRectangle 是在 呼叫 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);
在上述程式碼中,從容器內繪製的矩形會先由容器 (旋轉) 的世界中轉換,然後由 Graphics 物件的世界轉換 (轉譯) 來轉換。 從容器外部繪製的矩形只會由 Graphics 物件的世界轉換 (轉譯) 來轉換。 下圖顯示兩個矩形。
巢狀容器中的裁剪
下列範例說明巢狀容器如何處理裁剪區域。 程式碼會在該Graphics物件內建立Graphics物件和容器。 Graphics物件的裁剪區域是矩形,而容器的裁剪區域則是橢圓形。 程式碼會呼叫 Graphics::D rawLine 方法。 第一次呼叫 Graphics::D rawLine 位於容器內,而 呼叫 Graphics::D rawLine 是在呼叫 Graphics::EndContainer) 之後的容器外部 (。 第一行是由兩個裁剪區域的交集所裁剪。 第二行只會由 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);
下圖顯示兩條裁剪的行。
如上述兩個範例所示,轉換和裁剪區域會累積在巢狀容器中。 如果您設定容器和 Graphics 物件的世界轉換,這兩個轉換都會套用至從容器內繪製的專案。 容器的轉換會先套用,而 Graphics 物件的轉換則會套用第二個。 如果您設定容器和 Graphics 物件的裁剪區域,則從容器內繪製的專案將會由兩個裁剪區域的交集裁剪。
巢狀容器中的品質設定
在巢狀容器中 ( SmoothingMode、 TextRenderingHint等) 品質設定不會累積;相反地,容器的品質設定會暫時取代 Graphics 物件的品質設定。 當您建立新的容器時,該容器的品質設定會設定為預設值。 例如,假設您有SmoothingModeAntiAlias平滑模式的Graphics物件。 當您建立容器時,容器內的平滑模式是預設的平滑模式。 您可以自由設定容器的平滑模式,而從容器內繪製的任何專案都會根據您設定的模式來繪製。 在 呼叫 Graphics::EndContainer 之後繪製的專案,將會根據 SmoothingModeAntiAlias (SmoothingModeAntiAlias) 繪製,且在 呼叫 Graphics::BeginContainer之前已就緒。
數層巢狀容器
您不限於 Graphics 物件中的一個容器。 您可以建立一連串的容器、上述每個巢狀容器,以及指定這些巢狀容器的世界轉換、裁剪區域和品質設定。 如果您從最內層容器內呼叫繪圖方法,則會依序套用轉換,從最內層容器開始,並以最外層容器結束。 從最內層容器內繪製的專案將會由所有裁剪區域的交集裁剪。
下列範例會建立 Graphics 物件,並將其文字轉譯提示設定為 TextRenderingHintAntiAlias。 程式碼會建立兩個容器,一個巢狀于另一個容器內。 外部容器的文字轉譯提示會設定為 TextRenderingHintSingleBitPerPixel,而內部容器的文字轉譯提示會設定為 TextRenderingHintAntiAlias。 程式碼會繪製三個字串:一個來自內部容器、一個來自外部容器,另一個來自 Graphics 物件本身。
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);
下圖顯示三個字串。 從內部容器和 Graphics 物件繪製的字串會透過反鋸齒來平滑化。 因為 TextRenderingHintSingleBitPerPixel 設定,所以從外部容器繪製的字串不會平滑化。