android_graphics_drawable_VectorDrawable.cpp revision 5a11e8d0ba21624025b89ac63bbd18befa55be0e
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "jni.h"
18#include "GraphicsJNI.h"
19#include "core_jni_helpers.h"
20#include "log/log.h"
21
22#include "Paint.h"
23#include "VectorDrawable.h"
24
25namespace android {
26using namespace uirenderer;
27using namespace uirenderer::VectorDrawable;
28
29static jlong createTree(JNIEnv*, jobject, jlong groupPtr) {
30    VectorDrawable::Group* rootGroup = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
31    VectorDrawable::Tree* tree = new VectorDrawable::Tree(rootGroup);
32    return reinterpret_cast<jlong>(tree);
33}
34
35static void deleteTree(JNIEnv*, jobject, jlong treePtr) {
36    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
37    delete tree;
38}
39
40static void setTreeViewportSize(JNIEnv*, jobject, jlong treePtr,
41        jfloat viewportWidth, jfloat viewportHeight) {
42    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
43    tree->setViewportSize(viewportWidth, viewportHeight);
44}
45
46static jboolean setRootAlpha(JNIEnv*, jobject, jlong treePtr, jfloat alpha) {
47    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
48    return tree->setRootAlpha(alpha);
49}
50
51static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) {
52    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
53    return tree->getRootAlpha();
54}
55
56static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCaching) {
57    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
58    tree->setAllowCaching(allowCaching);
59}
60
61static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr,
62        jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) {
63    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
64    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
65    SkRect rect;
66    GraphicsJNI::jrect_to_rect(env, jrect, &rect);
67    SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr);
68    tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache);
69}
70
71static jlong createEmptyFullPath(JNIEnv*, jobject) {
72    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath();
73    return reinterpret_cast<jlong>(newPath);
74}
75
76static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) {
77    VectorDrawable::FullPath* srcFullPath =
78            reinterpret_cast<VectorDrawable::FullPath*>(srcFullPathPtr);
79    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(*srcFullPath);
80    return reinterpret_cast<jlong>(newPath);
81}
82
83static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong fullPathPtr,
84        jfloat strokeWidth, jint strokeColor, jfloat strokeAlpha, jint fillColor, jfloat fillAlpha,
85        jfloat trimPathStart, jfloat trimPathEnd, jfloat trimPathOffset, jfloat strokeMiterLimit,
86        jint strokeLineCap, jint strokeLineJoin) {
87    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
88    fullPath->updateProperties(strokeWidth, strokeColor, strokeAlpha, fillColor, fillAlpha,
89            trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit, strokeLineCap,
90            strokeLineJoin);
91}
92
93static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) {
94    VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
95    SkShader* fillShader = reinterpret_cast<SkShader*>(fillGradientPtr);
96    path->setFillGradient(fillShader);
97}
98
99static void updateFullPathStrokeGradient(JNIEnv*, jobject, jlong pathPtr, jlong strokeGradientPtr) {
100    VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
101    SkShader* strokeShader = reinterpret_cast<SkShader*>(strokeGradientPtr);
102    path->setStrokeGradient(strokeShader);
103}
104
105static jboolean getFullPathProperties(JNIEnv* env, jobject, jlong fullPathPtr,
106        jbyteArray outProperties, jint length) {
107    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
108    int8_t pathProperties[length];
109    bool success = fullPath->getProperties(pathProperties, length);
110    env->SetByteArrayRegion(outProperties, 0, length, reinterpret_cast<int8_t*>(&pathProperties));
111    return success;
112}
113
114static jboolean getGroupProperties(JNIEnv* env, jobject, jlong groupPtr,
115        jfloatArray outProperties, jint length) {
116    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
117    float groupProperties[length];
118    bool success = group->getProperties(groupProperties, length);
119    env->SetFloatArrayRegion(outProperties, 0, length, reinterpret_cast<float*>(&groupProperties));
120    return success;
121}
122
123static jlong createEmptyClipPath(JNIEnv*, jobject) {
124    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath();
125    return reinterpret_cast<jlong>(newPath);
126}
127
128static jlong createClipPath(JNIEnv*, jobject, jlong srcClipPathPtr) {
129    VectorDrawable::ClipPath* srcClipPath =
130            reinterpret_cast<VectorDrawable::ClipPath*>(srcClipPathPtr);
131    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(*srcClipPath);
132    return reinterpret_cast<jlong>(newPath);
133}
134
135static jlong createEmptyGroup(JNIEnv*, jobject) {
136    VectorDrawable::Group* newGroup = new VectorDrawable::Group();
137    return reinterpret_cast<jlong>(newGroup);
138}
139
140static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) {
141    VectorDrawable::Group* srcGroup = reinterpret_cast<VectorDrawable::Group*>(srcGroupPtr);
142    VectorDrawable::Group* newGroup = new VectorDrawable::Group(*srcGroup);
143    return reinterpret_cast<jlong>(newGroup);
144}
145
146static void deleteNode(JNIEnv*, jobject, jlong nodePtr) {
147    VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
148    delete node;
149}
150
151static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) {
152    VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
153    const char* nodeName = env->GetStringUTFChars(nameStr, NULL);
154    node->setName(nodeName);
155    env->ReleaseStringUTFChars(nameStr, nodeName);
156}
157
158static void updateGroupProperties(JNIEnv*, jobject, jlong groupPtr, jfloat rotate, jfloat pivotX,
159        jfloat pivotY, jfloat scaleX, jfloat scaleY, jfloat translateX, jfloat translateY) {
160    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
161    group->updateLocalMatrix(rotate, pivotX, pivotY, scaleX, scaleY, translateX, translateY);
162}
163
164static void addChild(JNIEnv*, jobject, jlong groupPtr, jlong childPtr) {
165    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
166    VectorDrawable::Node* child = reinterpret_cast<VectorDrawable::Node*>(childPtr);
167    group->addChild(child);
168}
169
170static void setPathString(JNIEnv* env, jobject, jlong pathPtr, jstring inputStr,
171        jint stringLength) {
172    VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr);
173    const char* pathString = env->GetStringUTFChars(inputStr, NULL);
174    path->setPath(pathString, stringLength);
175    env->ReleaseStringUTFChars(inputStr, pathString);
176}
177
178static jfloat getRotation(JNIEnv*, jobject, jlong groupPtr) {
179    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
180    return group->getRotation();
181}
182
183static void setRotation(JNIEnv*, jobject, jlong groupPtr, jfloat rotation) {
184    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
185    group->setRotation(rotation);
186}
187
188static jfloat getPivotX(JNIEnv*, jobject, jlong groupPtr) {
189    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
190    return group->getPivotX();
191}
192
193static void setPivotX(JNIEnv*, jobject, jlong groupPtr, jfloat pivotX) {
194    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
195    group->setPivotX(pivotX);
196}
197
198static jfloat getPivotY(JNIEnv*, jobject, jlong groupPtr) {
199    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
200    return group->getPivotY();
201}
202
203static void setPivotY(JNIEnv*, jobject, jlong groupPtr, jfloat pivotY) {
204    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
205    group->setPivotY(pivotY);
206}
207
208static jfloat getScaleX(JNIEnv*, jobject, jlong groupPtr) {
209    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
210    return group->getScaleX();
211}
212
213static void setScaleX(JNIEnv*, jobject, jlong groupPtr, jfloat scaleX) {
214    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
215    group->setScaleX(scaleX);
216}
217
218static jfloat getScaleY(JNIEnv*, jobject, jlong groupPtr) {
219    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
220    return group->getScaleY();
221}
222
223static void setScaleY(JNIEnv*, jobject, jlong groupPtr, jfloat scaleY) {
224    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
225    group->setScaleY(scaleY);
226}
227
228static jfloat getTranslateX(JNIEnv*, jobject, jlong groupPtr) {
229    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
230    return group->getTranslateX();
231}
232
233static void setTranslateX(JNIEnv*, jobject, jlong groupPtr, jfloat translateX) {
234    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
235    group->setTranslateX(translateX);
236}
237
238static jfloat getTranslateY(JNIEnv*, jobject, jlong groupPtr) {
239    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
240    return group->getTranslateY();
241}
242
243static void setTranslateY(JNIEnv*, jobject, jlong groupPtr, jfloat translateY) {
244    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
245    group->setTranslateY(translateY);
246}
247
248static void setPathData(JNIEnv*, jobject, jlong pathPtr, jlong pathDataPtr) {
249    VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr);
250    PathData* pathData = reinterpret_cast<PathData*>(pathDataPtr);
251    path->setPathData(*pathData);
252}
253
254static jfloat getStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr) {
255    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
256    return fullPath->getStrokeWidth();
257}
258
259static void setStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeWidth) {
260    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
261    fullPath->setStrokeWidth(strokeWidth);
262}
263
264static jint getStrokeColor(JNIEnv*, jobject, jlong fullPathPtr) {
265    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
266    return fullPath->getStrokeColor();
267}
268
269static void setStrokeColor(JNIEnv*, jobject, jlong fullPathPtr, jint strokeColor) {
270    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
271    fullPath->setStrokeColor(strokeColor);
272}
273
274static jfloat getStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr) {
275    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
276    return fullPath->getStrokeAlpha();
277}
278
279static void setStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeAlpha) {
280    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
281    fullPath->setStrokeAlpha(strokeAlpha);
282}
283
284static jint getFillColor(JNIEnv*, jobject, jlong fullPathPtr) {
285    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
286    return fullPath->getFillColor();
287}
288
289static void setFillColor(JNIEnv*, jobject, jlong fullPathPtr, jint fillColor) {
290    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
291    fullPath->setFillColor(fillColor);
292}
293
294static jfloat getFillAlpha(JNIEnv*, jobject, jlong fullPathPtr) {
295    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
296    return fullPath->getFillAlpha();
297}
298
299static void setFillAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat fillAlpha) {
300    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
301    fullPath->setFillAlpha(fillAlpha);
302}
303
304static jfloat getTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr) {
305    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
306    return fullPath->getTrimPathStart();
307}
308
309static void setTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathStart) {
310    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
311    fullPath->setTrimPathStart(trimPathStart);
312}
313
314static jfloat getTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr) {
315    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
316    return fullPath->getTrimPathEnd();
317}
318
319static void setTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathEnd) {
320    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
321    fullPath->setTrimPathEnd(trimPathEnd);
322}
323
324static jfloat getTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr) {
325    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
326    return fullPath->getTrimPathOffset();
327}
328
329static void setTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathOffset) {
330    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
331    fullPath->setTrimPathOffset(trimPathOffset);
332}
333
334static const JNINativeMethod gMethods[] = {
335        {"nCreateRenderer", "!(J)J", (void*)createTree},
336        {"nDestroyRenderer", "!(J)V", (void*)deleteTree},
337        {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize},
338        {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha},
339        {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha},
340        {"nSetAllowCaching", "!(JZ)V", (void*)setAllowCaching},
341
342        {"nDraw", "(JJJLandroid/graphics/Rect;ZZ)V", (void*)draw},
343        {"nCreateFullPath", "!()J", (void*)createEmptyFullPath},
344        {"nCreateFullPath", "!(J)J", (void*)createFullPath},
345        {"nUpdateFullPathProperties", "!(JFIFIFFFFFII)V", (void*)updateFullPathPropertiesAndStrokeStyles},
346        {"nUpdateFullPathFillGradient", "!(JJ)V", (void*)updateFullPathFillGradient},
347        {"nUpdateFullPathStrokeGradient", "!(JJ)V", (void*)updateFullPathStrokeGradient},
348        {"nGetFullPathProperties", "(J[BI)Z", (void*)getFullPathProperties},
349        {"nGetGroupProperties", "(J[FI)Z", (void*)getGroupProperties},
350
351        {"nCreateClipPath", "!()J", (void*)createEmptyClipPath},
352        {"nCreateClipPath", "!(J)J", (void*)createClipPath},
353        {"nCreateGroup", "!()J", (void*)createEmptyGroup},
354        {"nCreateGroup", "!(J)J", (void*)createGroup},
355        {"nDestroy", "!(J)V", (void*)deleteNode},
356        {"nSetName", "(JLjava/lang/String;)V", (void*)setNodeName},
357        {"nUpdateGroupProperties", "!(JFFFFFFF)V", (void*)updateGroupProperties},
358
359        {"nAddChild", "!(JJ)V", (void*)addChild},
360        {"nSetPathString", "(JLjava/lang/String;I)V", (void*)setPathString},
361
362        {"nGetRotation", "!(J)F", (void*)getRotation},
363        {"nSetRotation", "!(JF)V", (void*)setRotation},
364        {"nGetPivotX", "!(J)F", (void*)getPivotX},
365        {"nSetPivotX", "!(JF)V", (void*)setPivotX},
366        {"nGetPivotY", "!(J)F", (void*)getPivotY},
367        {"nSetPivotY", "!(JF)V", (void*)setPivotY},
368        {"nGetScaleX", "!(J)F", (void*)getScaleX},
369        {"nSetScaleX", "!(JF)V", (void*)setScaleX},
370        {"nGetScaleY", "!(J)F", (void*)getScaleY},
371        {"nSetScaleY", "!(JF)V", (void*)setScaleY},
372        {"nGetTranslateX", "!(J)F", (void*)getTranslateX},
373        {"nSetTranslateX", "!(JF)V", (void*)setTranslateX},
374        {"nGetTranslateY", "!(J)F", (void*)getTranslateY},
375        {"nSetTranslateY", "!(JF)V", (void*)setTranslateY},
376
377        {"nSetPathData", "!(JJ)V", (void*)setPathData},
378        {"nGetStrokeWidth", "!(J)F", (void*)getStrokeWidth},
379        {"nSetStrokeWidth", "!(JF)V", (void*)setStrokeWidth},
380        {"nGetStrokeColor", "!(J)I", (void*)getStrokeColor},
381        {"nSetStrokeColor", "!(JI)V", (void*)setStrokeColor},
382        {"nGetStrokeAlpha", "!(J)F", (void*)getStrokeAlpha},
383        {"nSetStrokeAlpha", "!(JF)V", (void*)setStrokeAlpha},
384        {"nGetFillColor", "!(J)I", (void*)getFillColor},
385        {"nSetFillColor", "!(JI)V", (void*)setFillColor},
386        {"nGetFillAlpha", "!(J)F", (void*)getFillAlpha},
387        {"nSetFillAlpha", "!(JF)V", (void*)setFillAlpha},
388        {"nGetTrimPathStart", "!(J)F", (void*)getTrimPathStart},
389        {"nSetTrimPathStart", "!(JF)V", (void*)setTrimPathStart},
390        {"nGetTrimPathEnd", "!(J)F", (void*)getTrimPathEnd},
391        {"nSetTrimPathEnd", "!(JF)V", (void*)setTrimPathEnd},
392        {"nGetTrimPathOffset", "!(J)F", (void*)getTrimPathOffset},
393        {"nSetTrimPathOffset", "!(JF)V", (void*)setTrimPathOffset},
394};
395
396int register_android_graphics_drawable_VectorDrawable(JNIEnv* env) {
397    return RegisterMethodsOrDie(env, "android/graphics/drawable/VectorDrawable", gMethods, NELEM(gMethods));
398}
399
400}; // namespace android
401