1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Drawing.Drawing2D; 6 using System.Drawing.Internal; 7 using System.Runtime.InteropServices; 8 9 namespace System.Drawing 10 { 11 /// <summary> 12 /// Encapsulates a GDI+ drawing surface. 13 /// </summary> 14 public sealed partial class Graphics : MarshalByRefObject, IDisposable, IDeviceContext 15 { 16 public void SetClip(Graphics g) => SetClip(g, CombineMode.Replace); 17 SetClip(Graphics g, CombineMode combineMode)18 public void SetClip(Graphics g, CombineMode combineMode) 19 { 20 if (g == null) 21 { 22 throw new ArgumentNullException(nameof(g)); 23 } 24 25 int status = SafeNativeMethods.Gdip.GdipSetClipGraphics(new HandleRef(this, NativeGraphics), new HandleRef(g, g.NativeGraphics), combineMode); 26 SafeNativeMethods.Gdip.CheckStatus(status); 27 } 28 29 public void SetClip(Rectangle rect) => SetClip(rect, CombineMode.Replace); 30 SetClip(Rectangle rect, CombineMode combineMode)31 public void SetClip(Rectangle rect, CombineMode combineMode) 32 { 33 int status = SafeNativeMethods.Gdip.GdipSetClipRectI(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 34 rect.Width, rect.Height, combineMode); 35 SafeNativeMethods.Gdip.CheckStatus(status); 36 } 37 38 public void SetClip(RectangleF rect) => SetClip(rect, CombineMode.Replace); 39 SetClip(RectangleF rect, CombineMode combineMode)40 public void SetClip(RectangleF rect, CombineMode combineMode) 41 { 42 int status = SafeNativeMethods.Gdip.GdipSetClipRect(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 43 rect.Width, rect.Height, combineMode); 44 SafeNativeMethods.Gdip.CheckStatus(status); 45 } 46 47 public void SetClip(GraphicsPath path) => SetClip(path, CombineMode.Replace); 48 SetClip(GraphicsPath path, CombineMode combineMode)49 public void SetClip(GraphicsPath path, CombineMode combineMode) 50 { 51 if (path == null) 52 { 53 throw new ArgumentNullException(nameof(path)); 54 } 55 56 int status = SafeNativeMethods.Gdip.GdipSetClipPath(new HandleRef(this, NativeGraphics), new HandleRef(path, path.nativePath), combineMode); 57 SafeNativeMethods.Gdip.CheckStatus(status); 58 } 59 SetClip(Region region, CombineMode combineMode)60 public void SetClip(Region region, CombineMode combineMode) 61 { 62 if (region == null) 63 { 64 throw new ArgumentNullException(nameof(region)); 65 } 66 67 int status = SafeNativeMethods.Gdip.GdipSetClipRegion(new HandleRef(this, NativeGraphics), new HandleRef(region, region._nativeRegion), combineMode); 68 SafeNativeMethods.Gdip.CheckStatus(status); 69 } 70 IntersectClip(Rectangle rect)71 public void IntersectClip(Rectangle rect) 72 { 73 int status = SafeNativeMethods.Gdip.GdipSetClipRectI(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 74 rect.Width, rect.Height, CombineMode.Intersect); 75 SafeNativeMethods.Gdip.CheckStatus(status); 76 } 77 IntersectClip(RectangleF rect)78 public void IntersectClip(RectangleF rect) 79 { 80 int status = SafeNativeMethods.Gdip.GdipSetClipRect(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 81 rect.Width, rect.Height, CombineMode.Intersect); 82 SafeNativeMethods.Gdip.CheckStatus(status); 83 } 84 IntersectClip(Region region)85 public void IntersectClip(Region region) 86 { 87 if (region == null) 88 { 89 throw new ArgumentNullException(nameof(region)); 90 } 91 92 int status = SafeNativeMethods.Gdip.GdipSetClipRegion(new HandleRef(this, NativeGraphics), new HandleRef(region, region._nativeRegion), 93 CombineMode.Intersect); 94 SafeNativeMethods.Gdip.CheckStatus(status); 95 } 96 ExcludeClip(Rectangle rect)97 public void ExcludeClip(Rectangle rect) 98 { 99 int status = SafeNativeMethods.Gdip.GdipSetClipRectI(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 100 rect.Width, rect.Height, CombineMode.Exclude); 101 SafeNativeMethods.Gdip.CheckStatus(status); 102 } 103 ExcludeClip(Region region)104 public void ExcludeClip(Region region) 105 { 106 if (region == null) 107 { 108 throw new ArgumentNullException(nameof(region)); 109 } 110 111 int status = SafeNativeMethods.Gdip.GdipSetClipRegion(new HandleRef(this, NativeGraphics), 112 new HandleRef(region, region._nativeRegion), 113 CombineMode.Exclude); 114 SafeNativeMethods.Gdip.CheckStatus(status); 115 } 116 ResetClip()117 public void ResetClip() 118 { 119 int status = SafeNativeMethods.Gdip.GdipResetClip(new HandleRef(this, NativeGraphics)); 120 SafeNativeMethods.Gdip.CheckStatus(status); 121 } 122 TranslateClip(float dx, float dy)123 public void TranslateClip(float dx, float dy) 124 { 125 int status = SafeNativeMethods.Gdip.GdipTranslateClip(new HandleRef(this, NativeGraphics), dx, dy); 126 SafeNativeMethods.Gdip.CheckStatus(status); 127 } 128 TranslateClip(int dx, int dy)129 public void TranslateClip(int dx, int dy) 130 { 131 int status = SafeNativeMethods.Gdip.GdipTranslateClip(new HandleRef(this, NativeGraphics), dx, dy); 132 SafeNativeMethods.Gdip.CheckStatus(status); 133 } 134 135 public Region Clip 136 { 137 get 138 { 139 var region = new Region(); 140 int status = SafeNativeMethods.Gdip.GdipGetClip(new HandleRef(this, NativeGraphics), new HandleRef(region, region._nativeRegion)); 141 SafeNativeMethods.Gdip.CheckStatus(status); 142 143 return region; 144 } 145 set => SetClip(value, CombineMode.Replace); 146 } 147 148 public RectangleF ClipBounds 149 { 150 get 151 { 152 var rect = new GPRECTF(); 153 int status = SafeNativeMethods.Gdip.GdipGetClipBounds(new HandleRef(this, NativeGraphics), ref rect); 154 SafeNativeMethods.Gdip.CheckStatus(status); 155 156 return rect.ToRectangleF(); 157 } 158 } 159 160 public bool IsClipEmpty 161 { 162 get 163 { 164 int isEmpty; 165 int status = SafeNativeMethods.Gdip.GdipIsClipEmpty(new HandleRef(this, NativeGraphics), out isEmpty); 166 SafeNativeMethods.Gdip.CheckStatus(status); 167 168 return isEmpty != 0; 169 } 170 } 171 172 public bool IsVisibleClipEmpty 173 { 174 get 175 { 176 int isEmpty; 177 int status = SafeNativeMethods.Gdip.GdipIsVisibleClipEmpty(new HandleRef(this, NativeGraphics), out isEmpty); 178 SafeNativeMethods.Gdip.CheckStatus(status); 179 180 return isEmpty != 0; 181 } 182 } 183 184 IsVisible(int x, int y)185 public bool IsVisible(int x, int y) => IsVisible(new Point(x, y)); 186 IsVisible(Point point)187 public bool IsVisible(Point point) 188 { 189 int isVisible; 190 int status = SafeNativeMethods.Gdip.GdipIsVisiblePointI(new HandleRef(this, NativeGraphics), point.X, point.Y, out isVisible); 191 SafeNativeMethods.Gdip.CheckStatus(status); 192 193 return isVisible != 0; 194 } 195 IsVisible(float x, float y)196 public bool IsVisible(float x, float y) => IsVisible(new PointF(x, y)); 197 IsVisible(PointF point)198 public bool IsVisible(PointF point) 199 { 200 int isVisible; 201 int status = SafeNativeMethods.Gdip.GdipIsVisiblePoint(new HandleRef(this, NativeGraphics), point.X, point.Y, out isVisible); 202 SafeNativeMethods.Gdip.CheckStatus(status); 203 204 return isVisible != 0; 205 } 206 IsVisible(int x, int y, int width, int height)207 public bool IsVisible(int x, int y, int width, int height) 208 { 209 return IsVisible(new Rectangle(x, y, width, height)); 210 } 211 IsVisible(Rectangle rect)212 public bool IsVisible(Rectangle rect) 213 { 214 int isVisible; 215 int status = SafeNativeMethods.Gdip.GdipIsVisibleRectI(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 216 rect.Width, rect.Height, out isVisible); 217 SafeNativeMethods.Gdip.CheckStatus(status); 218 219 return isVisible != 0; 220 } 221 IsVisible(float x, float y, float width, float height)222 public bool IsVisible(float x, float y, float width, float height) 223 { 224 return IsVisible(new RectangleF(x, y, width, height)); 225 } 226 IsVisible(RectangleF rect)227 public bool IsVisible(RectangleF rect) 228 { 229 int isVisible; 230 int status = SafeNativeMethods.Gdip.GdipIsVisibleRect(new HandleRef(this, NativeGraphics), rect.X, rect.Y, 231 rect.Width, rect.Height, out isVisible); 232 SafeNativeMethods.Gdip.CheckStatus(status); 233 234 return isVisible != 0; 235 } 236 237 /// <summary> 238 /// Gets or sets the world transform for this <see cref='Graphics'/>. 239 /// </summary> 240 public Matrix Transform 241 { 242 get 243 { 244 var matrix = new Matrix(); 245 int status = SafeNativeMethods.Gdip.GdipGetWorldTransform(new HandleRef(this, NativeGraphics), 246 new HandleRef(matrix, matrix.nativeMatrix)); 247 SafeNativeMethods.Gdip.CheckStatus(status); 248 249 return matrix; 250 } 251 set 252 { 253 int status = SafeNativeMethods.Gdip.GdipSetWorldTransform(new HandleRef(this, NativeGraphics), 254 new HandleRef(value, value.nativeMatrix)); 255 SafeNativeMethods.Gdip.CheckStatus(status); 256 } 257 } 258 259 /// <summary> 260 /// Resets the world transform to identity. 261 /// </summary> ResetTransform()262 public void ResetTransform() 263 { 264 int status = SafeNativeMethods.Gdip.GdipResetWorldTransform(new HandleRef(this, NativeGraphics)); 265 SafeNativeMethods.Gdip.CheckStatus(status); 266 } 267 268 /// <summary> 269 /// Multiplies the <see cref='Matrix'/> that represents the world transform and <paramref name="matrix"/>. 270 /// </summary> 271 public void MultiplyTransform(Matrix matrix) => MultiplyTransform(matrix, MatrixOrder.Prepend); 272 273 /// <summary> 274 /// Multiplies the <see cref='Matrix'/> that represents the world transform and <paramref name="matrix"/>. 275 /// </summary> MultiplyTransform(Matrix matrix, MatrixOrder order)276 public void MultiplyTransform(Matrix matrix, MatrixOrder order) 277 { 278 if (matrix == null) 279 { 280 throw new ArgumentNullException(nameof(matrix)); 281 } 282 283 int status = SafeNativeMethods.Gdip.GdipMultiplyWorldTransform(new HandleRef(this, NativeGraphics), 284 new HandleRef(matrix, matrix.nativeMatrix), 285 order); 286 SafeNativeMethods.Gdip.CheckStatus(status); 287 } 288 TranslateTransform(float dx, float dy)289 public void TranslateTransform(float dx, float dy) => TranslateTransform(dx, dy, MatrixOrder.Prepend); 290 TranslateTransform(float dx, float dy, MatrixOrder order)291 public void TranslateTransform(float dx, float dy, MatrixOrder order) 292 { 293 int status = SafeNativeMethods.Gdip.GdipTranslateWorldTransform(new HandleRef(this, NativeGraphics), dx, dy, order); 294 SafeNativeMethods.Gdip.CheckStatus(status); 295 } 296 ScaleTransform(float sx, float sy)297 public void ScaleTransform(float sx, float sy) => ScaleTransform(sx, sy, MatrixOrder.Prepend); 298 ScaleTransform(float sx, float sy, MatrixOrder order)299 public void ScaleTransform(float sx, float sy, MatrixOrder order) 300 { 301 int status = SafeNativeMethods.Gdip.GdipScaleWorldTransform(new HandleRef(this, NativeGraphics), sx, sy, order); 302 SafeNativeMethods.Gdip.CheckStatus(status); 303 } 304 RotateTransform(float angle)305 public void RotateTransform(float angle) => RotateTransform(angle, MatrixOrder.Prepend); 306 RotateTransform(float angle, MatrixOrder order)307 public void RotateTransform(float angle, MatrixOrder order) 308 { 309 int status = SafeNativeMethods.Gdip.GdipRotateWorldTransform(new HandleRef(this, NativeGraphics), angle, order); 310 SafeNativeMethods.Gdip.CheckStatus(status); 311 } 312 } 313 } 314