• 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 "include/core/SkCanvas.h"
9 #include "include/core/SkColor.h"
10 #include "include/core/SkPaint.h"
11 #include "include/core/SkRRect.h"
12 #include "include/core/SkShader.h"
13 #include "modules/jetski/src/Utils.h"
14 
15 #include <jni.h>
16 
17 namespace {
18 
Canvas_GetWidth(JNIEnv * env,jobject,jlong native_instance)19 jint Canvas_GetWidth(JNIEnv* env, jobject, jlong native_instance) {
20     const auto* canvas = reinterpret_cast<const SkCanvas*>(native_instance);
21     return canvas ? canvas->imageInfo().width() : 0;
22 }
23 
Canvas_GetHeight(JNIEnv * env,jobject,jlong native_instance)24 jint Canvas_GetHeight(JNIEnv* env, jobject, jlong native_instance) {
25     const auto* canvas = reinterpret_cast<const SkCanvas*>(native_instance);
26     return canvas ? canvas->imageInfo().height() : 0;
27 }
28 
Canvas_Save(JNIEnv * env,jobject,jlong native_instance)29 jint Canvas_Save(JNIEnv* env, jobject, jlong native_instance) {
30     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
31         return canvas->save();
32     }
33     return 0;
34 }
35 
Canvas_Restore(JNIEnv * env,jobject,jlong native_instance)36 void Canvas_Restore(JNIEnv* env, jobject, jlong native_instance) {
37     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
38         canvas->restore();
39     }
40 }
41 
Canvas_RestoreToCount(JNIEnv * env,jobject,jlong native_instance,jint count)42 void Canvas_RestoreToCount(JNIEnv* env, jobject, jlong native_instance, jint count) {
43     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
44         canvas->restoreToCount(count);
45     }
46 }
47 
Canvas_SaveLayer(JNIEnv * env,jobject,jlong native_instance,jlong native_paint)48 jint Canvas_SaveLayer(JNIEnv* env, jobject, jlong native_instance, jlong native_paint) {
49     auto* paint = reinterpret_cast<SkPaint* >(native_paint);
50     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
51         return canvas->saveLayer(nullptr, paint);
52     }
53     return 0;
54 }
55 
Canvas_LocalToDevice(JNIEnv * env,jobject,jlong native_instance)56 jlong Canvas_LocalToDevice(JNIEnv* env, jobject, jlong native_instance) {
57     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
58         SkM44* m = new SkM44(canvas->getLocalToDevice());
59         return reinterpret_cast<jlong>(m);
60     }
61     return 0;
62 }
63 
Canvas_Concat(JNIEnv * env,jobject,jlong native_instance,jlong native_matrix)64 void Canvas_Concat(JNIEnv* env, jobject, jlong native_instance, jlong native_matrix) {
65     auto* canvas = reinterpret_cast<SkCanvas*>(native_instance);
66     auto* matrix = reinterpret_cast<SkM44*   >(native_matrix);
67 
68     if (canvas && matrix) {
69         canvas->concat(*matrix);
70     }
71 }
72 
Canvas_Concat16f(JNIEnv * env,jobject,jlong native_instance,jfloatArray jmatrix)73 void Canvas_Concat16f(JNIEnv* env, jobject, jlong native_instance, jfloatArray jmatrix) {
74     SkASSERT(env->GetArrayLength(jmatrix) == 16);
75 
76     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
77         auto* m = env->GetFloatArrayElements(jmatrix, nullptr);
78         canvas->concat(SkM44::RowMajor(m));
79         env->ReleaseFloatArrayElements(jmatrix, m, 0);
80     }
81 }
82 
Canvas_Translate(JNIEnv * env,jobject,jlong native_instance,jfloat tx,jfloat ty,jfloat tz)83 void Canvas_Translate(JNIEnv* env, jobject, jlong native_instance,
84                       jfloat tx, jfloat ty, jfloat tz) {
85     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
86         canvas->concat(SkM44::Translate(tx, ty, tz));
87     }
88 }
89 
Canvas_Scale(JNIEnv * env,jobject,jlong native_instance,jfloat sx,jfloat sy,jfloat sz)90 void Canvas_Scale(JNIEnv* env, jobject, jlong native_instance, jfloat sx, jfloat sy, jfloat sz) {
91     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
92         canvas->concat(SkM44::Scale(sx, sy, sz));
93     }
94 }
95 
Canvas_ClipPath(JNIEnv * env,jobject,jlong native_instance,jlong native_path,jint native_clipOp,jboolean doAA)96 void Canvas_ClipPath(JNIEnv* env, jobject, jlong native_instance, jlong native_path,
97                                            jint native_clipOp, jboolean doAA) {
98     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
99         if (auto* path = reinterpret_cast<SkPath*>(native_path)) {
100             canvas->clipPath(*path, static_cast<SkClipOp>(native_clipOp), doAA);
101         }
102     }
103 }
104 
Canvas_ClipRect(JNIEnv * env,jobject,jlong native_instance,jfloat l,jfloat t,jfloat r,jfloat b,jint native_clipOp,jboolean doAA)105 void Canvas_ClipRect(JNIEnv* env, jobject, jlong native_instance, jfloat l, jfloat t, jfloat r, jfloat b,
106                                            jint native_clipOp, jboolean doAA) {
107     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
108         canvas->clipRect(SkRect::MakeLTRB(l, t, r, b), static_cast<SkClipOp>(native_clipOp), doAA);
109     }
110 }
111 
Canvas_ClipRRect(JNIEnv * env,jobject,jlong native_instance,jfloat l,jfloat t,jfloat r,jfloat b,jfloat xRad,jfloat yRad,jint native_clipOp,jboolean doAA)112 void Canvas_ClipRRect(JNIEnv* env, jobject, jlong native_instance, jfloat l, jfloat t, jfloat r, jfloat b,
113                                                                    jfloat xRad, jfloat yRad,
114                                                                    jint native_clipOp, jboolean doAA) {
115     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
116         canvas->clipRRect(SkRRect::MakeRectXY(SkRect::MakeLTRB(l, t, r, b), xRad, yRad),
117                           static_cast<SkClipOp>(native_clipOp), doAA);
118     }
119 }
120 
Canvas_ClipShader(JNIEnv * env,jobject,jlong native_instance,jlong native_shader,jint native_clipOp)121 void Canvas_ClipShader(JNIEnv* env, jobject, jlong native_instance, jlong native_shader, jint native_clipOp) {
122     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
123         if (auto* shader = reinterpret_cast<SkShader*>(native_shader)) {
124             canvas->clipShader(sk_ref_sp(shader), static_cast<SkClipOp>(native_clipOp));
125         }
126     }
127 }
128 
Canvas_DrawColor(JNIEnv * env,jobject,jlong native_instance,float r,float g,float b,float a)129 void Canvas_DrawColor(JNIEnv* env, jobject, jlong native_instance,
130                       float r, float g, float b, float a) {
131     if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) {
132         canvas->drawColor(SkColor4f{r, g, b, a});
133     }
134 }
135 
Canvas_DrawRect(JNIEnv * env,jobject,jlong native_instance,jfloat left,jfloat top,jfloat right,jfloat bottom,jlong native_paint)136 void Canvas_DrawRect(JNIEnv* env, jobject, jlong native_instance,
137                      jfloat left, jfloat top, jfloat right, jfloat bottom,
138                      jlong native_paint) {
139     auto* canvas = reinterpret_cast<SkCanvas*>(native_instance);
140     auto* paint  = reinterpret_cast<SkPaint* >(native_paint);
141     if (canvas && paint) {
142         canvas->drawRect(SkRect::MakeLTRB(left, top, right, bottom), *paint);
143     }
144 }
145 
Canvas_DrawImage(JNIEnv * env,jobject,jlong native_instance,jlong native_image,jfloat x,jfloat y,jint sampling_desc,jfloat sampling_b,jfloat sampling_c)146 void Canvas_DrawImage(JNIEnv* env, jobject, jlong native_instance, jlong native_image,
147                       jfloat x, jfloat y,
148                       jint sampling_desc, jfloat sampling_b, jfloat sampling_c) {
149     auto* canvas = reinterpret_cast<SkCanvas*>(native_instance);
150     auto*  image = reinterpret_cast<SkImage *>(native_image);
151 
152     if (canvas && image) {
153         canvas->drawImage(image, x, y,
154             jetski::utils::SamplingOptions(sampling_desc, sampling_b, sampling_c));
155     }
156 }
157 
Canvas_DrawPath(JNIEnv * env,jobject,jlong native_instance,jlong native_path,jlong native_paint)158 void Canvas_DrawPath(JNIEnv* env, jobject, jlong native_instance, jlong native_path,
159                      jlong native_paint) {
160     auto* canvas = reinterpret_cast<SkCanvas*>(native_instance);
161     auto* path  = reinterpret_cast<SkPath* >(native_path);
162     auto* paint  = reinterpret_cast<SkPaint* >(native_paint);
163     if (canvas && paint && path) {
164         canvas->drawPath(*path, *paint);
165     }
166 }
167 
168 // jPos: a composite array in the form of [x1, y1, x2, y2, ... ,xn, yn]
169 // callers of this function check should throw IllegalArgumentException in Java
Canvas_DrawGlyphs(JNIEnv * env,jobject,jlong native_instance,jcharArray jglyphs,jfloatArray jPos,jfloat xOrigin,jfloat yOrigin,jlong native_font,jlong native_paint)170 void Canvas_DrawGlyphs(JNIEnv* env, jobject, jlong native_instance, jcharArray jglyphs,
171                                              jfloatArray jPos, jfloat xOrigin, jfloat yOrigin,
172                                              jlong native_font, jlong native_paint) {
173     auto* canvas = reinterpret_cast<SkCanvas*>(native_instance);
174     auto* font = reinterpret_cast<SkFont*>(native_font);
175     auto* paint  = reinterpret_cast<SkPaint* >(native_paint);
176     if (canvas && font && paint) {
177         int count = env->GetArrayLength(jglyphs);
178         auto* compositePositions = env->GetFloatArrayElements(jPos, nullptr);
179         auto* positions = reinterpret_cast<SkPoint*>(compositePositions);
180         auto* glyphs = env->GetCharArrayElements(jglyphs, nullptr);
181         canvas->drawGlyphs(count, glyphs, positions, {xOrigin, yOrigin}, *font, *paint);
182 
183         env->ReleaseCharArrayElements(jglyphs, glyphs, 0);
184         env->ReleaseFloatArrayElements(jPos, compositePositions, 0);
185     }
186 }
187 
188 }  // namespace
189 
register_jetski_Canvas(JNIEnv * env)190 int register_jetski_Canvas(JNIEnv* env) {
191     static const JNINativeMethod methods[] = {
192         {"nGetWidth"        , "(J)I"           , reinterpret_cast<void*>(Canvas_GetWidth)      },
193         {"nGetHeight"       , "(J)I"           , reinterpret_cast<void*>(Canvas_GetHeight)     },
194         {"nSave"            , "(J)I"           , reinterpret_cast<void*>(Canvas_Save)          },
195         {"nSaveLayer"       , "(JJ)I"          , reinterpret_cast<void*>(Canvas_SaveLayer)     },
196         {"nRestore"         , "(J)V"           , reinterpret_cast<void*>(Canvas_Restore)       },
197         {"nRestoreToCount"  , "(JI)V"          , reinterpret_cast<void*>(Canvas_RestoreToCount)},
198         {"nGetLocalToDevice", "(J)J"           , reinterpret_cast<void*>(Canvas_LocalToDevice) },
199         {"nConcat"          , "(JJ)V"          , reinterpret_cast<void*>(Canvas_Concat)        },
200         {"nConcat16f"       , "(J[F)V"         , reinterpret_cast<void*>(Canvas_Concat16f)     },
201         {"nTranslate"       , "(JFFF)V"        , reinterpret_cast<void*>(Canvas_Translate)     },
202         {"nScale"           , "(JFFF)V"        , reinterpret_cast<void*>(Canvas_Scale)         },
203         {"nClipPath"        , "(JJIZ)V"        , reinterpret_cast<void*>(Canvas_ClipPath)      },
204         {"nClipRect"        , "(JFFFFIZ)V"     , reinterpret_cast<void*>(Canvas_ClipRect)      },
205         {"nClipRRect"       , "(JFFFFFFIZ)V"   , reinterpret_cast<void*>(Canvas_ClipRRect)     },
206         {"nClipShader"      , "(JJI)V"         , reinterpret_cast<void*>(Canvas_ClipShader)    },
207         {"nDrawColor"       , "(JFFFF)V"       , reinterpret_cast<void*>(Canvas_DrawColor)     },
208         {"nDrawRect"        , "(JFFFFJ)V"      , reinterpret_cast<void*>(Canvas_DrawRect)      },
209         {"nDrawImage"       , "(JJFFIFF)V"     , reinterpret_cast<void*>(Canvas_DrawImage)     },
210         {"nDrawPath"        , "(JJJ)V"         , reinterpret_cast<void*>(Canvas_DrawPath)      },
211         {"nDrawGlyphs"      , "(J[C[FFFJJ)V", reinterpret_cast<void*>(Canvas_DrawGlyphs)    },
212 
213     };
214 
215     const auto clazz = env->FindClass("org/skia/jetski/Canvas");
216     return clazz
217         ? env->RegisterNatives(clazz, methods, std::size(methods))
218         : JNI_ERR;
219 }
220