LinearGradientBrush
Encapsulates a Brush with a linear gradient. This class cannot be inherited.
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.Graphics.GdiPlus;
namespace System.Drawing.Drawing2D
{
[NullableContext(1)]
[Nullable(0)]
public sealed class LinearGradientBrush : Brush
{
private bool _interpolationColorsWasSet;
[Nullable(0)]
internal unsafe GpLineGradient* NativeLineGradient {
[NullableContext(0)]
get {
return (GpLineGradient*)base.NativeBrush;
}
}
public unsafe Color[] LinearColors {
get {
uint* ptr = stackalloc uint[2];
PInvoke.GdipGetLineColors(NativeLineGradient, ptr).ThrowIfFailed();
GC.KeepAlive(this);
return new Color[2] {
Color.FromArgb((int)(*ptr)),
Color.FromArgb((int)ptr[1])
};
}
set {
PInvoke.GdipSetLineColors(NativeLineGradient, (uint)value[0].ToArgb(), (uint)value[1].ToArgb()).ThrowIfFailed();
GC.KeepAlive(this);
}
}
public unsafe RectangleF Rectangle {
get {
RectangleF result = default(RectangleF);
PInvoke.GdipGetLineRect(NativeLineGradient, (RectF*)(&result)).ThrowIfFailed();
GC.KeepAlive(this);
return result;
}
}
public unsafe bool GammaCorrection {
get {
BOOL value = default(BOOL);
PInvoke.GdipGetLineGammaCorrection(NativeLineGradient, &value).ThrowIfFailed();
GC.KeepAlive(this);
return value;
}
set {
PInvoke.GdipSetLineGammaCorrection(NativeLineGradient, value).ThrowIfFailed();
GC.KeepAlive(this);
}
}
[Nullable(2)]
public unsafe Blend Blend {
[NullableContext(2)]
get {
if (_interpolationColorsWasSet)
return null;
int num = default(int);
PInvoke.GdipGetLineBlendCount(NativeLineGradient, &num).ThrowIfFailed();
GC.KeepAlive(this);
if (num > 0) {
Blend blend = new Blend(num);
fixed (float* blend2 = blend.Factors) {
fixed (float* positions = blend.Positions) {
PInvoke.GdipGetLineBlend(NativeLineGradient, blend2, positions, num).ThrowIfFailed();
GC.KeepAlive(this);
return blend;
}
}
}
return null;
}
[NullableContext(2)]
set {
ArgumentNullException.ThrowIfNull(value, "value");
ArgumentNullException.ThrowIfNull(value.Factors, "value.Factors");
if (value.Positions == null || value.Positions.Length != value.Factors.Length)
throw new ArgumentException(System.SR.Format(System.SR.InvalidArgumentValue, "value.Positions", value.Positions), "value");
fixed (float* blend = value.Factors) {
fixed (float[] array = value.Positions) {
float* positions = (float*);
PInvoke.GdipSetLineBlend(NativeLineGradient, blend, positions, value.Factors.Length).ThrowIfFailed();
GC.KeepAlive(this);
}
}
array = null;
}
}
public unsafe ColorBlend InterpolationColors {
get {
int num = default(int);
PInvoke.GdipGetLinePresetBlendCount(NativeLineGradient, &num).ThrowIfFailed();
if (num != 0) {
ArgbBuffer argbBuffer = new ArgbBuffer(num);
try {
float[] array = new float[num];
ColorBlend colorBlend = new ColorBlend(num);
fixed (uint* blend = &argbBuffer.GetPinnableReference()) {
fixed (float* positions = array) {
PInvoke.GdipGetLinePresetBlend(NativeLineGradient, blend, positions, num).ThrowIfFailed();
}
}
colorBlend.Positions = array;
colorBlend.Colors = argbBuffer.ToColorArray(num);
GC.KeepAlive(this);
return colorBlend;
} finally {
argbBuffer.Dispose();
}
}
return new ColorBlend();
}
set {
_interpolationColorsWasSet = true;
ArgumentNullException.ThrowIfNull(value, "value");
int count = value.Colors.Length;
if (value.Positions == null)
throw new ArgumentException(System.SR.Format(System.SR.InvalidArgumentValue, "value.Positions", value.Positions), "value");
if (value.Colors.Length != value.Positions.Length)
throw new ArgumentException(null, "value");
float[] positions = value.Positions;
ArgbBuffer argbBuffer = new ArgbBuffer(value.Colors);
try {
fixed (float* positions2 = positions) {
fixed (uint* blend = &argbBuffer.GetPinnableReference()) {
PInvoke.GdipSetLinePresetBlend(NativeLineGradient, blend, positions2, count).ThrowIfFailed();
GC.KeepAlive(this);
}
}
} finally {
argbBuffer.Dispose();
}
}
}
public unsafe WrapMode WrapMode {
get {
WrapMode result = default(WrapMode);
PInvoke.GdipGetLineWrapMode(NativeLineGradient, (global::Windows.Win32.Graphics.GdiPlus.WrapMode*)(&result)).ThrowIfFailed();
GC.KeepAlive(this);
return result;
}
set {
if ((value < WrapMode.Tile || value > WrapMode.Clamp) ? true : false)
throw new InvalidEnumArgumentException("value", (int)value, typeof(WrapMode));
PInvoke.GdipSetLineWrapMode(NativeLineGradient, (global::Windows.Win32.Graphics.GdiPlus.WrapMode)value).ThrowIfFailed();
GC.KeepAlive(this);
}
}
public unsafe Matrix Transform {
get {
Matrix matrix = new Matrix();
PInvoke.GdipGetLineTransform(NativeLineGradient, matrix.NativeMatrix).ThrowIfFailed();
GC.KeepAlive(this);
return matrix;
}
set {
ArgumentNullException.ThrowIfNull(value, "value");
PInvoke.GdipSetLineTransform(NativeLineGradient, value.NativeMatrix).ThrowIfFailed();
GC.KeepAlive(value);
GC.KeepAlive(this);
}
}
public unsafe LinearGradientBrush(PointF point1, PointF point2, Color color1, Color color2)
{
GpLineGradient* nativeBrushInternal = default(GpLineGradient*);
PInvoke.GdipCreateLineBrush((global::Windows.Win32.Graphics.GdiPlus.PointF*)(&point1), (global::Windows.Win32.Graphics.GdiPlus.PointF*)(&point2), (uint)color1.ToArgb(), (uint)color2.ToArgb(), global::Windows.Win32.Graphics.GdiPlus.WrapMode.WrapModeTile, &nativeBrushInternal).ThrowIfFailed();
SetNativeBrushInternal((GpBrush*)nativeBrushInternal);
}
public LinearGradientBrush(Point point1, Point point2, Color color1, Color color2)
: this((PointF)point1, (PointF)point2, color1, color2)
{
}
public unsafe LinearGradientBrush(RectangleF rect, Color color1, Color color2, LinearGradientMode linearGradientMode)
{
if ((linearGradientMode < LinearGradientMode.Horizontal || linearGradientMode > LinearGradientMode.BackwardDiagonal) ? true : false)
throw new InvalidEnumArgumentException("linearGradientMode", (int)linearGradientMode, typeof(LinearGradientMode));
if ((double)rect.Width == 0 || (double)rect.Height == 0)
throw new ArgumentException(System.SR.Format(System.SR.GdiplusInvalidRectangle, rect.ToString()));
GpLineGradient* nativeBrushInternal = default(GpLineGradient*);
PInvoke.GdipCreateLineBrushFromRect((RectF*)(&rect), (ARGB)ref color1, (ARGB)ref color2, (global::Windows.Win32.Graphics.GdiPlus.LinearGradientMode)linearGradientMode, global::Windows.Win32.Graphics.GdiPlus.WrapMode.WrapModeTile, &nativeBrushInternal).ThrowIfFailed();
SetNativeBrushInternal((GpBrush*)nativeBrushInternal);
}
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode)
: this((RectangleF)rect, color1, color2, linearGradientMode)
{
}
public LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle)
: this(rect, color1, color2, angle, false)
{
}
public unsafe LinearGradientBrush(RectangleF rect, Color color1, Color color2, float angle, bool isAngleScaleable)
{
if ((double)rect.Width == 0 || (double)rect.Height == 0)
throw new ArgumentException(System.SR.Format(System.SR.GdiplusInvalidRectangle, rect.ToString()));
GpLineGradient* nativeBrushInternal = default(GpLineGradient*);
PInvoke.GdipCreateLineBrushFromRectWithAngle((RectF*)(&rect), (ARGB)ref color1, (ARGB)ref color2, angle, isAngleScaleable, global::Windows.Win32.Graphics.GdiPlus.WrapMode.WrapModeTile, &nativeBrushInternal).ThrowIfFailed();
SetNativeBrushInternal((GpBrush*)nativeBrushInternal);
}
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle)
: this(rect, color1, color2, angle, false)
{
}
public LinearGradientBrush(Rectangle rect, Color color1, Color color2, float angle, bool isAngleScaleable)
: this((RectangleF)rect, color1, color2, angle, isAngleScaleable)
{
}
[NullableContext(0)]
internal unsafe LinearGradientBrush(GpLineGradient* nativeBrush)
{
SetNativeBrushInternal((GpBrush*)nativeBrush);
}
public unsafe override object Clone()
{
GpBrush* nativeBrush = default(GpBrush*);
PInvoke.GdipCloneBrush(base.NativeBrush, &nativeBrush).ThrowIfFailed();
GC.KeepAlive(this);
return new LinearGradientBrush((GpLineGradient*)nativeBrush);
}
public void SetSigmaBellShape(float focus)
{
SetSigmaBellShape(focus, 1);
}
public unsafe void SetSigmaBellShape(float focus, float scale)
{
PInvoke.GdipSetLineSigmaBlend(NativeLineGradient, focus, scale).ThrowIfFailed();
GC.KeepAlive(this);
}
public void SetBlendTriangularShape(float focus)
{
SetBlendTriangularShape(focus, 1);
}
public unsafe void SetBlendTriangularShape(float focus, float scale)
{
_interpolationColorsWasSet = false;
PInvoke.GdipSetLineLinearBlend(NativeLineGradient, focus, scale).ThrowIfFailed();
GC.KeepAlive(this);
}
public unsafe void ResetTransform()
{
PInvoke.GdipResetLineTransform(NativeLineGradient).ThrowIfFailed();
GC.KeepAlive(this);
}
public void MultiplyTransform(Matrix matrix)
{
MultiplyTransform(matrix, MatrixOrder.Prepend);
}
public unsafe void MultiplyTransform(Matrix matrix, MatrixOrder order)
{
ArgumentNullException.ThrowIfNull(matrix, "matrix");
PInvoke.GdipMultiplyLineTransform(NativeLineGradient, matrix.NativeMatrix, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed();
GC.KeepAlive(this);
}
public void TranslateTransform(float dx, float dy)
{
TranslateTransform(dx, dy, MatrixOrder.Prepend);
}
public unsafe void TranslateTransform(float dx, float dy, MatrixOrder order)
{
PInvoke.GdipTranslateLineTransform(NativeLineGradient, dx, dy, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed();
GC.KeepAlive(this);
}
public void ScaleTransform(float sx, float sy)
{
ScaleTransform(sx, sy, MatrixOrder.Prepend);
}
public unsafe void ScaleTransform(float sx, float sy, MatrixOrder order)
{
PInvoke.GdipScaleLineTransform(NativeLineGradient, sx, sy, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed();
GC.KeepAlive(this);
}
public void RotateTransform(float angle)
{
RotateTransform(angle, MatrixOrder.Prepend);
}
public unsafe void RotateTransform(float angle, MatrixOrder order)
{
PInvoke.GdipRotateLineTransform(NativeLineGradient, angle, (global::Windows.Win32.Graphics.GdiPlus.MatrixOrder)order).ThrowIfFailed();
GC.KeepAlive(this);
}
}
}