Usually, when you draw images, you have the entire visible canvas to work with. (You can draw images and shapes off the edge of the canvas if you want, but if a tree draws an image in the forest and no one is there to admire it, does it appear?) But there are times when you may want only a portion of what you draw to appear. Windows uses this method itself to save time. When you obscure a window with another one, and then expose the hidden window, the application has to redraw everything that appeared on the form or window. But if only a portion of that background window was hidden and then made visible again, why should the program go through the trouble of drawing everything again? It really only has to redraw the part that was hidden, the part that was in the hidden region.
A region specifies an area to be drawn on a surface. And regions aren't limited to boring rectangular shapes. You can design a region based on simple shapes, or you can combine existing regions into more complex regions. For instance, if you have two rectangular regions, you can overlap them and request a new combined region that contains (1) all of the original two regions; (2) the original regions but without the overlapped parts; or (3) just the overlapped parts. Figure 17-11 shows these combinations.
Figure 17-11. Different combinations of regions
During drawing operations, regions are sometimes referred to as "clipping regions" because any content drawn outside of the region is clipped off and thrown away. The following code draws an image, but masks out an ellipse in the middle by using (ta-da!) a graphics path to establish a custom clipping region.
' ----- Load the image. We'll show it smaller than normal. Dim splashImage As New Bitmap("c:\temp\SplashImage.jpg") Dim thePath As New Drawing2D.GraphicsPath() ' ----- Create an elliptical path that is the size of the ' output image. thePath.AddEllipse(20, 20, splashImage.Width \ 2, _ splashImage.Height \ 2) ' ----- Replace the original clipping region that covers ' the entire canvas with just the rectangular region. e.Graphics.SetClip(thePath, Drawing2D.CombineMode.Replace) ' ----- Draw the image, which will be clipped. e.Graphics.DrawImage(splashImage, 20, 20, _ splashImage.Width \ 2, splashImage.Height \ 2) ' ----- Clean up. thePath.Dispose()
The output for this code appears in Figure 17-12.
Figure 17-12. Ready to hang in your portrait gallery
Regions are also useful for "hit testing." If you draw a non-rectangular image on a form, and you want to know when the user clicks on the image, but not on any pixel just off of the image, you can use a region that is the exact shape of the image to test for mouse clicks.