/* * Copyright 2021 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include "include/core/SkColorSpace.h" #include "include/core/SkM44.h" #include "include/effects/SkGradientShader.h" #include "modules/jetski/src/Utils.h" namespace { // Helper for common gradient data access. class GradientData { public: GradientData(JNIEnv* env, const jfloatArray& jcolors, const jfloatArray& jpos, jint jtm, jlong native_lm) : fEnv(env) , fJColors(jcolors) , fJPos(jpos) , fColors(env->GetFloatArrayElements(jcolors, nullptr)) , fPos(env->GetFloatArrayElements(jpos, nullptr)) , fCount(env->GetArrayLength(jpos)) , fTileMode(jetski::utils::TileMode(jtm)) , fLocalMatrix(native_lm ? reinterpret_cast(native_lm)->asM33() : SkMatrix()) { SkASSERT(env->GetArrayLength(jcolors) == 4*fCount); } ~GradientData() { fEnv->ReleaseFloatArrayElements(fJPos, fPos, 0); fEnv->ReleaseFloatArrayElements(fJColors, fColors, 0); } int count() const { return fCount; } const SkColor4f* colors() const { return reinterpret_cast(fColors); } const float* pos() const { return fPos; } const SkTileMode& tileMode() const { return fTileMode; } const SkMatrix& localMatrix() const { return fLocalMatrix; } private: JNIEnv* fEnv; const jfloatArray& fJColors; const jfloatArray& fJPos; float* fColors; float* fPos; const int fCount; const SkTileMode fTileMode; const SkMatrix fLocalMatrix; }; static jlong MakeLinear(JNIEnv* env, jobject, jfloat x0, jfloat y0, jfloat x1, jfloat y1, jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) { const GradientData gdata(env, jcolors, jpos, jtm, native_lm); const SkPoint pts[] = {{x0, y0}, {x1, y1}}; auto shader = SkGradientShader::MakeLinear(pts, gdata.colors(), nullptr, gdata.pos(), gdata.count(), gdata.tileMode(), 0, &gdata.localMatrix()); return reinterpret_cast(shader.release()); } static jlong MakeRadial(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat r, jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) { const GradientData gdata(env, jcolors, jpos, jtm, native_lm); auto shader = SkGradientShader::MakeRadial({x,y}, r, gdata.colors(), nullptr, gdata.pos(), gdata.count(), gdata.tileMode(), 0, &gdata.localMatrix()); return reinterpret_cast(shader.release()); } static jlong MakeTwoPointConical(JNIEnv* env, jobject, jfloat x0, jfloat y0, jfloat r0, jfloat x1, jfloat y1, jfloat r1, jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) { const GradientData gdata(env, jcolors, jpos, jtm, native_lm); auto shader = SkGradientShader::MakeTwoPointConical({x0,y0}, r0, {x1,y1}, r1, gdata.colors(), nullptr, gdata.pos(), gdata.count(), gdata.tileMode(), 0, &gdata.localMatrix()); return reinterpret_cast(shader.release()); } static jlong MakeSweep(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat sa, jfloat ea, jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) { const GradientData gdata(env, jcolors, jpos, jtm, native_lm); auto shader = SkGradientShader::MakeSweep(x, y, gdata.colors(), nullptr, gdata.pos(), gdata.count(), gdata.tileMode(), sa, ea, 0, &gdata.localMatrix()); return reinterpret_cast(shader.release()); } } // namespace int register_jetski_LinearGradient(JNIEnv* env) { static const JNINativeMethod methods[] = { {"nMakeLinear", "(FFFF[F[FIJ)J", reinterpret_cast(MakeLinear)}, }; const auto clazz = env->FindClass("org/skia/jetski/LinearGradient"); return clazz ? env->RegisterNatives(clazz, methods, std::size(methods)) : JNI_ERR; } int register_jetski_RadialGradient(JNIEnv* env) { static const JNINativeMethod methods[] = { {"nMakeRadial", "(FFF[F[FIJ)J", reinterpret_cast(MakeRadial)}, }; const auto clazz = env->FindClass("org/skia/jetski/RadialGradient"); return clazz ? env->RegisterNatives(clazz, methods, std::size(methods)) : JNI_ERR; } int register_jetski_TwoPointConicalGradient(JNIEnv* env) { static const JNINativeMethod methods[] = { {"nMakeTwoPointConical", "(FFFFFF[F[FIJ)J", reinterpret_cast(MakeTwoPointConical)}, }; const auto clazz = env->FindClass("org/skia/jetski/TwoPointConicalGradient"); return clazz ? env->RegisterNatives(clazz, methods, std::size(methods)) : JNI_ERR; } int register_jetski_SweepGradient(JNIEnv* env) { static const JNINativeMethod methods[] = { {"nMakeSweep", "(FFFF[F[FIJ)J", reinterpret_cast(MakeSweep)}, }; const auto clazz = env->FindClass("org/skia/jetski/SweepGradient"); return clazz ? env->RegisterNatives(clazz, methods, std::size(methods)) : JNI_ERR; }