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