diff --git a/gn/core.gni b/gn/core.gni index 830fb6c67fc8..2f47784c2676 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -151,6 +151,7 @@ skia_core_public = [ # //src/text:text_srcs skia_core_sources = [ "$_include/c/sk_bitmap.h", + "$_include/c/sk_blender.h", "$_include/c/sk_canvas.h", "$_include/c/sk_codec.h", "$_include/c/sk_colorfilter.h", @@ -184,6 +185,7 @@ skia_core_sources = [ "$_include/c/sk_vertices.h", "$_include/c/gr_context.h", "$_src/c/sk_bitmap.cpp", + "$_src/c/sk_blender.cpp", "$_src/c/sk_canvas.cpp", "$_src/c/sk_codec.cpp", "$_src/c/sk_colorfilter.cpp", diff --git a/include/c/sk_blender.h b/include/c/sk_blender.h new file mode 100644 index 000000000000..1544e63ffb35 --- /dev/null +++ b/include/c/sk_blender.h @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef sk_blender_DEFINED +#define sk_blender_DEFINED + +#include "include/c/sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +SK_C_API void sk_blender_ref(sk_blender_t* blender); +SK_C_API void sk_blender_unref(sk_blender_t* blender); +SK_C_API sk_blender_t* sk_blender_new_mode(sk_blendmode_t mode); +SK_C_API sk_blender_t* sk_blender_new_arithmetic(float k1, float k2, float k3, float k4, bool enforcePremul); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/include/c/sk_imagefilter.h b/include/c/sk_imagefilter.h index f56dcd908c7d..528250a4bc79 100644 --- a/include/c/sk_imagefilter.h +++ b/include/c/sk_imagefilter.h @@ -20,6 +20,7 @@ SK_C_PLUS_PLUS_BEGIN_GUARD SK_C_API void sk_imagefilter_unref(sk_imagefilter_t* cfilter); SK_C_API sk_imagefilter_t* sk_imagefilter_new_arithmetic(float k1, float k2, float k3, float k4, bool enforcePMColor, const sk_imagefilter_t* background, const sk_imagefilter_t* foreground, const sk_rect_t* cropRect); SK_C_API sk_imagefilter_t* sk_imagefilter_new_blend(sk_blendmode_t mode, const sk_imagefilter_t* background, const sk_imagefilter_t* foreground, const sk_rect_t* cropRect); +SK_C_API sk_imagefilter_t* sk_imagefilter_new_blender(sk_blender_t* blender, const sk_imagefilter_t* background, const sk_imagefilter_t* foreground, const sk_rect_t* cropRect); SK_C_API sk_imagefilter_t* sk_imagefilter_new_blur(float sigmaX, float sigmaY, sk_shader_tilemode_t tileMode, const sk_imagefilter_t* input, const sk_rect_t* cropRect); SK_C_API sk_imagefilter_t* sk_imagefilter_new_color_filter(sk_colorfilter_t* cf, const sk_imagefilter_t* input, const sk_rect_t* cropRect); SK_C_API sk_imagefilter_t* sk_imagefilter_new_compose(const sk_imagefilter_t* outer, const sk_imagefilter_t* inner); diff --git a/include/c/sk_paint.h b/include/c/sk_paint.h index 5de94f536a85..feda20b2b24d 100644 --- a/include/c/sk_paint.h +++ b/include/c/sk_paint.h @@ -37,6 +37,7 @@ SK_C_API void sk_paint_set_stroke_join(sk_paint_t*, sk_stroke_join_t); SK_C_API void sk_paint_set_shader(sk_paint_t*, sk_shader_t*); SK_C_API void sk_paint_set_maskfilter(sk_paint_t*, sk_maskfilter_t*); SK_C_API void sk_paint_set_blendmode(sk_paint_t*, sk_blendmode_t); +SK_C_API void sk_paint_set_blender(sk_paint_t* paint, sk_blender_t* blender); SK_C_API bool sk_paint_is_dither(const sk_paint_t*); SK_C_API void sk_paint_set_dither(sk_paint_t*, bool); SK_C_API sk_shader_t* sk_paint_get_shader(sk_paint_t*); @@ -46,6 +47,7 @@ SK_C_API sk_colorfilter_t* sk_paint_get_colorfilter(sk_paint_t*); SK_C_API void sk_paint_set_imagefilter(sk_paint_t*, sk_imagefilter_t*); SK_C_API sk_imagefilter_t* sk_paint_get_imagefilter(sk_paint_t*); SK_C_API sk_blendmode_t sk_paint_get_blendmode(sk_paint_t*); +SK_C_API sk_blender_t* sk_paint_get_blender(sk_paint_t* cpaint); SK_C_API sk_path_effect_t* sk_paint_get_path_effect(sk_paint_t* cpaint); SK_C_API void sk_paint_set_path_effect(sk_paint_t* cpaint, sk_path_effect_t* effect); SK_C_API bool sk_paint_get_fill_path(const sk_paint_t* cpaint, const sk_path_t* src, sk_path_t* dst, const sk_rect_t* cullRect, const sk_matrix_t* cmatrix); diff --git a/include/c/sk_runtimeeffect.h b/include/c/sk_runtimeeffect.h index 6cab7c52eb1d..fe56b447f403 100644 --- a/include/c/sk_runtimeeffect.h +++ b/include/c/sk_runtimeeffect.h @@ -14,9 +14,11 @@ SK_C_PLUS_PLUS_BEGIN_GUARD SK_C_API sk_runtimeeffect_t* sk_runtimeeffect_make_for_color_filter(sk_string_t* sksl, sk_string_t* error); SK_C_API sk_runtimeeffect_t* sk_runtimeeffect_make_for_shader(sk_string_t* sksl, sk_string_t* error); +SK_C_API sk_runtimeeffect_t* sk_runtimeeffect_make_for_blender(sk_string_t* sksl, sk_string_t* error); SK_C_API void sk_runtimeeffect_unref(sk_runtimeeffect_t* effect); SK_C_API sk_shader_t* sk_runtimeeffect_make_shader(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, const sk_matrix_t* localMatrix); SK_C_API sk_colorfilter_t* sk_runtimeeffect_make_color_filter(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount); +SK_C_API sk_blender_t* sk_runtimeeffect_make_blender(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount); SK_C_API size_t sk_runtimeeffect_get_uniform_byte_size(const sk_runtimeeffect_t* effect); SK_C_API size_t sk_runtimeeffect_get_uniforms_size(const sk_runtimeeffect_t* effect); diff --git a/include/c/sk_shader.h b/include/c/sk_shader.h index 310fdfd8b1fd..8f6813002b4f 100644 --- a/include/c/sk_shader.h +++ b/include/c/sk_shader.h @@ -27,6 +27,7 @@ SK_C_API sk_shader_t* sk_shader_new_empty(void); SK_C_API sk_shader_t* sk_shader_new_color(sk_color_t color); SK_C_API sk_shader_t* sk_shader_new_color4f(const sk_color4f_t* color, const sk_colorspace_t* colorspace); SK_C_API sk_shader_t* sk_shader_new_blend(sk_blendmode_t mode, const sk_shader_t* dst, const sk_shader_t* src); +SK_C_API sk_shader_t* sk_shader_new_blender(sk_blender_t* blender, const sk_shader_t* dst, const sk_shader_t* src); // SkGradientShader diff --git a/include/c/sk_types.h b/include/c/sk_types.h index 41e2b336df25..b8ff91ef001d 100644 --- a/include/c/sk_types.h +++ b/include/c/sk_types.h @@ -351,6 +351,8 @@ typedef struct sk_pixmap_t sk_pixmap_t; typedef struct sk_colorfilter_t sk_colorfilter_t; typedef struct sk_imagefilter_t sk_imagefilter_t; +typedef struct sk_blender_t sk_blender_t; + /** A sk_typeface_t pecifies the typeface and intrinsic style of a font. This is used in the paint, along with optionally algorithmic settings like diff --git a/src/c/sk_blender.cpp b/src/c/sk_blender.cpp new file mode 100644 index 000000000000..a5c5647d8709 --- /dev/null +++ b/src/c/sk_blender.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2014 Google Inc. + * Copyright 2015 Xamarin Inc. + * Copyright 2017 Microsoft Corporation. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkBlender.h" +#include "include/effects/SkBlenders.h" + +#include "include/c/sk_blender.h" + +#include "src/c/sk_types_priv.h" + +void sk_blender_ref(sk_blender_t* blender) { + SkSafeRef(AsBlender(blender)); +} + +void sk_blender_unref(sk_blender_t* blender) { + SkSafeUnref(AsBlender(blender)); +} + +sk_blender_t* sk_blender_new_mode(sk_blendmode_t mode) { + return ToBlender(SkBlender::Mode((SkBlendMode)mode).release()); +} + +sk_blender_t* sk_blender_new_arithmetic(float k1, float k2, float k3, float k4, bool enforcePremul) { + return ToBlender(SkBlenders::Arithmetic(k1, k2, k3, k4, enforcePremul).release()); +} diff --git a/src/c/sk_imagefilter.cpp b/src/c/sk_imagefilter.cpp index d06fbd5a54f8..fe98b1c79e02 100644 --- a/src/c/sk_imagefilter.cpp +++ b/src/c/sk_imagefilter.cpp @@ -32,6 +32,10 @@ sk_imagefilter_t* sk_imagefilter_new_blend(sk_blendmode_t mode, const sk_imagefi return ToImageFilter(SkImageFilters::Blend((SkBlendMode)mode, sk_ref_sp(AsImageFilter(background)), sk_ref_sp(AsImageFilter(foreground)), AsRect(cropRect)).release()); } +sk_imagefilter_t* sk_imagefilter_new_blender(sk_blender_t* blender, const sk_imagefilter_t* background, const sk_imagefilter_t* foreground, const sk_rect_t* cropRect) { + return ToImageFilter(SkImageFilters::Blend(sk_ref_sp(AsBlender(blender)), sk_ref_sp(AsImageFilter(background)), sk_ref_sp(AsImageFilter(foreground)), AsRect(cropRect)).release()); +} + sk_imagefilter_t* sk_imagefilter_new_blur(float sigmaX, float sigmaY, sk_shader_tilemode_t tileMode, const sk_imagefilter_t* input, const sk_rect_t* cropRect) { return ToImageFilter(SkImageFilters::Blur(sigmaX, sigmaY, (SkTileMode)tileMode, sk_ref_sp(AsImageFilter(input)), AsRect(cropRect)).release()); } diff --git a/src/c/sk_paint.cpp b/src/c/sk_paint.cpp index 06aadf882e89..106305d437ce 100644 --- a/src/c/sk_paint.cpp +++ b/src/c/sk_paint.cpp @@ -7,6 +7,7 @@ * found in the LICENSE file. */ +#include "include/core/SkBlender.h" #include "include/core/SkColorFilter.h" #include "include/core/SkMaskFilter.h" #include "include/core/SkPaint.h" @@ -108,6 +109,10 @@ void sk_paint_set_blendmode(sk_paint_t* paint, sk_blendmode_t mode) { AsPaint(paint)->setBlendMode((SkBlendMode)mode); } +void sk_paint_set_blender(sk_paint_t* paint, sk_blender_t* blender) { + AsPaint(paint)->setBlender(sk_ref_sp(AsBlender(blender))); +} + bool sk_paint_is_dither(const sk_paint_t* cpaint) { return AsPaint(cpaint)->isDither(); } @@ -144,6 +149,10 @@ sk_blendmode_t sk_paint_get_blendmode(sk_paint_t* paint) { return (sk_blendmode_t)AsPaint(paint)->getBlendMode_or(SkBlendMode::kSrcOver); } +sk_blender_t* sk_paint_get_blender(sk_paint_t* cpaint) { + return ToBlender(AsPaint(cpaint)->refBlender().release()); +} + sk_path_effect_t* sk_paint_get_path_effect(sk_paint_t* cpaint) { return ToPathEffect(AsPaint(cpaint)->refPathEffect().release()); } diff --git a/src/c/sk_runtimeeffect.cpp b/src/c/sk_runtimeeffect.cpp index eaa32deb0869..a700576d6903 100644 --- a/src/c/sk_runtimeeffect.cpp +++ b/src/c/sk_runtimeeffect.cpp @@ -29,6 +29,13 @@ sk_runtimeeffect_t* sk_runtimeeffect_make_for_shader(sk_string_t* sksl, sk_strin return ToRuntimeEffect(effect.release()); } +sk_runtimeeffect_t* sk_runtimeeffect_make_for_blender(sk_string_t* sksl, sk_string_t* error) { + auto [effect, errorMessage] = SkRuntimeEffect::MakeForBlender(AsString(*sksl)); + if (error && errorMessage.size() > 0) + AsString(error)->swap(errorMessage); + return ToRuntimeEffect(effect.release()); +} + void sk_runtimeeffect_unref(sk_runtimeeffect_t* effect) { SkSafeUnref(AsRuntimeEffect(effect)); } @@ -64,6 +71,19 @@ sk_colorfilter_t* sk_runtimeeffect_make_color_filter(sk_runtimeeffect_t* effect, return ToColorFilter(shader.release()); } +sk_blender_t* sk_runtimeeffect_make_blender(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount) { + std::vector skChildren(childCount); + for (size_t i = 0; i < childCount; i++) { + skChildren[i] = sk_ref_sp(AsFlattenable(children[i])); + } + + sk_sp shader = AsRuntimeEffect(effect)->makeBlender( + sk_ref_sp(AsData(uniforms)), + SkSpan(skChildren.data(), childCount)); + + return ToBlender(shader.release()); +} + size_t sk_runtimeeffect_get_uniform_byte_size(const sk_runtimeeffect_t* effect) { return AsRuntimeEffect(effect)->uniformSize(); } diff --git a/src/c/sk_shader.cpp b/src/c/sk_shader.cpp index cc694f127bec..591ce2862885 100644 --- a/src/c/sk_shader.cpp +++ b/src/c/sk_shader.cpp @@ -54,6 +54,10 @@ sk_shader_t* sk_shader_new_blend(sk_blendmode_t mode, const sk_shader_t* dst, co return ToShader(SkShaders::Blend((SkBlendMode)mode, sk_ref_sp(AsShader(dst)), sk_ref_sp(AsShader(src))).release()); } +sk_shader_t* sk_shader_new_blender(sk_blender_t* blender, const sk_shader_t* dst, const sk_shader_t* src) { + return ToShader(SkShaders::Blend(sk_ref_sp(AsBlender(blender)), sk_ref_sp(AsShader(dst)), sk_ref_sp(AsShader(src))).release()); +} + // SkGradientShader sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2], const sk_color_t colors[], const float colorPos[], int colorCount, sk_shader_tilemode_t tileMode, const sk_matrix_t* localMatrix) { diff --git a/src/c/sk_types_priv.h b/src/c/sk_types_priv.h index 2ab313139064..e671b7ddcd47 100644 --- a/src/c/sk_types_priv.h +++ b/src/c/sk_types_priv.h @@ -101,6 +101,7 @@ DEF_CLASS_MAP(SkBitmap, sk_bitmap_t, Bitmap) DEF_CLASS_MAP(SkCanvas, sk_canvas_t, Canvas) DEF_CLASS_MAP(SkCodec, sk_codec_t, Codec) DEF_CLASS_MAP(SkColorFilter, sk_colorfilter_t, ColorFilter) +DEF_CLASS_MAP(SkBlender, sk_blender_t, Blender) DEF_CLASS_MAP(SkColorSpace, sk_colorspace_t, ColorSpace) DEF_CLASS_MAP(SkData, sk_data_t, Data) DEF_CLASS_MAP(SkDocument, sk_document_t, Document) diff --git a/src/xamarin/SkiaKeeper.c b/src/xamarin/SkiaKeeper.c index 5bfcd3b29de4..61cb2786669a 100644 --- a/src/xamarin/SkiaKeeper.c +++ b/src/xamarin/SkiaKeeper.c @@ -11,6 +11,7 @@ // Skia #include "include/c/gr_context.h" #include "include/c/sk_bitmap.h" +#include "include/c/sk_blender.h" #include "include/c/sk_canvas.h" #include "include/c/sk_codec.h" #include "include/c/sk_colorfilter.h" @@ -65,6 +66,7 @@ void** KeepSkiaCSymbols (void) (void*)gr_recording_context_unref, (void*)gr_glinterface_create_native_interface, (void*)sk_bitmap_new, + (void*)sk_blender_unref, (void*)sk_canvas_destroy, (void*)sk_codec_min_buffered_bytes_needed, (void*)sk_colorfilter_unref,