Skip to content

Commit aa4f2ff

Browse files
authored
Expose SKBlender (#2830)
1 parent a0f3767 commit aa4f2ff

File tree

18 files changed

+567
-2
lines changed

18 files changed

+567
-2
lines changed

binding/SkiaSharp.Resources/ResourcesApi.generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using gr_vk_memory_allocator_t = System.IntPtr;
1919
using gr_vkinterface_t = System.IntPtr;
2020
using sk_bitmap_t = System.IntPtr;
21+
using sk_blender_t = System.IntPtr;
2122
using sk_canvas_t = System.IntPtr;
2223
using sk_codec_t = System.IntPtr;
2324
using sk_colorfilter_t = System.IntPtr;

binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using gr_vk_memory_allocator_t = System.IntPtr;
1919
using gr_vkinterface_t = System.IntPtr;
2020
using sk_bitmap_t = System.IntPtr;
21+
using sk_blender_t = System.IntPtr;
2122
using sk_canvas_t = System.IntPtr;
2223
using sk_codec_t = System.IntPtr;
2324
using sk_colorfilter_t = System.IntPtr;

binding/SkiaSharp.Skottie/SkottieApi.generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using gr_vk_memory_allocator_t = System.IntPtr;
1919
using gr_vkinterface_t = System.IntPtr;
2020
using sk_bitmap_t = System.IntPtr;
21+
using sk_blender_t = System.IntPtr;
2122
using sk_canvas_t = System.IntPtr;
2223
using sk_codec_t = System.IntPtr;
2324
using sk_colorfilter_t = System.IntPtr;

binding/SkiaSharp/SKBlender.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace SkiaSharp;
5+
6+
public unsafe class SKBlender : SKObject, ISKReferenceCounted
7+
{
8+
private static readonly Dictionary<SKBlendMode, SKBlender> blendModeBlenders;
9+
10+
static SKBlender ()
11+
{
12+
// TODO: This is not the best way to do this as it will create a lot of objects that
13+
// might not be needed, but it is the only way to ensure that the static
14+
// instances are created before any access is made to them.
15+
// See more info: SKObject.EnsureStaticInstanceAreInitialized()
16+
17+
var modes = Enum.GetValues (typeof (SKBlendMode));
18+
blendModeBlenders = new Dictionary<SKBlendMode, SKBlender> (modes.Length);
19+
foreach (SKBlendMode mode in modes)
20+
{
21+
blendModeBlenders [mode] = new SKBlenderStatic (SkiaApi.sk_blender_new_mode (mode));
22+
}
23+
}
24+
25+
internal static void EnsureStaticInstanceAreInitialized ()
26+
{
27+
// IMPORTANT: do not remove to ensure that the static instances
28+
// are initialized before any access is made to them
29+
}
30+
31+
internal SKBlender(IntPtr handle, bool owns)
32+
: base (handle, owns)
33+
{
34+
}
35+
36+
protected override void Dispose (bool disposing) =>
37+
base.Dispose (disposing);
38+
39+
public static SKBlender CreateBlendMode (SKBlendMode mode)
40+
{
41+
if (!blendModeBlenders.TryGetValue (mode, out var value))
42+
throw new ArgumentOutOfRangeException (nameof (mode));
43+
return value;
44+
}
45+
46+
public static SKBlender CreateArithmetic (float k1, float k2, float k3, float k4, bool enforcePMColor) =>
47+
GetObject (SkiaApi.sk_blender_new_arithmetic (k1, k2, k3, k4, enforcePMColor));
48+
49+
internal static SKBlender GetObject (IntPtr handle) =>
50+
GetOrAddObject (handle, (h, o) => new SKBlender (h, o));
51+
52+
//
53+
54+
private sealed class SKBlenderStatic : SKBlender
55+
{
56+
internal SKBlenderStatic (IntPtr x)
57+
: base (x, false)
58+
{
59+
}
60+
61+
protected override void Dispose (bool disposing) { }
62+
}
63+
}

binding/SkiaSharp/SKColorSpace.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public unsafe class SKColorSpace : SKObject, ISKNonVirtualReferenceCounted
1212

1313
static SKColorSpace ()
1414
{
15+
// TODO: This is not the best way to do this as it will create a lot of objects that
16+
// might not be needed, but it is the only way to ensure that the static
17+
// instances are created before any access is made to them.
18+
// See more info: SKObject.EnsureStaticInstanceAreInitialized()
19+
1520
srgb = new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb ());
1621
srgbLinear = new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb_linear ());
1722
}

binding/SkiaSharp/SKData.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public unsafe class SKData : SKObject, ISKNonVirtualReferenceCounted
1919

2020
static SKData ()
2121
{
22+
// TODO: This is not the best way to do this as it will create a lot of objects that
23+
// might not be needed, but it is the only way to ensure that the static
24+
// instances are created before any access is made to them.
25+
// See more info: SKObject.EnsureStaticInstanceAreInitialized()
26+
2227
empty = new SKDataStatic (SkiaApi.sk_data_new_empty ());
2328
}
2429

binding/SkiaSharp/SKFontManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public unsafe class SKFontManager : SKObject, ISKReferenceCounted
1414

1515
static SKFontManager ()
1616
{
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+
1722
defaultManager = new SKFontManagerStatic (SkiaApi.sk_fontmgr_ref_default ());
1823
}
1924

binding/SkiaSharp/SKImageFilter.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,23 @@ public static SKImageFilter CreateBlendMode (SKBlendMode mode, SKImageFilter? ba
341341
private static SKImageFilter CreateBlendMode (SKBlendMode mode, SKImageFilter? background, SKImageFilter? foreground, SKRect* cropRect) =>
342342
GetObject (SkiaApi.sk_imagefilter_new_blend (mode, background?.Handle ?? IntPtr.Zero, foreground?.Handle ?? IntPtr.Zero, cropRect));
343343

344+
// CreateBlendMode (Blender)
345+
346+
public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background) =>
347+
CreateBlendMode (blender, background, null, null);
348+
349+
public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground) =>
350+
CreateBlendMode (blender, background, foreground, null);
351+
352+
public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground, SKRect cropRect) =>
353+
CreateBlendMode (blender, background, foreground, &cropRect);
354+
355+
private static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground, SKRect* cropRect)
356+
{
357+
_ = blender ?? throw new ArgumentNullException (nameof (blender));
358+
return GetObject (SkiaApi.sk_imagefilter_new_blender (blender.Handle, background?.Handle ?? IntPtr.Zero, foreground?.Handle ?? IntPtr.Zero, cropRect));
359+
}
360+
344361
// CreateArithmetic
345362

346363
public static SKImageFilter CreateArithmetic (float k1, float k2, float k3, float k4, bool enforcePMColor, SKImageFilter? background) =>

binding/SkiaSharp/SKObject.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static SKObject ()
4444
SKData.EnsureStaticInstanceAreInitialized ();
4545
SKFontManager.EnsureStaticInstanceAreInitialized ();
4646
SKTypeface.EnsureStaticInstanceAreInitialized ();
47+
SKBlender.EnsureStaticInstanceAreInitialized ();
4748
}
4849

4950
internal SKObject (IntPtr handle, bool owns)

binding/SkiaSharp/SKPaint.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ public SKBlendMode BlendMode {
203203
set => SkiaApi.sk_paint_set_blendmode (Handle, value);
204204
}
205205

206+
public SKBlender Blender {
207+
get => SKBlender.GetObject (SkiaApi.sk_paint_get_blender (Handle));
208+
set => SkiaApi.sk_paint_set_blender (Handle, value == null ? IntPtr.Zero : value.Handle);
209+
}
210+
206211
[Obsolete ($"Use {nameof (SKSamplingOptions)} instead.")]
207212
public SKFilterQuality FilterQuality {
208213
get => (SKFilterQuality)SkiaApi.sk_compatpaint_get_filter_quality (Handle);

binding/SkiaSharp/SKRuntimeEffect.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ public static SKRuntimeEffect CreateColorFilter (string sksl, out string errors)
4141
return effect;
4242
}
4343

44+
public static SKRuntimeEffect CreateBlender (string sksl, out string errors)
45+
{
46+
using var s = new SKString (sksl);
47+
using var errorString = new SKString ();
48+
var effect = GetObject (SkiaApi.sk_runtimeeffect_make_for_blender (s.Handle, errorString.Handle));
49+
errors = errorString?.ToString ();
50+
if (errors?.Length == 0)
51+
errors = null;
52+
return effect;
53+
}
54+
4455
// Build*
4556

4657
public static SKRuntimeShaderBuilder BuildShader (string sksl)
@@ -57,6 +68,13 @@ public static SKRuntimeColorFilterBuilder BuildColorFilter (string sksl)
5768
return new SKRuntimeColorFilterBuilder (effect);
5869
}
5970

71+
public static SKRuntimeBlenderBuilder BuildBlender (string sksl)
72+
{
73+
var effect = CreateBlender (sksl, out var errors);
74+
ValidateResult (effect, errors);
75+
return new SKRuntimeBlenderBuilder (effect);
76+
}
77+
6078
private static void ValidateResult (SKRuntimeEffect effect, string errors)
6179
{
6280
if (effect is null) {
@@ -148,6 +166,30 @@ private SKColorFilter ToColorFilter (SKData uniforms, SKObject[] children)
148166
}
149167
}
150168

169+
// ToBlender
170+
171+
public SKBlender ToBlender () =>
172+
ToBlender ((SKData)null, null);
173+
174+
public SKBlender ToBlender (SKRuntimeEffectUniforms uniforms) =>
175+
ToBlender (uniforms.ToData (), null);
176+
177+
private SKBlender ToBlender (SKData uniforms) =>
178+
ToBlender (uniforms, null);
179+
180+
public SKBlender ToBlender (SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) =>
181+
ToBlender (uniforms.ToData (), children.ToArray ());
182+
183+
private SKBlender ToBlender (SKData uniforms, SKObject[] children)
184+
{
185+
var uniformsHandle = uniforms?.Handle ?? IntPtr.Zero;
186+
using var childrenHandles = Utils.RentHandlesArray (children, true);
187+
188+
fixed (IntPtr* ch = childrenHandles) {
189+
return SKBlender.GetObject (SkiaApi.sk_runtimeeffect_make_blender (Handle, uniformsHandle, ch, (IntPtr)childrenHandles.Length));
190+
}
191+
}
192+
151193
//
152194

153195
internal static SKRuntimeEffect GetObject (IntPtr handle) =>
@@ -560,15 +602,24 @@ public SKRuntimeEffectChild (SKColorFilter colorFilter)
560602
value = colorFilter;
561603
}
562604

605+
public SKRuntimeEffectChild (SKBlender blender)
606+
{
607+
value = blender;
608+
}
609+
563610
public SKObject Value => value;
564611

565612
public SKShader Shader => value as SKShader;
566613

567614
public SKColorFilter ColorFilter => value as SKColorFilter;
568615

616+
public SKBlender Blender => value as SKBlender;
617+
569618
public static implicit operator SKRuntimeEffectChild (SKShader shader) => new (shader);
570619

571620
public static implicit operator SKRuntimeEffectChild (SKColorFilter colorFilter) => new (colorFilter);
621+
622+
public static implicit operator SKRuntimeEffectChild (SKBlender blender) => new (blender);
572623
}
573624

574625
public class SKRuntimeEffectBuilderException : ApplicationException
@@ -627,4 +678,15 @@ public SKRuntimeColorFilterBuilder (SKRuntimeEffect effect)
627678
public SKColorFilter Build () =>
628679
Effect.ToColorFilter (Uniforms, Children);
629680
}
681+
682+
public class SKRuntimeBlenderBuilder : SKRuntimeEffectBuilder
683+
{
684+
public SKRuntimeBlenderBuilder (SKRuntimeEffect effect)
685+
: base (effect)
686+
{
687+
}
688+
689+
public SKBlender Build () =>
690+
Effect.ToBlender (Uniforms, Children);
691+
}
630692
}

binding/SkiaSharp/SKShader.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,23 @@ public static SKShader CreateCompose (SKShader shaderA, SKShader shaderB, SKBlen
408408
return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle));
409409
}
410410

411+
// CreateBlend
412+
413+
public static SKShader CreateBlend (SKBlendMode mode, SKShader shaderA, SKShader shaderB)
414+
{
415+
_ = shaderA ?? throw new ArgumentNullException (nameof (shaderA));
416+
_ = shaderB ?? throw new ArgumentNullException (nameof (shaderB));
417+
return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle));
418+
}
419+
420+
public static SKShader CreateBlend (SKBlender blender, SKShader shaderA, SKShader shaderB)
421+
{
422+
_ = shaderA ?? throw new ArgumentNullException (nameof (shaderA));
423+
_ = shaderB ?? throw new ArgumentNullException (nameof (shaderB));
424+
_ = blender ?? throw new ArgumentNullException (nameof (blender));
425+
return GetObject (SkiaApi.sk_shader_new_blender (blender.Handle, shaderA.Handle, shaderB.Handle));
426+
}
427+
411428
// CreateColorFilter
412429

413430
public static SKShader CreateColorFilter (SKShader shader, SKColorFilter filter)

binding/SkiaSharp/SKTypeface.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public unsafe class SKTypeface : SKObject, ISKReferenceCounted
1414

1515
static SKTypeface ()
1616
{
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+
1722
defaultTypeface = new SKTypefaceStatic (SkiaApi.sk_typeface_ref_default ());
1823
}
1924

0 commit comments

Comments
 (0)