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