Skip to content

Commit a8f74f1

Browse files
authored
Add the missing SKColorFilter types (#2882)
1 parent b3cf651 commit a8f74f1

File tree

7 files changed

+202
-7
lines changed

7 files changed

+202
-7
lines changed

binding/SkiaSharp/SKColorFilter.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@ public unsafe class SKColorFilter : SKObject, ISKReferenceCounted
99
public const int ColorMatrixSize = 20;
1010
public const int TableMaxLength = 256;
1111

12+
private static readonly SKColorFilter srgbToLinear;
13+
private static readonly SKColorFilter linearToSrgb;
14+
15+
static SKColorFilter ()
16+
{
17+
// TODO: This is not the best way to do this as it will create a lot of objects that
18+
// might not be needed, but it is the only way to ensure that the static
19+
// instances are created before any access is made to them.
20+
// See more info: SKObject.EnsureStaticInstanceAreInitialized()
21+
22+
srgbToLinear = new SKColorFilterStatic (SkiaApi.sk_colorfilter_new_srgb_to_linear_gamma ());
23+
linearToSrgb = new SKColorFilterStatic (SkiaApi.sk_colorfilter_new_linear_to_srgb_gamma ());
24+
}
25+
26+
internal static void EnsureStaticInstanceAreInitialized ()
27+
{
28+
// IMPORTANT: do not remove to ensure that the static instances
29+
// are initialized before any access is made to them
30+
}
31+
1232
internal SKColorFilter(IntPtr handle, bool owns)
1333
: base (handle, owns)
1434
{
@@ -17,6 +37,10 @@ internal SKColorFilter(IntPtr handle, bool owns)
1737
protected override void Dispose (bool disposing) =>
1838
base.Dispose (disposing);
1939

40+
public static SKColorFilter CreateSrgbToLinearGamma() => srgbToLinear;
41+
42+
public static SKColorFilter CreateLinearToSrgbGamma() => linearToSrgb;
43+
2044
public static SKColorFilter CreateBlendMode(SKColor c, SKBlendMode mode)
2145
{
2246
return GetObject (SkiaApi.sk_colorfilter_new_mode((uint)c, mode));
@@ -36,6 +60,14 @@ public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inn
3660
return GetObject (SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle));
3761
}
3862

63+
public static SKColorFilter CreateLerp(float weight, SKColorFilter filter0, SKColorFilter filter1)
64+
{
65+
_ = filter0 ?? throw new ArgumentNullException(nameof(filter0));
66+
_ = filter1 ?? throw new ArgumentNullException(nameof(filter1));
67+
68+
return GetObject (SkiaApi.sk_colorfilter_new_lerp(weight, filter0.Handle, filter1.Handle));
69+
}
70+
3971
public static SKColorFilter CreateColorMatrix(float[] matrix)
4072
{
4173
if (matrix == null)
@@ -52,6 +84,15 @@ public static SKColorFilter CreateColorMatrix(ReadOnlySpan<float> matrix)
5284
}
5385
}
5486

87+
public static SKColorFilter CreateHslaColorMatrix(ReadOnlySpan<float> matrix)
88+
{
89+
if (matrix.Length != 20)
90+
throw new ArgumentException("Matrix must have a length of 20.", nameof(matrix));
91+
fixed (float* m = matrix) {
92+
return GetObject (SkiaApi.sk_colorfilter_new_hsla_matrix (m));
93+
}
94+
}
95+
5596
public static SKColorFilter CreateLumaColor()
5697
{
5798
return GetObject (SkiaApi.sk_colorfilter_new_luma_color());
@@ -117,5 +158,15 @@ public static SKColorFilter CreateHighContrast(bool grayscale, SKHighContrastCon
117158

118159
internal static SKColorFilter GetObject (IntPtr handle) =>
119160
GetOrAddObject (handle, (h, o) => new SKColorFilter (h, o));
161+
162+
private sealed class SKColorFilterStatic : SKColorFilter
163+
{
164+
internal SKColorFilterStatic (IntPtr x)
165+
: base (x, false)
166+
{
167+
}
168+
169+
protected override void Dispose (bool disposing) { }
170+
}
120171
}
121172
}

binding/SkiaSharp/SKObject.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static SKObject ()
4545
SKFontManager.EnsureStaticInstanceAreInitialized ();
4646
SKTypeface.EnsureStaticInstanceAreInitialized ();
4747
SKBlender.EnsureStaticInstanceAreInitialized ();
48+
SKColorFilter.EnsureStaticInstanceAreInitialized ();
4849
}
4950

5051
internal SKObject (IntPtr handle, bool owns)

binding/SkiaSharp/SkiaApi.generated.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3865,6 +3865,44 @@ internal static sk_colorfilter_t sk_colorfilter_new_high_contrast (SKHighContras
38653865
(sk_colorfilter_new_high_contrast_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_high_contrast> ("sk_colorfilter_new_high_contrast")).Invoke (config);
38663866
#endif
38673867

3868+
// sk_colorfilter_t* sk_colorfilter_new_hsla_matrix(const float[20] array = 20)
3869+
#if !USE_DELEGATES
3870+
#if USE_LIBRARY_IMPORT
3871+
[LibraryImport (SKIA)]
3872+
internal static partial sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
3873+
#else // !USE_LIBRARY_IMPORT
3874+
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
3875+
internal static extern sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
3876+
#endif
3877+
#else
3878+
private partial class Delegates {
3879+
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
3880+
internal delegate sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array);
3881+
}
3882+
private static Delegates.sk_colorfilter_new_hsla_matrix sk_colorfilter_new_hsla_matrix_delegate;
3883+
internal static sk_colorfilter_t sk_colorfilter_new_hsla_matrix (Single* array) =>
3884+
(sk_colorfilter_new_hsla_matrix_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_hsla_matrix> ("sk_colorfilter_new_hsla_matrix")).Invoke (array);
3885+
#endif
3886+
3887+
// sk_colorfilter_t* sk_colorfilter_new_lerp(float weight, sk_colorfilter_t* filter0, sk_colorfilter_t* filter1)
3888+
#if !USE_DELEGATES
3889+
#if USE_LIBRARY_IMPORT
3890+
[LibraryImport (SKIA)]
3891+
internal static partial sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
3892+
#else // !USE_LIBRARY_IMPORT
3893+
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
3894+
internal static extern sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
3895+
#endif
3896+
#else
3897+
private partial class Delegates {
3898+
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
3899+
internal delegate sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1);
3900+
}
3901+
private static Delegates.sk_colorfilter_new_lerp sk_colorfilter_new_lerp_delegate;
3902+
internal static sk_colorfilter_t sk_colorfilter_new_lerp (Single weight, sk_colorfilter_t filter0, sk_colorfilter_t filter1) =>
3903+
(sk_colorfilter_new_lerp_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_lerp> ("sk_colorfilter_new_lerp")).Invoke (weight, filter0, filter1);
3904+
#endif
3905+
38683906
// sk_colorfilter_t* sk_colorfilter_new_lighting(sk_color_t mul, sk_color_t add)
38693907
#if !USE_DELEGATES
38703908
#if USE_LIBRARY_IMPORT
@@ -3884,6 +3922,25 @@ internal static sk_colorfilter_t sk_colorfilter_new_lighting (UInt32 mul, UInt32
38843922
(sk_colorfilter_new_lighting_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_lighting> ("sk_colorfilter_new_lighting")).Invoke (mul, add);
38853923
#endif
38863924

3925+
// sk_colorfilter_t* sk_colorfilter_new_linear_to_srgb_gamma()
3926+
#if !USE_DELEGATES
3927+
#if USE_LIBRARY_IMPORT
3928+
[LibraryImport (SKIA)]
3929+
internal static partial sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
3930+
#else // !USE_LIBRARY_IMPORT
3931+
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
3932+
internal static extern sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
3933+
#endif
3934+
#else
3935+
private partial class Delegates {
3936+
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
3937+
internal delegate sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma ();
3938+
}
3939+
private static Delegates.sk_colorfilter_new_linear_to_srgb_gamma sk_colorfilter_new_linear_to_srgb_gamma_delegate;
3940+
internal static sk_colorfilter_t sk_colorfilter_new_linear_to_srgb_gamma () =>
3941+
(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 ();
3942+
#endif
3943+
38873944
// sk_colorfilter_t* sk_colorfilter_new_luma_color()
38883945
#if !USE_DELEGATES
38893946
#if USE_LIBRARY_IMPORT
@@ -3922,6 +3979,25 @@ internal static sk_colorfilter_t sk_colorfilter_new_mode (UInt32 c, SKBlendMode
39223979
(sk_colorfilter_new_mode_delegate ??= GetSymbol<Delegates.sk_colorfilter_new_mode> ("sk_colorfilter_new_mode")).Invoke (c, mode);
39233980
#endif
39243981

3982+
// sk_colorfilter_t* sk_colorfilter_new_srgb_to_linear_gamma()
3983+
#if !USE_DELEGATES
3984+
#if USE_LIBRARY_IMPORT
3985+
[LibraryImport (SKIA)]
3986+
internal static partial sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
3987+
#else // !USE_LIBRARY_IMPORT
3988+
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
3989+
internal static extern sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
3990+
#endif
3991+
#else
3992+
private partial class Delegates {
3993+
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
3994+
internal delegate sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma ();
3995+
}
3996+
private static Delegates.sk_colorfilter_new_srgb_to_linear_gamma sk_colorfilter_new_srgb_to_linear_gamma_delegate;
3997+
internal static sk_colorfilter_t sk_colorfilter_new_srgb_to_linear_gamma () =>
3998+
(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 ();
3999+
#endif
4000+
39254001
// sk_colorfilter_t* sk_colorfilter_new_table(const uint8_t[256] table = 256)
39264002
#if !USE_DELEGATES
39274003
#if USE_LIBRARY_IMPORT

tests/Tests/GarbageCleanupFixture.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class GarbageCleanupFixture : IDisposable
1616
"SkiaSharp.SKFontStyle+SKFontStyleStatic",
1717
"SkiaSharp.SKTypeface+SKTypefaceStatic",
1818
"SkiaSharp.SKColorSpace+SKColorSpaceStatic",
19+
"SkiaSharp.SKColorFilter+SKColorFilterStatic",
1920
"SkiaSharp.SKBlender+SKBlenderStatic",
2021
};
2122

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace SkiaSharp.Tests
7+
{
8+
public class SKColorFilterTest : SKTest
9+
{
10+
[SkippableFact]
11+
public void StaticSrgbToLinearIsReturnedAsTheStaticInstance()
12+
{
13+
var handle = SkiaApi.sk_colorfilter_new_srgb_to_linear_gamma();
14+
try
15+
{
16+
var cs = SKColorFilter.GetObject(handle);
17+
Assert.Equal("SKColorFilterStatic", cs.GetType().Name);
18+
}
19+
finally
20+
{
21+
SkiaApi.sk_refcnt_safe_unref(handle);
22+
}
23+
}
24+
25+
[SkippableFact]
26+
public void StaticLinearToSrgbIsReturnedAsTheStaticInstance()
27+
{
28+
var handle = SkiaApi.sk_colorfilter_new_linear_to_srgb_gamma();
29+
try
30+
{
31+
var cs = SKColorFilter.GetObject(handle);
32+
Assert.Equal("SKColorFilterStatic", cs.GetType().Name);
33+
}
34+
finally
35+
{
36+
SkiaApi.sk_refcnt_safe_unref(handle);
37+
}
38+
}
39+
40+
[SkippableTheory]
41+
[InlineData(-1, 0)]
42+
[InlineData(-0.5f, 0)]
43+
[InlineData(0, 0)]
44+
[InlineData(0.5f, -1)]
45+
[InlineData(1, 1)]
46+
[InlineData(1.5f, 1)]
47+
public void LerpReturnsCorrectFilter(float weight, int returned)
48+
{
49+
var first = SKColorFilter.CreateBlendMode(SKColors.Red, SKBlendMode.SrcOver);
50+
var second = SKColorFilter.CreateBlendMode(SKColors.Blue, SKBlendMode.SrcOver);
51+
var filters = new[] { first, second };
52+
53+
var lerp = SKColorFilter.CreateLerp(weight, first, second);
54+
55+
Assert.Equal(returned, Array.IndexOf(filters, lerp));
56+
}
57+
}
58+
}

tests/Tests/SkiaSharp/SKColorSpaceTest.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,32 +295,40 @@ public void LinearSrgbColorSpaceIsCorrect()
295295
[SkippableFact]
296296
public void SameColorSpaceCreatedDifferentWaysAreTheSameObject()
297297
{
298+
// the instance is static, so all instances in .NET are the same instance
299+
const int NativeInstanceCount = 4;
300+
301+
// get the first instance of the sRGB Linear
298302
var colorspace1 = SKColorSpace.CreateSrgbLinear();
299303
Assert.Equal("SkiaSharp.SKColorSpace+SKColorSpaceStatic", colorspace1.GetType().FullName);
300-
Assert.Equal(2, colorspace1.GetReferenceCount());
304+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
301305

306+
// create a new one with the same parameters, which will return the same instance
302307
var colorspace2 = SKColorSpace.CreateRgb(SKColorSpaceTransferFn.Linear, SKColorSpaceXyz.Srgb);
303308
Assert.Equal("SkiaSharp.SKColorSpace+SKColorSpaceStatic", colorspace2.GetType().FullName);
304-
Assert.Equal(2, colorspace2.GetReferenceCount());
305-
306309
Assert.Same(colorspace1, colorspace2);
310+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
311+
Assert.Equal(NativeInstanceCount, colorspace2.GetReferenceCount());
307312

313+
// create a different one manually, which will return a new instance
308314
var colorspace3 = SKColorSpace.CreateRgb(
309315
new SKColorSpaceTransferFn { A = 0.6f, B = 0.5f, C = 0.4f, D = 0.3f, E = 0.2f, F = 0.1f },
310316
SKColorSpaceXyz.Identity);
311317
Assert.NotSame(colorspace1, colorspace3);
318+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
319+
Assert.Equal(NativeInstanceCount, colorspace2.GetReferenceCount());
312320

313321
colorspace3.Dispose();
314322
Assert.True(colorspace3.IsDisposed);
315-
Assert.Equal(2, colorspace1.GetReferenceCount());
323+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
316324

317325
colorspace2.Dispose();
318326
Assert.False(colorspace2.IsDisposed);
319-
Assert.Equal(2, colorspace1.GetReferenceCount());
327+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
320328

321329
colorspace1.Dispose();
322330
Assert.False(colorspace1.IsDisposed);
323-
Assert.Equal(2, colorspace1.GetReferenceCount());
331+
Assert.Equal(NativeInstanceCount, colorspace1.GetReferenceCount());
324332
}
325333

326334
private static void AssertMatrix(float[] expected, SKMatrix44 actual)

0 commit comments

Comments
 (0)