巢狀圖形容器
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 對象的質量設定。 當您建立新的容器時,該容器的品質設定會設定為預設值。 例如,假設您有 Graphics 物件,其平滑模式為 smoothingModeAntiAlias 。 當您建立容器時,容器內的平滑模式是預設的平滑模式。 您可以自由設定容器的平滑模式,而從容器內繪製的任何專案都會根據您設定的模式繪製。 在呼叫 Graphics::EndContainer 之後繪製的專案會根據平滑模式(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 設定而平滑化。