• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include <jni.h>
9 
10 #include "include/core/SkM44.h"
11 #include "include/effects/SkGradientShader.h"
12 #include "modules/androidkit/src/Utils.h"
13 
14 namespace {
15 
16 // Helper for common gradient data access.
17 class GradientData {
18 public:
GradientData(JNIEnv * env,const jfloatArray & jcolors,const jfloatArray & jpos,jint jtm,jlong native_lm)19     GradientData(JNIEnv* env, const jfloatArray& jcolors, const jfloatArray& jpos,
20                  jint jtm, jlong native_lm)
21         : fEnv(env)
22         , fJColors(jcolors)
23         , fJPos(jpos)
24         , fColors(env->GetFloatArrayElements(jcolors, nullptr))
25         , fPos(env->GetFloatArrayElements(jpos, nullptr))
26         , fCount(env->GetArrayLength(jpos))
27         , fTileMode(androidkit::utils::TileMode(jtm))
28         , fLocalMatrix(native_lm ? reinterpret_cast<const SkM44*>(native_lm)->asM33() : SkMatrix())
29     {
30         SkASSERT(env->GetArrayLength(jcolors) == 4*fCount);
31     }
32 
~GradientData()33     ~GradientData() {
34         fEnv->ReleaseFloatArrayElements(fJPos, fPos, 0);
35         fEnv->ReleaseFloatArrayElements(fJColors, fColors, 0);
36     }
37 
count() const38     int count() const { return fCount; }
39 
colors() const40     const SkColor4f*  colors()      const { return reinterpret_cast<const SkColor4f*>(fColors); }
pos() const41     const float*      pos()         const { return fPos; }
tileMode() const42     const SkTileMode& tileMode()    const { return fTileMode; }
localMatrix() const43     const SkMatrix&   localMatrix() const { return fLocalMatrix; }
44 
45 private:
46     JNIEnv*            fEnv;
47     const jfloatArray& fJColors;
48     const jfloatArray& fJPos;
49     float*             fColors;
50     float*             fPos;
51     const int          fCount;
52     const SkTileMode   fTileMode;
53     const SkMatrix     fLocalMatrix;
54 };
55 
MakeLinear(JNIEnv * env,jobject,jfloat x0,jfloat y0,jfloat x1,jfloat y1,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)56 static jlong MakeLinear(JNIEnv* env, jobject, jfloat x0, jfloat y0, jfloat x1, jfloat y1,
57                         jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
58     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
59     const SkPoint pts[] = {{x0, y0}, {x1, y1}};
60 
61     auto shader = SkGradientShader::MakeLinear(pts,
62                                                gdata.colors(),
63                                                nullptr,
64                                                gdata.pos(),
65                                                gdata.count(),
66                                                gdata.tileMode(),
67                                                0,
68                                                &gdata.localMatrix());
69 
70     return reinterpret_cast<jlong>(shader.release());
71 }
72 
MakeRadial(JNIEnv * env,jobject,jfloat x,jfloat y,jfloat r,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)73 static jlong MakeRadial(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat r,
74                         jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
75     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
76 
77     auto shader = SkGradientShader::MakeRadial({x,y}, r,
78                                                gdata.colors(),
79                                                nullptr,
80                                                gdata.pos(),
81                                                gdata.count(),
82                                                gdata.tileMode(),
83                                                0,
84                                                &gdata.localMatrix());
85 
86     return reinterpret_cast<jlong>(shader.release());
87 }
88 
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)89 static jlong MakeTwoPointConical(JNIEnv* env, jobject,
90                                  jfloat x0, jfloat y0, jfloat r0,
91                                  jfloat x1, jfloat y1, jfloat r1,
92                                  jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
93     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
94 
95     auto shader = SkGradientShader::MakeTwoPointConical({x0,y0}, r0,
96                                                         {x1,y1}, r1,
97                                                         gdata.colors(),
98                                                         nullptr,
99                                                         gdata.pos(),
100                                                         gdata.count(),
101                                                         gdata.tileMode(),
102                                                         0,
103                                                         &gdata.localMatrix());
104 
105     return reinterpret_cast<jlong>(shader.release());
106 }
107 
MakeSweep(JNIEnv * env,jobject,jfloat x,jfloat y,jfloat sa,jfloat ea,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)108 static jlong MakeSweep(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat sa, jfloat ea,
109                        jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
110     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
111 
112     auto shader = SkGradientShader::MakeSweep(x, y,
113                                               gdata.colors(),
114                                               nullptr,
115                                               gdata.pos(),
116                                               gdata.count(),
117                                               gdata.tileMode(),
118                                               sa, ea,
119                                               0,
120                                               &gdata.localMatrix());
121 
122     return reinterpret_cast<jlong>(shader.release());
123 }
124 
125 } // namespace
126 
register_androidkit_LinearGradient(JNIEnv * env)127 int register_androidkit_LinearGradient(JNIEnv* env) {
128     static const JNINativeMethod methods[] = {
129         {"nMakeLinear", "(FFFF[F[FIJ)J", reinterpret_cast<void*>(MakeLinear)},
130     };
131 
132     const auto clazz = env->FindClass("org/skia/androidkit/LinearGradient");
133     return clazz
134         ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
135         : JNI_ERR;
136 }
137 
register_androidkit_RadialGradient(JNIEnv * env)138 int register_androidkit_RadialGradient(JNIEnv* env) {
139     static const JNINativeMethod methods[] = {
140         {"nMakeRadial", "(FFF[F[FIJ)J", reinterpret_cast<void*>(MakeRadial)},
141     };
142 
143     const auto clazz = env->FindClass("org/skia/androidkit/RadialGradient");
144     return clazz
145         ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
146         : JNI_ERR;
147 }
148 
register_androidkit_TwoPointConicalGradient(JNIEnv * env)149 int register_androidkit_TwoPointConicalGradient(JNIEnv* env) {
150     static const JNINativeMethod methods[] = {
151         {"nMakeTwoPointConical", "(FFFFFF[F[FIJ)J", reinterpret_cast<void*>(MakeTwoPointConical)},
152     };
153 
154     const auto clazz = env->FindClass("org/skia/androidkit/TwoPointConicalGradient");
155     return clazz
156         ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
157         : JNI_ERR;
158 }
159 
register_androidkit_SweepGradient(JNIEnv * env)160 int register_androidkit_SweepGradient(JNIEnv* env) {
161     static const JNINativeMethod methods[] = {
162         {"nMakeSweep", "(FFFF[F[FIJ)J", reinterpret_cast<void*>(MakeSweep)},
163     };
164 
165     const auto clazz = env->FindClass("org/skia/androidkit/SweepGradient");
166     return clazz
167         ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
168         : JNI_ERR;
169 }
170