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