Unverified Commit 2fe57f72 authored by Ivan Matkov's avatar Ivan Matkov Committed by GitHub

Expose skia's `Shader.makeWithLocalMatrix` API (#1065)

[CMP-8343](https://youtrack.jetbrains.com/issue/CMP-8343) Support
`TransformShader` in skiko implementation
parent 2accb3b1
...@@ -3,8 +3,21 @@ package org.jetbrains.skia ...@@ -3,8 +3,21 @@ package org.jetbrains.skia
import org.jetbrains.skia.impl.* import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
/**
* Shaders specify the source color(s) for what is being drawn. If a paint
* has no shader, then the paint's color is used. If the paint has a
* shader, then the shader's color(s) are use instead, but they are
* modulated by the paint's alpha. This makes it easy to create a shader
* once (e.g. bitmap tiling or gradient) and then change its transparency
* w/o having to modify the original shader... only the paint's alpha needs
* to be modified.
*/
class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) { class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object { companion object {
init {
staticLoad()
}
// Linear // Linear
fun makeLinearGradient(p0: Point, p1: Point, colors: IntArray): Shader { fun makeLinearGradient(p0: Point, p1: Point, colors: IntArray): Shader {
return makeLinearGradient(p0.x, p0.y, p1.x, p1.y, colors) return makeLinearGradient(p0.x, p0.y, p1.x, p1.y, colors)
...@@ -501,18 +514,36 @@ class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -501,18 +514,36 @@ class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
} }
}
init { /**
staticLoad() * Return a shader that will apply the specified localMatrix to this shader.
* The specified matrix will be applied before any matrix associated with this shader.
*/
fun makeWithLocalMatrix(localMatrix: Matrix33): Shader {
return try {
Stats.onNativeCall()
Shader(
interopScope {
_nMakeWithLocalMatrix(_ptr, toInterop(localMatrix.mat))
})
} finally {
reachabilityBarrier(this)
reachabilityBarrier(localMatrix)
} }
} }
fun makeWithColorFilter(f: ColorFilter?): Shader { /**
* Create a new shader that produces the same colors as invoking this shader and then applying
* the colorfilter.
*/
fun makeWithColorFilter(filter: ColorFilter?): Shader {
return try { return try {
Shader(_nMakeWithColorFilter(_ptr, getPtr(f))) Stats.onNativeCall()
Shader(_nMakeWithColorFilter(_ptr, getPtr(filter)))
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(f) reachabilityBarrier(filter)
} }
} }
} }
...@@ -521,6 +552,10 @@ class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -521,6 +552,10 @@ class Shader internal constructor(ptr: NativePointer) : RefCnt(ptr) {
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Shader__1nMakeEmpty") @ModuleImport("./skiko.mjs", "org_jetbrains_skia_Shader__1nMakeEmpty")
private external fun Shader_nMakeEmpty(): NativePointer private external fun Shader_nMakeEmpty(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Shader__1nMakeWithLocalMatrix")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Shader__1nMakeWithLocalMatrix")
private external fun _nMakeWithLocalMatrix(ptr: NativePointer, localMatrix: InteropPointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Shader__1nMakeWithColorFilter") @ExternalSymbolName("org_jetbrains_skia_Shader__1nMakeWithColorFilter")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Shader__1nMakeWithColorFilter") @ModuleImport("./skiko.mjs", "org_jetbrains_skia_Shader__1nMakeWithColorFilter")
private external fun _nMakeWithColorFilter(ptr: NativePointer, colorFilterPtr: NativePointer): NativePointer private external fun _nMakeWithColorFilter(ptr: NativePointer, colorFilterPtr: NativePointer): NativePointer
......
...@@ -102,4 +102,14 @@ class ShaderTest { ...@@ -102,4 +102,14 @@ class ShaderTest {
Shader.makeTurbulence(0.4f, 0.5f, 10, 0.5f) Shader.makeTurbulence(0.4f, 0.5f, 10, 0.5f)
Shader.makeTurbulence(0.4f, 0.5f, 10, 0.5f, ISize(16, 16)) Shader.makeTurbulence(0.4f, 0.5f, 10, 0.5f, ISize(16, 16))
} }
@Test
fun canMakeWithLocalMatrix() {
Shader.makeEmpty().makeWithLocalMatrix(Matrix33.IDENTITY)
}
@Test
fun canMakeWithColorFilter() {
Shader.makeEmpty().makeWithColorFilter(ColorFilter.sRGBToLinearGamma)
}
} }
\ No newline at end of file
...@@ -8,6 +8,14 @@ ...@@ -8,6 +8,14 @@
#include "SkSize.h" #include "SkSize.h"
#include "interop.hh" #include "interop.hh"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ShaderKt__1nMakeWithLocalMatrix
(JNIEnv* env, jclass jclass, jlong ptr, jfloatArray localMatrixArr) {
SkShader* instance = reinterpret_cast<SkShader*>(static_cast<uintptr_t>(ptr));
std::unique_ptr<SkMatrix> localMatrix = skMatrix(env, localMatrixArr);
SkShader* newPtr = instance->makeWithLocalMatrix(*localMatrix).release();
return reinterpret_cast<jlong>(newPtr);
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ShaderKt__1nMakeWithColorFilter extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ShaderKt__1nMakeWithColorFilter
(JNIEnv* env, jclass jclass, jlong ptr, jlong filterPtr) { (JNIEnv* env, jclass jclass, jlong ptr, jlong filterPtr) {
SkShader* instance = reinterpret_cast<SkShader*>(static_cast<uintptr_t>(ptr)); SkShader* instance = reinterpret_cast<SkShader*>(static_cast<uintptr_t>(ptr));
......
...@@ -6,6 +6,14 @@ ...@@ -6,6 +6,14 @@
#include "SkSize.h" #include "SkSize.h"
#include "common.h" #include "common.h"
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeWithLocalMatrix
(KNativePointer ptr, KFloat* localMatrixArr) {
SkShader* instance = reinterpret_cast<SkShader*>((ptr));
std::unique_ptr<SkMatrix> localMatrix = skMatrix(localMatrixArr);
SkShader* newPtr = instance->makeWithLocalMatrix(*localMatrix).release();
return reinterpret_cast<KNativePointer>(newPtr);
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeWithColorFilter SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeWithColorFilter
(KNativePointer ptr, KNativePointer filterPtr) { (KNativePointer ptr, KNativePointer filterPtr) {
SkShader* instance = reinterpret_cast<SkShader*>((ptr)); SkShader* instance = reinterpret_cast<SkShader*>((ptr));
...@@ -14,7 +22,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeWithColorFilter ...@@ -14,7 +22,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeWithColorFilter
return reinterpret_cast<KNativePointer>(newPtr); return reinterpret_cast<KNativePointer>(newPtr);
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradient SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradient
(KFloat x0, KFloat y0, KFloat x1, KFloat y1, KInt* colorsArray, KFloat* posArray, KInt count, KInt tileModeInt, KInt flags, KFloat* matrixArray) { (KFloat x0, KFloat y0, KFloat x1, KFloat y1, KInt* colorsArray, KFloat* posArray, KInt count, KInt tileModeInt, KInt flags, KFloat* matrixArray) {
SkPoint pts[2] {SkPoint::Make(x0, y0), SkPoint::Make(x1, y1)}; SkPoint pts[2] {SkPoint::Make(x0, y0), SkPoint::Make(x1, y1)};
...@@ -26,7 +33,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradient ...@@ -26,7 +33,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradient
return reinterpret_cast<KNativePointer>(ptr); return reinterpret_cast<KNativePointer>(ptr);
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradientCS SKIKO_EXPORT KNativePointer org_jetbrains_skia_Shader__1nMakeLinearGradientCS
(KFloat x0, KFloat y0, KFloat x1, KFloat y1, KFloat* colorsArray, KNativePointer colorSpacePtr, KFloat* posArray, KInt count, KInt tileModeInt, KInt flags, KFloat* matrixArray) { (KFloat x0, KFloat y0, KFloat x1, KFloat y1, KFloat* colorsArray, KNativePointer colorSpacePtr, KFloat* posArray, KInt count, KInt tileModeInt, KInt flags, KFloat* matrixArray) {
SkPoint pts[2] {SkPoint::Make(x0, y0), SkPoint::Make(x1, y1)}; SkPoint pts[2] {SkPoint::Make(x0, y0), SkPoint::Make(x1, y1)};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment