Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the missing SKColorFilter types #2882

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions binding/SkiaSharp/SKColorFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ public unsafe class SKColorFilter : SKObject, ISKReferenceCounted
public const int ColorMatrixSize = 20;
public const int TableMaxLength = 256;

private static readonly SKColorFilter srgbToLinear;
private static readonly SKColorFilter linearToSrgb;

static SKColorFilter ()
{
// TODO: This is not the best way to do this as it will create a lot of objects that
// might not be needed, but it is the only way to ensure that the static
// instances are created before any access is made to them.
// See more info: SKObject.EnsureStaticInstanceAreInitialized()

srgbToLinear = new SKColorFilterStatic (SkiaApi.sk_colorfilter_new_srgb_to_linear_gamma ());
linearToSrgb = new SKColorFilterStatic (SkiaApi.sk_colorfilter_new_linear_to_srgb_gamma ());
}

internal static void EnsureStaticInstanceAreInitialized ()
{
// IMPORTANT: do not remove to ensure that the static instances
// are initialized before any access is made to them
}

internal SKColorFilter(IntPtr handle, bool owns)
: base (handle, owns)
{
Expand All @@ -17,6 +37,10 @@ internal SKColorFilter(IntPtr handle, bool owns)
protected override void Dispose (bool disposing) =>
base.Dispose (disposing);

public static SKColorFilter CreateSrgbToLinearGamma() => srgbToLinear;

public static SKColorFilter CreateLinearToSrgbGamma() => linearToSrgb;

public static SKColorFilter CreateBlendMode(SKColor c, SKBlendMode mode)
{
return GetObject (SkiaApi.sk_colorfilter_new_mode((uint)c, mode));
Expand All @@ -36,6 +60,14 @@ public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inn
return GetObject (SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle));
}

public static SKColorFilter CreateLerp(float weight, SKColorFilter filter0, SKColorFilter filter1)
{
_ = filter0 ?? throw new ArgumentNullException(nameof(filter0));
_ = filter1 ?? throw new ArgumentNullException(nameof(filter1));

return GetObject (SkiaApi.sk_colorfilter_new_lerp(weight, filter0.Handle, filter1.Handle));
}

public static SKColorFilter CreateColorMatrix(float[] matrix)
{
if (matrix == null)
Expand All @@ -52,6 +84,15 @@ public static SKColorFilter CreateColorMatrix(ReadOnlySpan<float> matrix)
}
}

public static SKColorFilter CreateHslaColorMatrix(ReadOnlySpan<float> matrix)
{
if (matrix.Length != 20)
throw new ArgumentException("Matrix must have a length of 20.", nameof(matrix));
fixed (float* m = matrix) {
return GetObject (SkiaApi.sk_colorfilter_new_hsla_matrix (m));
}
}

public static SKColorFilter CreateLumaColor()
{
return GetObject (SkiaApi.sk_colorfilter_new_luma_color());
Expand Down Expand Up @@ -117,5 +158,15 @@ public static SKColorFilter CreateHighContrast(bool grayscale, SKHighContrastCon

internal static SKColorFilter GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKColorFilter (h, o));

private sealed class SKColorFilterStatic : SKColorFilter
{
internal SKColorFilterStatic (IntPtr x)
: base (x, false)
{
}

protected override void Dispose (bool disposing) { }
}
}
}
1 change: 1 addition & 0 deletions binding/SkiaSharp/SKObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static SKObject ()
SKFontManager.EnsureStaticInstanceAreInitialized ();
SKTypeface.EnsureStaticInstanceAreInitialized ();
SKBlender.EnsureStaticInstanceAreInitialized ();
SKColorFilter.EnsureStaticInstanceAreInitialized ();
}

internal SKObject (IntPtr handle, bool owns)
Expand Down
76 changes: 76 additions & 0 deletions binding/SkiaSharp/SkiaApi.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3827,6 +3827,44 @@ internal static sk_colorfilter_t sk_colorfilter_new_high_contrast (SKHighContras
(sk_colorfilter_new_high_contrast_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_high_contrast> ("sk_colorfilter_new_high_contrast")).Invoke (config);
#endif

// sk_colorfilter_t* sk_colorfilter_new_hsla_matrix(const float[20] array = 20)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
}
private static Delegates.sk_colorfilter_new_hsla_matrix sk_colorfilter_new_hsla_matrix_delegate;
internal static sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array) =>
(sk_colorfilter_new_hsla_matrix_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_hsla_matrix> ("sk_colorfilter_new_hsla_matrix")).Invoke (array);
#endif

// sk_colorfilter_t* sk_colorfilter_new_lerp(float weight, sk_colorfilter_t* filter0, sk_colorfilter_t* filter1)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
}
private static Delegates.sk_colorfilter_new_lerp sk_colorfilter_new_lerp_delegate;
internal static sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1) =>
(sk_colorfilter_new_lerp_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_lerp> ("sk_colorfilter_new_lerp")).Invoke (weight, filter0, filter1);
#endif

// sk_colorfilter_t* sk_colorfilter_new_lighting(sk_color_t mul, sk_color_t add)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
Expand All @@ -3846,6 +3884,25 @@ internal static sk_colorfilter_t sk_colorfilter_new_lighting (UInt32 mul, UInt32
(sk_colorfilter_new_lighting_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_lighting> ("sk_colorfilter_new_lighting")).Invoke (mul, add);
#endif

// sk_colorfilter_t* sk_colorfilter_new_linear_to_srgb_gamma()
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
}
private static Delegates.sk_colorfilter_new_linear_to_srgb_gamma sk_colorfilter_new_linear_to_srgb_gamma_delegate;
internal static sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma () =>
(sk_colorfilter_new_linear_to_srgb_gamma_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_linear_to_srgb_gamma> ("sk_colorfilter_new_linear_to_srgb_gamma")).Invoke ();
#endif

// sk_colorfilter_t* sk_colorfilter_new_luma_color()
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
Expand Down Expand Up @@ -3884,6 +3941,25 @@ internal static sk_colorfilter_t sk_colorfilter_new_mode (UInt32 c, SKBlendMode
(sk_colorfilter_new_mode_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_mode> ("sk_colorfilter_new_mode")).Invoke (c, mode);
#endif

// sk_colorfilter_t* sk_colorfilter_new_srgb_to_linear_gamma()
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
}
private static Delegates.sk_colorfilter_new_srgb_to_linear_gamma sk_colorfilter_new_srgb_to_linear_gamma_delegate;
internal static sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma () =>
(sk_colorfilter_new_srgb_to_linear_gamma_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_srgb_to_linear_gamma> ("sk_colorfilter_new_srgb_to_linear_gamma")).Invoke ();
#endif

// sk_colorfilter_t* sk_colorfilter_new_table(const uint8_t[256] table = 256)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
Expand Down
2 changes: 1 addition & 1 deletion externals/skia
1 change: 1 addition & 0 deletions tests/Tests/GarbageCleanupFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class GarbageCleanupFixture : IDisposable
"SkiaSharp.SKFontStyle+SKFontStyleStatic",
"SkiaSharp.SKTypeface+SKTypefaceStatic",
"SkiaSharp.SKColorSpace+SKColorSpaceStatic",
"SkiaSharp.SKColorFilter+SKColorFilterStatic",
"SkiaSharp.SKBlender+SKBlenderStatic",
};

Expand Down
58 changes: 58 additions & 0 deletions tests/Tests/SkiaSharp/SKColorFilterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Linq;
using Xunit;

namespace SkiaSharp.Tests
{
public class SKColorFilterTest : SKTest
{
[SkippableFact]
public void StaticSrgbToLinearIsReturnedAsTheStaticInstance()
{
var handle = SkiaApi.sk_colorfilter_new_srgb_to_linear_gamma();
try
{
var cs = SKColorFilter.GetObject(handle);
Assert.Equal("SKColorFilterStatic", cs.GetType().Name);
}
finally
{
SkiaApi.sk_refcnt_safe_unref(handle);
}
}

[SkippableFact]
public void StaticLinearToSrgbIsReturnedAsTheStaticInstance()
{
var handle = SkiaApi.sk_colorfilter_new_linear_to_srgb_gamma();
try
{
var cs = SKColorFilter.GetObject(handle);
Assert.Equal("SKColorFilterStatic", cs.GetType().Name);
}
finally
{
SkiaApi.sk_refcnt_safe_unref(handle);
}
}

[SkippableTheory]
[InlineData(-1, 0)]
[InlineData(-0.5f, 0)]
[InlineData(0, 0)]
[InlineData(0.5f, -1)]
[InlineData(1, 1)]
[InlineData(1.5f, 1)]
public void LerpReturnsCorrectFilter(float weight, int returned)
{
var first = SKColorFilter.CreateBlendMode(SKColors.Red, SKBlendMode.SrcOver);
var second = SKColorFilter.CreateBlendMode(SKColors.Blue, SKBlendMode.SrcOver);
var filters = new[] { first, second };

var lerp = SKColorFilter.CreateLerp(weight, first, second);

Assert.Equal(returned, Array.IndexOf(filters, lerp));
}
}
}