Regions


Whereas paths define a set of figures, with both a frame and an area, a region defines only an area. A region can be used for filling or, most importantly, clipping. A region is modeled in .NET with the Region class:

namespace System.Drawing {    sealed class Region : IDisposable, ... {      // Constructors      public Region( ... );      // Methods      public void Complement( ... );      public void Exclude( ... );      public static Region FromHrgn(IntPtr hrgn);      public RectangleF GetBounds(Graphics g);      public IntPtr GetHrgn(Graphics g);      public RegionData GetRegionData();      public RectangleF[] GetRegionScans(Matrix matrix);      public void Intersect( ... );      public bool IsEmpty(Graphics g);      public bool IsInfinite(Graphics g);      public bool IsVisible( ... );      public void MakeEmpty();      public void MakeInfinite();      public void ReleaseHRgn(IntPtr regionHandle); // New      public void Transform( ... );      public void Translate( ... );      public void Union( ... );      public void Xor( ... );    } }


Constructing and Filling a Region

Because the underlying Win32 implementation also has a construct that represents a region (managed using the Win32 HRGN data type), the Region class can be translated back and forth for interoperability reasons. In addition to constructing a region from an HRGN, you can construct regions from Rectangle objects or, more generally, from GraphicsPath objects:

using( GraphicsPath path = new GraphicsPath() ) {   path.AddEllipse(rect);   path.Flatten(new Matrix(), 13f);   path.AddString("Flattened Ellipse", ...); using( Region region = new Region(path) ) {   g.FillRegion(Brushes.Red, region);   } }


You might be curious about what might drive you to fill a region, especially given that paths can be drawn or filled but regions can only be filled. The answer is that you probably won't use regions to draw. You'll probably use regions to decide what not to draw.

Clipping to a Region

Every Graphics object has a region to which all drawing is clipped; any drawing outside the clip region is ignored. By default, the clip region is an infinite region, and this means that it has no bounds and nothing inside the region being drawn will be thrown out. Windows itself clips outside the region that isn't part of the invalid region that triggered the Paint event, but that's a separate region from the region exposed by the Graphics object. You can set the clip region on the Graphics object by setting the Clip property (as shown in Figure 7.11):

Figure 7.11. Rectangle Clipped to an Ellipse Region


using( GraphicsPath path = new GraphicsPath() ) {    path.AddEllipse(this.ClientRectangle);    using( Region region = new Region(path) ) {      // Frame clipping region      g.DrawPath(Pens.Red, path);      // Don't draw outside the ellipse region      g.Clip = region;      // Draw a rectangle      Rectangle rect = this.ClientRectangle;      rect.Offset(10, 10);      rect.Width -= 20;      rect.Height -= 20;      g.FillRectangle(Brushes.Black, rect);      g.DrawString("Rectangle clipped to Ellipse", ...);    } }


If you'd rather call a method than set a property when setting the clip region, you can use the SetClip method. It has overloads that take rectangles and paths and create the underlying clip region itself from those. If you'd like to go back to no clipping, you can use the ResetClip method. There are also several clip-related methods on the Region class that deal with intersecting and combining clip regions. All these operate on the underlying methods of the Region class itself, which supports various combination techniques.

Region Combination Operations

Regions support several combination operations for creating more complicated regions from several combined simpler regions. These operations are complement, exclude, intersect, union, and xor, as shown in Figure 7.12.

Figure 7.12. Region Combination Operations


Each region combination method takes a path, a region, or a rectangle and combines it with the existing region. By default, a Region with no constructor argument is infinite, but you can make it empty by calling MakeEmpty. Creating a Region with a constructor argument is like creating it as empty and then using the Union method to add a new shape to the region. The following are equivalent:

// Intersect the easy way using( Region region = new Region(path1) ) {   region.Intersect(path2);   g.FillRegion(Brushes.Red, region); } // Intersect the hard way using( Region region = new Region() ) {   // Defaults to region.IsInfinite(g) == true   if( !region.IsEmpty(g) ) region.MakeEmpty();   region.Union(path1); // Add a path   region.Intersect(path2); // Intersect with another path   g.FillRegion(Brushes.Red, region); }


Taken together, these combining operations provide a complete set of ways to combine regions for filling and clipping.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net