/// <devdoc> /// Selects a region as the current clipping region for the device context. /// Remarks (From MSDN): /// - Only a copy of the selected region is used. The region itself can be selected for any number of other device contexts or it can be deleted. /// - The SelectClipRgn function assumes that the coordinates for a region are specified in device units. /// - To remove a device-context's clipping region, specify a NULL region handle. /// </devdoc> public void SetClip(WindowsRegion region) { HandleRef hdc = new HandleRef(this, this.Hdc); HandleRef hRegion = new HandleRef(region, region.HRegion); IntUnsafeNativeMethods.SelectClipRgn(hdc, hRegion); }
///<devdoc> /// Creates a new clipping region from the intersection of the current clipping region and /// the specified rectangle. ///</devdoc> public void IntersectClip(WindowsRegion wr) { //if the incoming windowsregion is infinite, there is no need to do any intersecting. if (wr.HRegion == IntPtr.Zero) { return; } WindowsRegion clip = new WindowsRegion(0, 0, 0, 0); try { int result = IntUnsafeNativeMethods.GetClipRgn(new HandleRef(this, this.Hdc), new HandleRef(clip, clip.HRegion)); // If the function succeeds and there is a clipping region for the given device context, the return value is 1. if (result == 1) { Debug.Assert(clip.HRegion != IntPtr.Zero); wr.CombineRegion(clip, wr, RegionCombineMode.AND); //1 = AND (or Intersect) } SetClip(wr); } finally { clip.Dispose(); } }
// Consider implementing a constructor that calls ExtCreateRegion(XFORM lpXform, DWORD nCount, RGNDATA lpRgnData) if needed. /// <devdoc> /// Creates a WindowsRegion from a region handle, if 'takeOwnership' is true, the handle is added to the HandleCollector /// and is removed & destroyed on dispose. /// </devdoc> public static WindowsRegion FromHregion(IntPtr hRegion, bool takeOwnership) { WindowsRegion wr = new WindowsRegion(); // Note: Passing IntPtr.Zero for hRegion is ok. GDI+ infinite regions will have hRegion == null. // GDI's SelectClipRgn interprets null region handle as resetting the clip region (all region will be available for painting). if( hRegion != IntPtr.Zero ) { wr.nativeHandle = hRegion; if (takeOwnership) { wr.ownHandle = true; System.Internal.HandleCollector.Add(hRegion, IntSafeNativeMethods.CommonHandles.GDI); } } return wr; }
/// <devdoc> /// Creates a WindowsRegion from a System.Drawing.Region. /// </devdoc> public static WindowsRegion FromRegion(Region region, Graphics g) { if (region.IsInfinite(g)) { // An infinite region would cover the entire device region which is the same as // not having a clipping region. Observe that this is not the same as having an // empty region, which when clipping to it has the effect of excluding the entire // device region. // To remove the clip region from a dc the SelectClipRgn() function needs to be // called with a null region ptr - that's why we use the empty constructor here. // GDI+ will return IntPtr.Zero for Region.GetHrgn(Graphics) when the region is // Infinite. return(new WindowsRegion()); } return(WindowsRegion.FromHregion(region.GetHrgn(g), true)); }
// Consider implementing a constructor that calls ExtCreateRegion(XFORM lpXform, DWORD nCount, RGNDATA lpRgnData) if needed. /// <devdoc> /// Creates a WindowsRegion from a region handle, if 'takeOwnership' is true, the handle is added to the HandleCollector /// and is removed & destroyed on dispose. /// </devdoc> public static WindowsRegion FromHregion(IntPtr hRegion, bool takeOwnership) { WindowsRegion wr = new WindowsRegion(); // Note: Passing IntPtr.Zero for hRegion is ok. GDI+ infinite regions will have hRegion == null. // GDI's SelectClipRgn interprets null region handle as resetting the clip region (all region will be available for painting). if (hRegion != IntPtr.Zero) { wr.nativeHandle = hRegion; if (takeOwnership) { wr.ownHandle = true; System.Internal.HandleCollector.Add(hRegion, IntSafeNativeMethods.CommonHandles.GDI); } } return(wr); }
/// <devdoc> /// Combines region1 & region2 into this region. The regions cannot be null. /// The three regions need not be distinct. For example, the sourceRgn1 can equal this region. /// </devdoc> public IntNativeMethods.RegionFlags CombineRegion(WindowsRegion region1, WindowsRegion region2, RegionCombineMode mode) { return(IntUnsafeNativeMethods.CombineRgn(new HandleRef(this, this.HRegion), new HandleRef(region1, region1.HRegion), new HandleRef(region2, region2.HRegion), mode)); }
public static WindowsGraphics FromGraphics(Graphics g, ApplyGraphicsProperties properties) { Debug.Assert(g != null, "null Graphics object."); //Debug.Assert( properties != ApplyGraphicsProperties.None, "Consider using other WindowsGraphics constructor if not preserving Graphics properties." ); WindowsRegion wr = null; float[] elements = null; Region clipRgn = null; Matrix worldTransf = null; if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0 || (properties & ApplyGraphicsProperties.Clipping) != 0) { if (g.GetContextInfo() is object[] data && data.Length == 2) { clipRgn = data[0] as Region; worldTransf = data[1] as Matrix; } if (worldTransf != null) { if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0) { elements = worldTransf.Elements; } worldTransf.Dispose(); } if (clipRgn != null) { if ((properties & ApplyGraphicsProperties.Clipping) != 0) { // We have to create the WindowsRegion and dipose the Region object before locking the Graphics object, // in case of an unlikely exception before releasing the WindowsRegion, the finalizer will do it for us. // (no try-finally block since this method is used frequently - perf). // If the Graphics.Clip has not been set (Region.IsInfinite) we don't need to apply it to the DC. if (!clipRgn.IsInfinite(g)) { wr = WindowsRegion.FromRegion(clipRgn, g); // WindowsRegion will take ownership of the hRegion. } } clipRgn.Dispose(); // Disposing the Region object doesn't destroy the hRegion. } } WindowsGraphics wg = WindowsGraphics.FromHdc(g.GetHdc()); // This locks the Graphics object. wg.graphics = g; // Apply transform and clip if (wr != null) { using (wr) { // If the Graphics object was created from a native DC the actual clipping region is the intersection // beteween the original DC clip region and the GDI+ one - for display Graphics it is the same as // Graphics.VisibleClipBounds. wg.DeviceContext.IntersectClip(wr); } } if (elements != null) { // elements (XFORM) = [eM11, eM12, eM21, eM22, eDx, eDy], eDx/eDy specify the translation offset. wg.DeviceContext.TranslateTransform((int)elements[4], (int)elements[5]); } return(wg); }
/// <devdoc> /// Combines region1 & region2 into this region. The regions cannot be null. /// The three regions need not be distinct. For example, the sourceRgn1 can equal this region. /// </devdoc> public IntNativeMethods.RegionFlags CombineRegion(WindowsRegion region1, WindowsRegion region2, RegionCombineMode mode) { return IntUnsafeNativeMethods.CombineRgn(new HandleRef(this, this.HRegion), new HandleRef(region1, region1.HRegion), new HandleRef(region2, region2.HRegion), mode); }
public void IntersectClip(WindowsRegion wr) { //if the incoming windowsregion is infinite, there is no need to do any intersecting. if (wr.HRegion == IntPtr.Zero) { return; } WindowsRegion clip = new WindowsRegion(0,0,0,0); try { int result = IntUnsafeNativeMethods.GetClipRgn(new HandleRef( this, this.Hdc), new HandleRef(clip, clip.HRegion)); // If the function succeeds and there is a clipping region for the given device context, the return value is 1. if (result == 1) { Debug.Assert(clip.HRegion != IntPtr.Zero); wr.CombineRegion(clip, wr, RegionCombineMode.AND); //1 = AND (or Intersect) } SetClip(wr); } finally { clip.Dispose(); } }
public void SetClip(WindowsRegion region) { HandleRef hdc = new HandleRef(this, this.Hdc); HandleRef hRegion = new HandleRef(region, region.HRegion); IntUnsafeNativeMethods.SelectClipRgn(hdc, hRegion); }
public void IntersectClip(WindowsRegion wr) { if (wr.HRegion != IntPtr.Zero) { using (WindowsRegion region = new WindowsRegion(0, 0, 0, 0)) { if (IntUnsafeNativeMethods.GetClipRgn(new HandleRef(this, this.Hdc), new HandleRef(region, region.HRegion)) == 1) { wr.CombineRegion(region, wr, RegionCombineMode.AND); } this.SetClip(wr); } } }