Kontainer Grafis
Status grafik — mengklip wilayah, transformasi, dan pengaturan kualitas — disimpan dalam objek Grafis . Windows GDI+ memungkinkan Anda untuk mengganti sementara atau menambah bagian status dalam objek Grafis dengan menggunakan kontainer. Anda memulai kontainer dengan memanggil metode Graphics::BeginContainer dari objek Grafis , dan Anda mengakhiri kontainer dengan memanggil metode Graphics::EndContainer . Di antara Grafis::BeginContainer dan Graphics::EndContainer, setiap perubahan status yang Anda buat pada objek Grafis milik kontainer dan jangan timpa status objek Grafis yang ada.
Contoh berikut membuat kontainer dalam objek Grafis . Transformasi dunia objek Grafis adalah terjemahan 200 unit ke kanan, dan transformasi dunia kontainer adalah terjemahan 100 unit ke bawah.
myGraphics.TranslateTransform(200.0f, 0.0f);
myGraphicsContainer = myGraphics.BeginContainer();
myGraphics.TranslateTransform(0.0f, 100.0f);
myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50);
myGraphics.EndContainer(myGraphicsContainer);
myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50);
Perhatikan bahwa dalam contoh sebelumnya, pernyataan myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50)
yang dibuat di antara panggilan ke Graphics::BeginContainer dan Graphics::EndContainer menghasilkan persegi panjang yang berbeda dari pernyataan yang sama yang dibuat setelah panggilan ke Graphics::EndContainer. Hanya terjemahan horizontal yang berlaku untuk panggilan DrawRectangle yang dilakukan di luar kontainer. Kedua transformasi — terjemahan horizontal 200 unit dan terjemahan vertikal 100 unit — berlaku untuk panggilan Graphics::D rawRectangle yang dilakukan di dalam kontainer. Ilustrasi berikut menunjukkan dua persegi panjang.
Kontainer dapat disarangkan dalam kontainer. Contoh berikut membuat kontainer dalam objek Grafis dan kontainer lain dalam kontainer pertama. Transformasi dunia objek Grafis adalah terjemahan 100 unit ke arah x dan 80 unit ke arah y. Transformasi dunia dari kontainer pertama adalah rotasi 30 derajat. Transformasi dunia kontainer kedua adalah penskalaan dengan faktor 2 ke arah x. Panggilan ke metode Graphics::D rawEllipse dilakukan di dalam kontainer kedua.
myGraphics.TranslateTransform(100.0f, 80.0f, MatrixOrderAppend);
container1 = myGraphics.BeginContainer();
myGraphics.RotateTransform(30.0f, MatrixOrderAppend);
container2 = myGraphics.BeginContainer();
myGraphics.ScaleTransform(2.0f, 1.0f);
myGraphics.DrawEllipse(&myPen, -30, -20, 60, 40);
myGraphics.EndContainer(container2);
myGraphics.EndContainer(container1);
Ilustrasi berikut menunjukkan elips.
Perhatikan bahwa ketiga transformasi berlaku untuk panggilan Graphics::D rawEllipse yang dilakukan dalam kontainer kedua (terdalam). Perhatikan juga urutan transformasi: skala pertama, lalu putar, lalu terjemahkan. Transformasi terdalam diterapkan terlebih dahulu, dan transformasi terluar diterapkan terakhir.
Properti objek Grafis apa pun dapat diatur di dalam kontainer (di antara panggilan ke Grafis::BeginContainer dan Graphics::EndContainer). Misalnya, wilayah kliping dapat diatur di dalam kontainer. Setiap gambar yang dilakukan di dalam kontainer akan dibatasi untuk wilayah kliping kontainer tersebut dan juga akan dibatasi untuk wilayah kliping kontainer luar apa pun dan wilayah kliping objek Grafis itu sendiri.
Properti yang dibahas sejauh ini - transformasi dunia dan wilayah kliping - dikombinasikan oleh kontainer berlapis. Properti lain untuk sementara digantikan oleh kontainer berlapis. Misalnya, jika Anda mengatur mode penghalusan ke SmoothingModeAntiAlias dalam kontainer, metode menggambar apa pun yang disebut di dalam kontainer tersebut akan menggunakan mode penghalusan antialias, tetapi metode menggambar yang dipanggil setelah Graphics::EndContainer akan menggunakan mode smoothing yang ada sebelum panggilan ke Graphics::BeginContainer.
Untuk contoh lain menggabungkan transformasi dunia objek Grafis dan kontainer, misalkan Anda ingin menggambar mata dan menempatkannya di berbagai lokasi pada urutan wajah. Contoh berikut menggambar mata yang berpusat pada asal sistem koordinat.
void DrawEye(Graphics* pGraphics)
{
GraphicsContainer eyeContainer;
eyeContainer = pGraphics->BeginContainer();
Pen myBlackPen(Color(255, 0, 0, 0));
SolidBrush myGreenBrush(Color(255, 0, 128, 0));
SolidBrush myBlackBrush(Color(255, 0, 0, 0));
GraphicsPath myTopPath;
myTopPath.AddEllipse(-30, -50, 60, 60);
GraphicsPath myBottomPath;
myBottomPath.AddEllipse(-30, -10, 60, 60);
Region myTopRegion(&myTopPath);
Region myBottomRegion(&myBottomPath);
// Draw the outline of the eye.
// The outline of the eye consists of two ellipses.
// The top ellipse is clipped by the bottom ellipse, and
// the bottom ellipse is clipped by the top ellipse.
pGraphics->SetClip(&myTopRegion);
pGraphics->DrawPath(&myBlackPen, &myBottomPath);
pGraphics->SetClip(&myBottomRegion);
pGraphics->DrawPath(&myBlackPen, &myTopPath);
// Fill the iris.
// The iris is clipped by the bottom ellipse.
pGraphics->FillEllipse(&myGreenBrush, -10, -15, 20, 22);
// Fill the pupil.
pGraphics->FillEllipse(&myBlackBrush, -3, -7, 6, 9);
pGraphics->EndContainer(eyeContainer);
}
Ilustrasi berikut menunjukkan mata dan sumbu koordinat.
Fungsi DrawEye, yang ditentukan dalam contoh sebelumnya menerima alamat objek Grafis dan segera membuat kontainer dalam objek Grafis tersebut. Kontainer ini mengisolasi kode apa pun yang memanggil fungsi DrawEye dari pengaturan properti yang dibuat selama eksekusi fungsi DrawEye. Misalnya, kode dalam fungsi DrawEye mengatur wilayah kliping objek Grafis , tetapi ketika DrawEye mengembalikan kontrol ke rutinitas panggilan, wilayah kliping akan seperti sebelum panggilan ke DrawEye.
Contoh berikut menggambar tiga elipsis (wajah), masing-masing dengan mata di dalamnya.
// Draw an ellipse with center at (100, 100).
myGraphics.TranslateTransform(100.0f, 100.0f);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);
// Draw the eye at the center of the ellipse.
DrawEye(&myGraphics);
// Draw an ellipse with center at 200, 100.
myGraphics.TranslateTransform(100.0f, 0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);
// Rotate the eye 40 degrees, and draw it 30 units above
// the center of the ellipse.
myGraphicsContainer = myGraphics.BeginContainer();
myGraphics.RotateTransform(-40.0f);
myGraphics.TranslateTransform(0.0f, -30.0f, MatrixOrderAppend);
DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);
// Draw a ellipse with center at (300.0f, 100.0f).
myGraphics.TranslateTransform(100.0f, 0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);
// Stretch and rotate the eye, and draw it at the
// center of the ellipse.
myGraphicsContainer = myGraphics.BeginContainer();
myGraphics.ScaleTransform(2.0f, 1.5f);
myGraphics.RotateTransform(45.0f, MatrixOrderAppend);
DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);
Ilustrasi berikut menunjukkan tiga elipsis.
Dalam contoh sebelumnya, semua elipsis digambar dengan panggilan DrawEllipse(&myBlackPen, -40, -60, 80, 120)
, yang menggambar elips yang berpusat pada asal sistem koordinat. Elipsis dipindahkan menjauh dari sudut kiri atas area klien dengan mengatur transformasi dunia objek Grafis . Pernyataan tersebut menyebabkan elips pertama berpusat pada (100, 100). Pernyataan tersebut menyebabkan pusat elips kedua menjadi 100 unit di sebelah kanan tengah elips pertama. Demikian juga, pusat elips ketiga adalah 100 unit di sebelah kanan tengah elips kedua.
Kontainer dalam contoh sebelumnya digunakan untuk mengubah mata relatif terhadap pusat elips tertentu. Mata pertama digambar di tengah elips tanpa transformasi, sehingga panggilan DrawEye tidak berada di dalam kontainer. Mata kedua diputar 40 derajat dan ditarik 30 unit di atas bagian tengah elips, sehingga fungsi DrawEye dan metode yang mengatur transformasi disebut di dalam kontainer. Mata ketiga direntangkan dan diputar dan ditarik di tengah elips. Seperti mata kedua, fungsi DrawEye dan metode yang mengatur transformasi dipanggil di dalam kontainer.