<PackageReference Include="System.Drawing.Common" Version="10.0.0-preview.6.25358.103" />

Pen

Defines an object used to draw lines and curves. This class cannot be inherited.
using System.ComponentModel; using System.Drawing.Drawing2D; using System.Drawing.Internal; using System.Runtime.CompilerServices; using Windows.Win32; using Windows.Win32.Graphics.Gdi; using Windows.Win32.Graphics.GdiPlus; namespace System.Drawing { [NullableContext(1)] [Nullable(0)] public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable, ISystemColorTracker { [Nullable(0)] private unsafe GpPen* _nativePen; private Color _color; private bool _immutable; private bool _dashStyleWasOrIsNotSolid; [Nullable(0)] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] internal unsafe GpPen* NativePen { [NullableContext(0)] get { return _nativePen; } } public unsafe float Width { get { float result = default(float); PInvokeGdiPlus.GdipGetPenWidth(NativePen, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenWidth(NativePen, value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.LineCap StartCap { get { System.Drawing.Drawing2D.LineCap result = default(System.Drawing.Drawing2D.LineCap); PInvokeGdiPlus.GdipGetPenStartCap(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineCap*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (value <= System.Drawing.Drawing2D.LineCap.ArrowAnchor) { if ((uint)value > 3 && (uint)(value - 16) > 4) goto IL_0022; } else if (value != System.Drawing.Drawing2D.LineCap.AnchorMask && value != System.Drawing.Drawing2D.LineCap.Custom) { goto IL_0022; } if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenStartCap(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineCap)value).ThrowIfFailed(); GC.KeepAlive(this); return; IL_0022: throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.LineCap)); } } public unsafe System.Drawing.Drawing2D.LineCap EndCap { get { System.Drawing.Drawing2D.LineCap result = default(System.Drawing.Drawing2D.LineCap); PInvokeGdiPlus.GdipGetPenEndCap(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineCap*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (value <= System.Drawing.Drawing2D.LineCap.ArrowAnchor) { if ((uint)value > 3 && (uint)(value - 16) > 4) goto IL_0022; } else if (value != System.Drawing.Drawing2D.LineCap.AnchorMask && value != System.Drawing.Drawing2D.LineCap.Custom) { goto IL_0022; } if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenEndCap(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineCap)value).ThrowIfFailed(); GC.KeepAlive(this); return; IL_0022: throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.LineCap)); } } public unsafe CustomLineCap CustomStartCap { get { GpCustomLineCap* cap = default(GpCustomLineCap*); PInvokeGdiPlus.GdipGetPenCustomStartCap(NativePen, &cap).ThrowIfFailed(); GC.KeepAlive(this); return CustomLineCap.CreateCustomLineCapObject(cap); } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenCustomStartCap(NativePen, (GpCustomLineCap*)(long)((value == null) ? ((IntPtr)(void*)null) : ((IntPtr)value._nativeCap))).ThrowIfFailed(); GC.KeepAlive(value); GC.KeepAlive(this); } } public unsafe CustomLineCap CustomEndCap { get { GpCustomLineCap* cap = default(GpCustomLineCap*); PInvokeGdiPlus.GdipGetPenCustomEndCap(NativePen, &cap).ThrowIfFailed(); GC.KeepAlive(this); return CustomLineCap.CreateCustomLineCapObject(cap); } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenCustomEndCap(NativePen, (GpCustomLineCap*)(long)((value == null) ? ((IntPtr)(void*)null) : ((IntPtr)value._nativeCap))).ThrowIfFailed(); GC.KeepAlive(value); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.DashCap DashCap { get { System.Drawing.Drawing2D.DashCap result = default(System.Drawing.Drawing2D.DashCap); PInvokeGdiPlus.GdipGetPenDashCap197819(NativePen, (global::Windows.Win32.Graphics.GdiPlus.DashCap*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (value != 0 && value != System.Drawing.Drawing2D.DashCap.Round && value != System.Drawing.Drawing2D.DashCap.Triangle) throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.DashCap)); if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenDashCap197819(NativePen, (global::Windows.Win32.Graphics.GdiPlus.DashCap)value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.LineJoin LineJoin { get { System.Drawing.Drawing2D.LineJoin result = default(System.Drawing.Drawing2D.LineJoin); PInvokeGdiPlus.GdipGetPenLineJoin(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineJoin*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if ((value < System.Drawing.Drawing2D.LineJoin.Miter || value > System.Drawing.Drawing2D.LineJoin.MiterClipped) ? true : false) throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.LineJoin)); if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenLineJoin(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineJoin)value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe float MiterLimit { get { float result = default(float); PInvokeGdiPlus.GdipGetPenMiterLimit(NativePen, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenMiterLimit(NativePen, value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.PenAlignment Alignment { get { System.Drawing.Drawing2D.PenAlignment result = default(System.Drawing.Drawing2D.PenAlignment); PInvokeGdiPlus.GdipGetPenMode(NativePen, (global::Windows.Win32.Graphics.GdiPlus.PenAlignment*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if ((value < System.Drawing.Drawing2D.PenAlignment.Center || value > System.Drawing.Drawing2D.PenAlignment.Right) ? true : false) throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.PenAlignment)); if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenMode(NativePen, (global::Windows.Win32.Graphics.GdiPlus.PenAlignment)value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.Matrix Transform { get { System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(); PInvokeGdiPlus.GdipGetPenTransform(NativePen, matrix.NativeMatrix).ThrowIfFailed(); GC.KeepAlive(this); return matrix; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); ArgumentNullException.ThrowIfNull(value, "value"); PInvokeGdiPlus.GdipSetPenTransform(NativePen, value.NativeMatrix).ThrowIfFailed(); GC.KeepAlive(value); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.PenType PenType { get { global::Windows.Win32.Graphics.GdiPlus.PenType result = default(global::Windows.Win32.Graphics.GdiPlus.PenType); PInvokeGdiPlus.GdipGetPenFillType(NativePen, &result).ThrowIfFailed(); GC.KeepAlive(this); return (System.Drawing.Drawing2D.PenType)result; } } public unsafe Color Color { get { if (_color == Color.Empty) { if (PenType != 0) throw new ArgumentException(System.SR.GdiplusInvalidParameter); ARGB argb = default(ARGB); PInvokeGdiPlus.GdipGetPenColor(NativePen, (uint*)(&argb)).ThrowIfFailed(); GC.KeepAlive(this); _color = argb; } return _color; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); if (value != _color) { Color color = _color; _color = value; InternalSetColor(value); if (value.IsSystemColor && !color.IsSystemColor) SystemColorTracker.Add(this); } } } public unsafe Brush Brush { get { Brush result = null; switch (PenType) { case System.Drawing.Drawing2D.PenType.SolidColor: result = new SolidBrush((GpSolidFill*)GetNativeBrush()); break; case System.Drawing.Drawing2D.PenType.HatchFill: result = new HatchBrush((GpHatch*)GetNativeBrush()); break; case System.Drawing.Drawing2D.PenType.TextureFill: result = new TextureBrush((GpTexture*)GetNativeBrush()); break; case System.Drawing.Drawing2D.PenType.PathGradient: result = new PathGradientBrush((GpPathGradient*)GetNativeBrush()); break; case System.Drawing.Drawing2D.PenType.LinearGradient: result = new LinearGradientBrush((GpLineGradient*)GetNativeBrush()); break; } return result; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); ArgumentNullException.ThrowIfNull(value, "value"); PInvokeGdiPlus.GdipSetPenBrushFill(NativePen, value.Pointer()).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe System.Drawing.Drawing2D.DashStyle DashStyle { get { System.Drawing.Drawing2D.DashStyle result = default(System.Drawing.Drawing2D.DashStyle); PInvokeGdiPlus.GdipGetPenDashStyle(NativePen, (global::Windows.Win32.Graphics.GdiPlus.DashStyle*)(&result)).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if ((value < System.Drawing.Drawing2D.DashStyle.Solid || value > System.Drawing.Drawing2D.DashStyle.Custom) ? true : false) throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Drawing.Drawing2D.DashStyle)); if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenDashStyle(NativePen, (global::Windows.Win32.Graphics.GdiPlus.DashStyle)value).ThrowIfFailed(); GC.KeepAlive(this); if (value == System.Drawing.Drawing2D.DashStyle.Custom) EnsureValidDashPattern(); if (value != 0) _dashStyleWasOrIsNotSolid = true; } } public unsafe float DashOffset { get { float result = default(float); PInvokeGdiPlus.GdipGetPenDashOffset(NativePen, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenDashOffset(NativePen, value).ThrowIfFailed(); GC.KeepAlive(this); } } public unsafe float[] DashPattern { get { int num = default(int); PInvokeGdiPlus.GdipGetPenDashCount(NativePen, &num).ThrowIfFailed(); GC.KeepAlive(this); float[] array; if (num > 0) { array = new float[num]; fixed (float* dash = array) { PInvokeGdiPlus.GdipGetPenDashArray(NativePen, dash, num).ThrowIfFailed(); } } else { if (DashStyle == System.Drawing.Drawing2D.DashStyle.Solid && !_dashStyleWasOrIsNotSolid) throw new InvalidOperationException(); array = ((DashStyle != 0) ? new float[1] { 1 } : Array.Empty<float>()); } GC.KeepAlive(this); return array; } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); if (value == null || value.Length == 0) throw new ArgumentException(System.SR.InvalidDashPattern); fixed (float* dash = value) { PInvokeGdiPlus.GdipSetPenDashArray(NativePen, dash, value.Length).ThrowIfFailed(); GC.KeepAlive(this); } } } public unsafe float[] CompoundArray { get { int num = default(int); PInvokeGdiPlus.GdipGetPenCompoundCount(NativePen, &num).ThrowIfFailed(); if (num != 0) { float[] obj = new float[num]; fixed (float* dash = obj) { PInvokeGdiPlus.GdipGetPenCompoundArray(NativePen, dash, num).ThrowIfFailed(); GC.KeepAlive(this); return obj; } } return Array.Empty<float>(); } set { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); ArgumentNullException.ThrowIfNull(value, "value"); fixed (float* dash = value) { PInvokeGdiPlus.GdipSetPenCompoundArray(NativePen, dash, value.Length).ThrowIfFailed(); GC.KeepAlive(this); } } } [NullableContext(0)] private unsafe Pen(GpPen* nativePen) { SetNativePen(nativePen); } internal Pen(Color color, bool immutable) : this(color) { _immutable = immutable; } public Pen(Color color) : this(color, 1) { } public unsafe Pen(Color color, float width) { _color = color; GpPen* nativePen = default(GpPen*); PInvokeGdiPlus.GdipCreatePen1((uint)color.ToArgb(), width, Unit.UnitWorld, &nativePen).ThrowIfFailed(); SetNativePen(nativePen); if (_color.IsSystemColor) SystemColorTracker.Add(this); } public Pen(Brush brush) : this(brush, 1) { } public unsafe Pen(Brush brush, float width) { ArgumentNullException.ThrowIfNull(brush, "brush"); GpPen* nativePen = default(GpPen*); PInvokeGdiPlus.GdipCreatePen2(brush.NativeBrush, width, Unit.UnitWorld, &nativePen).ThrowIfFailed(); GC.KeepAlive(brush); SetNativePen(nativePen); } [NullableContext(0)] internal unsafe void SetNativePen(GpPen* nativePen) { _nativePen = nativePen; } public unsafe object Clone() { GpPen* nativePen = default(GpPen*); PInvokeGdiPlus.GdipClonePen(NativePen, &nativePen).ThrowIfFailed(); GC.KeepAlive(this); return new Pen(nativePen); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private unsafe void Dispose(bool disposing) { if (!disposing) _immutable = false; else if (_immutable) { throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); } if (_nativePen != null) { if (Gdip.Initialized) PInvokeGdiPlus.GdipDeletePen(NativePen); _nativePen = null; } } ~Pen() { Dispose(false); } public unsafe void SetLineCap(System.Drawing.Drawing2D.LineCap startCap, System.Drawing.Drawing2D.LineCap endCap, System.Drawing.Drawing2D.DashCap dashCap) { if (_immutable) throw new ArgumentException(System.SR.Format(System.SR.CantChangeImmutableObjects, "Pen")); PInvokeGdiPlus.GdipSetPenLineCap197819(NativePen, (global::Windows.Win32.Graphics.GdiPlus.LineCap)startCap, (global::Windows.Win32.Graphics.GdiPlus.LineCap)endCap, (global::Windows.Win32.Graphics.GdiPlus.DashCap)dashCap).ThrowIfFailed(); GC.KeepAlive(this); } public unsafe void ResetTransform() { PInvokeGdiPlus.GdipResetPenTransform(NativePen).ThrowIfFailed(); GC.KeepAlive(this); } public void MultiplyTransform(System.Drawing.Drawing2D.Matrix matrix) { MultiplyTransform(matrix, System.Drawing.Drawing2D.MatrixOrder.Prepend); } public unsafe void MultiplyTransform(System.Drawing.Drawing2D.Matrix matrix, System.Drawing.Drawing2D.MatrixOrder order) { ArgumentNullException.ThrowIfNull(matrix, "matrix"); if (matrix.NativeMatrix != null) { PInvokeGdiPlus.GdipMultiplyPenTransform(NativePen, matrix.NativeMatrix, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed(); GC.KeepAlive(matrix); GC.KeepAlive(this); } } public void TranslateTransform(float dx, float dy) { TranslateTransform(dx, dy, System.Drawing.Drawing2D.MatrixOrder.Prepend); } public unsafe void TranslateTransform(float dx, float dy, System.Drawing.Drawing2D.MatrixOrder order) { PInvokeGdiPlus.GdipTranslatePenTransform(NativePen, dx, dy, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed(); GC.KeepAlive(this); } public void ScaleTransform(float sx, float sy) { ScaleTransform(sx, sy, System.Drawing.Drawing2D.MatrixOrder.Prepend); } public unsafe void ScaleTransform(float sx, float sy, System.Drawing.Drawing2D.MatrixOrder order) { PInvokeGdiPlus.GdipScalePenTransform(NativePen, sx, sy, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed(); GC.KeepAlive(this); } public void RotateTransform(float angle) { RotateTransform(angle, System.Drawing.Drawing2D.MatrixOrder.Prepend); } public unsafe void RotateTransform(float angle, System.Drawing.Drawing2D.MatrixOrder order) { PInvokeGdiPlus.GdipRotatePenTransform(NativePen, angle, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed(); GC.KeepAlive(this); } private unsafe void InternalSetColor(Color value) { PInvokeGdiPlus.GdipSetPenColor(NativePen, (uint)_color.ToArgb()).ThrowIfFailed(); GC.KeepAlive(this); _color = value; } [NullableContext(0)] private unsafe GpBrush* GetNativeBrush() { GpBrush* result = default(GpBrush*); PInvokeGdiPlus.GdipGetPenBrushFill(NativePen, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } private unsafe void EnsureValidDashPattern() { int num = default(int); PInvokeGdiPlus.GdipGetPenDashCount(NativePen, &num); GC.KeepAlive(this); if (num == 0) DashPattern = new float[1] { 1 }; } unsafe void ISystemColorTracker.OnSystemColorChanged() { if (NativePen != null) InternalSetColor(_color); } } }