1 /* libs/android_runtime/android/graphics/Matrix.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "jni.h" 19 #include "GraphicsJNI.h" 20 #include <android_runtime/AndroidRuntime.h> 21 22 #include "SkMatrix.h" 23 #include "SkTemplates.h" 24 25 #include "Matrix.h" 26 27 #include <Caches.h> 28 29 namespace android { 30 31 class SkMatrixGlue { 32 public: 33 34 static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) { 35 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 36 delete obj; 37 } 38 39 static jlong create(JNIEnv* env, jobject clazz, jlong srcHandle) { 40 const SkMatrix* src = reinterpret_cast<SkMatrix*>(srcHandle); 41 SkMatrix* obj = new SkMatrix(); 42 if (src) 43 *obj = *src; 44 else 45 obj->reset(); 46 return reinterpret_cast<jlong>(obj); 47 } 48 49 static jboolean isIdentity(JNIEnv* env, jobject clazz, jlong objHandle) { 50 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 51 return obj->isIdentity() ? JNI_TRUE : JNI_FALSE; 52 } 53 54 static jboolean isAffine(JNIEnv* env, jobject clazz, jlong objHandle) { 55 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 56 return obj->asAffine(NULL) ? JNI_TRUE : JNI_FALSE; 57 } 58 59 static jboolean rectStaysRect(JNIEnv* env, jobject clazz, jlong objHandle) { 60 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 61 return obj->rectStaysRect() ? JNI_TRUE : JNI_FALSE; 62 } 63 64 static void reset(JNIEnv* env, jobject clazz, jlong objHandle) { 65 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 66 obj->reset(); 67 } 68 static void set(JNIEnv* env, jobject clazz, jlong objHandle, jlong otherHandle) { 69 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 70 SkMatrix* other = reinterpret_cast<SkMatrix*>(otherHandle); 71 *obj = *other; 72 } 73 static void setTranslate(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { 74 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 75 obj->setTranslate(dx, dy); 76 } 77 static void setScale__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy, jfloat px, jfloat py) { 78 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 79 obj->setScale(sx, sy, px, py); 80 } 81 static void setScale__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy) { 82 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 83 obj->setScale(sx, sy); 84 } 85 static void setRotate__FFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees, jfloat px, jfloat py) { 86 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 87 obj->setRotate(degrees, px, py); 88 } 89 static void setRotate__F(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees) { 90 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 91 obj->setRotate(degrees); 92 } 93 static void setSinCos__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sinValue, jfloat cosValue, jfloat px, jfloat py) { 94 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 95 obj->setSinCos(sinValue, cosValue, px, py); 96 } 97 static void setSinCos__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sinValue, jfloat cosValue) { 98 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 99 obj->setSinCos(sinValue, cosValue); 100 } 101 static void setSkew__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat kx, jfloat ky, jfloat px, jfloat py) { 102 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 103 obj->setSkew(kx, ky, px, py); 104 } 105 static void setSkew__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat kx, jfloat ky) { 106 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 107 obj->setSkew(kx, ky); 108 } 109 static void setConcat(JNIEnv* env, jobject clazz, jlong objHandle, jlong aHandle, jlong bHandle) { 110 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 111 SkMatrix* a = reinterpret_cast<SkMatrix*>(aHandle); 112 SkMatrix* b = reinterpret_cast<SkMatrix*>(bHandle); 113 obj->setConcat(*a, *b); 114 } 115 116 static void preTranslate(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { 117 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 118 obj->preTranslate(dx, dy); 119 } 120 121 static void preScale__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy, jfloat px, jfloat py) { 122 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 123 obj->preScale(sx, sy, px, py); 124 } 125 126 static void preScale__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy) { 127 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 128 obj->preScale(sx, sy); 129 } 130 131 static void preRotate__FFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees, jfloat px, jfloat py) { 132 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 133 obj->preRotate(degrees, px, py); 134 } 135 136 static void preRotate__F(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees) { 137 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 138 obj->preRotate(degrees); 139 } 140 141 static void preSkew__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat kx, jfloat ky, jfloat px, jfloat py) { 142 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 143 obj->preSkew(kx, ky, px, py); 144 } 145 146 static void preSkew__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat kx, jfloat ky) { 147 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 148 obj->preSkew(kx, ky); 149 } 150 151 static void preConcat(JNIEnv* env, jobject clazz, jlong objHandle, jlong otherHandle) { 152 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 153 SkMatrix* other = reinterpret_cast<SkMatrix*>(otherHandle); 154 obj->preConcat(*other); 155 } 156 157 static void postTranslate(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { 158 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 159 obj->postTranslate(dx, dy); 160 } 161 162 static void postScale__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy, jfloat px, jfloat py) { 163 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 164 obj->postScale(sx, sy, px, py); 165 } 166 167 static void postScale__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat sx, jfloat sy) { 168 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 169 obj->postScale(sx, sy); 170 } 171 172 static void postRotate__FFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees, jfloat px, jfloat py) { 173 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 174 obj->postRotate(degrees, px, py); 175 } 176 177 static void postRotate__F(JNIEnv* env, jobject clazz, jlong objHandle, jfloat degrees) { 178 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 179 obj->postRotate(degrees); 180 } 181 182 static void postSkew__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat kx, jfloat ky, jfloat px, jfloat py) { 183 SkMatrix* obj = reinterpret_cast<SkMatrix*>(objHandle); 184 obj->postSkew(kx, ky, px, py); 185 } 186 187 static void postSkew__FF(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloat kx, jfloat ky) { 188 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 189 matrix->postSkew(kx, ky); 190 } 191 192 static void postConcat(JNIEnv* env, jobject clazz, jlong matrixHandle, jlong otherHandle) { 193 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 194 SkMatrix* other = reinterpret_cast<SkMatrix*>(otherHandle); 195 matrix->postConcat(*other); 196 } 197 198 static jboolean setRectToRect(JNIEnv* env, jobject clazz, jlong matrixHandle, jobject src, jobject dst, jint stfHandle) { 199 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 200 SkMatrix::ScaleToFit stf = static_cast<SkMatrix::ScaleToFit>(stfHandle); 201 SkRect src_; 202 GraphicsJNI::jrectf_to_rect(env, src, &src_); 203 SkRect dst_; 204 GraphicsJNI::jrectf_to_rect(env, dst, &dst_); 205 return matrix->setRectToRect(src_, dst_, stf) ? JNI_TRUE : JNI_FALSE; 206 } 207 208 static jboolean setPolyToPoly(JNIEnv* env, jobject clazz, jlong matrixHandle, 209 jfloatArray jsrc, jint srcIndex, 210 jfloatArray jdst, jint dstIndex, jint ptCount) { 211 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 212 SkASSERT(srcIndex >= 0); 213 SkASSERT(dstIndex >= 0); 214 SkASSERT((unsigned)ptCount <= 4); 215 216 AutoJavaFloatArray autoSrc(env, jsrc, srcIndex + (ptCount << 1), kRO_JNIAccess); 217 AutoJavaFloatArray autoDst(env, jdst, dstIndex + (ptCount << 1), kRW_JNIAccess); 218 float* src = autoSrc.ptr() + srcIndex; 219 float* dst = autoDst.ptr() + dstIndex; 220 bool result; 221 222 #ifdef SK_SCALAR_IS_FLOAT 223 result = matrix->setPolyToPoly((const SkPoint*)src, (const SkPoint*)dst, 224 ptCount); 225 #else 226 SkASSERT(false); 227 #endif 228 return result ? JNI_TRUE : JNI_FALSE; 229 } 230 231 static jboolean invert(JNIEnv* env, jobject clazz, jlong matrixHandle, jlong inverseHandle) { 232 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 233 SkMatrix* inverse = reinterpret_cast<SkMatrix*>(inverseHandle); 234 return matrix->invert(inverse); 235 } 236 237 static void mapPoints(JNIEnv* env, jobject clazz, jlong matrixHandle, 238 jfloatArray dst, jint dstIndex, 239 jfloatArray src, jint srcIndex, 240 jint ptCount, jboolean isPts) { 241 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 242 SkASSERT(ptCount >= 0); 243 AutoJavaFloatArray autoSrc(env, src, srcIndex + (ptCount << 1), kRO_JNIAccess); 244 AutoJavaFloatArray autoDst(env, dst, dstIndex + (ptCount << 1), kRW_JNIAccess); 245 float* srcArray = autoSrc.ptr() + srcIndex; 246 float* dstArray = autoDst.ptr() + dstIndex; 247 #ifdef SK_SCALAR_IS_FLOAT 248 if (isPts) 249 matrix->mapPoints((SkPoint*)dstArray, (const SkPoint*)srcArray, 250 ptCount); 251 else 252 matrix->mapVectors((SkVector*)dstArray, (const SkVector*)srcArray, 253 ptCount); 254 #else 255 SkASSERT(false); 256 #endif 257 } 258 259 static jboolean mapRect__RectFRectF(JNIEnv* env, jobject clazz, jlong matrixHandle, jobjectArray dst, jobject src) { 260 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 261 SkRect dst_, src_; 262 GraphicsJNI::jrectf_to_rect(env, src, &src_); 263 jboolean rectStaysRect = matrix->mapRect(&dst_, src_); 264 GraphicsJNI::rect_to_jrectf(dst_, env, dst); 265 return rectStaysRect ? JNI_TRUE : JNI_FALSE; 266 } 267 268 static jfloat mapRadius(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloat radius) { 269 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 270 float result; 271 result = SkScalarToFloat(matrix->mapRadius(radius)); 272 return static_cast<jfloat>(result); 273 } 274 static void getValues(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloatArray values) { 275 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 276 AutoJavaFloatArray autoValues(env, values, 9, kRW_JNIAccess); 277 float* dst = autoValues.ptr(); 278 #ifdef SK_SCALAR_IS_FLOAT 279 for (int i = 0; i < 9; i++) { 280 dst[i] = matrix->get(i); 281 } 282 #else 283 SkASSERT(false); 284 #endif 285 } 286 287 static void setValues(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloatArray values) { 288 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); 289 AutoJavaFloatArray autoValues(env, values, 9, kRO_JNIAccess); 290 const float* src = autoValues.ptr(); 291 292 #ifdef SK_SCALAR_IS_FLOAT 293 for (int i = 0; i < 9; i++) { 294 matrix->set(i, src[i]); 295 } 296 #else 297 SkASSERT(false); 298 #endif 299 } 300 301 static jboolean equals(JNIEnv* env, jobject clazz, jlong aHandle, jlong bHandle) { 302 const SkMatrix* a = reinterpret_cast<SkMatrix*>(aHandle); 303 const SkMatrix* b = reinterpret_cast<SkMatrix*>(bHandle); 304 return *a == *b; 305 } 306 }; 307 308 static JNINativeMethod methods[] = { 309 {"finalizer", "(J)V", (void*) SkMatrixGlue::finalizer}, 310 {"native_create","(J)J", (void*) SkMatrixGlue::create}, 311 {"native_isIdentity","(J)Z", (void*) SkMatrixGlue::isIdentity}, 312 {"native_isAffine","(J)Z", (void*) SkMatrixGlue::isAffine}, 313 {"native_rectStaysRect","(J)Z", (void*) SkMatrixGlue::rectStaysRect}, 314 {"native_reset","(J)V", (void*) SkMatrixGlue::reset}, 315 {"native_set","(JJ)V", (void*) SkMatrixGlue::set}, 316 {"native_setTranslate","(JFF)V", (void*) SkMatrixGlue::setTranslate}, 317 {"native_setScale","(JFFFF)V", (void*) SkMatrixGlue::setScale__FFFF}, 318 {"native_setScale","(JFF)V", (void*) SkMatrixGlue::setScale__FF}, 319 {"native_setRotate","(JFFF)V", (void*) SkMatrixGlue::setRotate__FFF}, 320 {"native_setRotate","(JF)V", (void*) SkMatrixGlue::setRotate__F}, 321 {"native_setSinCos","(JFFFF)V", (void*) SkMatrixGlue::setSinCos__FFFF}, 322 {"native_setSinCos","(JFF)V", (void*) SkMatrixGlue::setSinCos__FF}, 323 {"native_setSkew","(JFFFF)V", (void*) SkMatrixGlue::setSkew__FFFF}, 324 {"native_setSkew","(JFF)V", (void*) SkMatrixGlue::setSkew__FF}, 325 {"native_setConcat","(JJJ)V", (void*) SkMatrixGlue::setConcat}, 326 {"native_preTranslate","(JFF)V", (void*) SkMatrixGlue::preTranslate}, 327 {"native_preScale","(JFFFF)V", (void*) SkMatrixGlue::preScale__FFFF}, 328 {"native_preScale","(JFF)V", (void*) SkMatrixGlue::preScale__FF}, 329 {"native_preRotate","(JFFF)V", (void*) SkMatrixGlue::preRotate__FFF}, 330 {"native_preRotate","(JF)V", (void*) SkMatrixGlue::preRotate__F}, 331 {"native_preSkew","(JFFFF)V", (void*) SkMatrixGlue::preSkew__FFFF}, 332 {"native_preSkew","(JFF)V", (void*) SkMatrixGlue::preSkew__FF}, 333 {"native_preConcat","(JJ)V", (void*) SkMatrixGlue::preConcat}, 334 {"native_postTranslate","(JFF)V", (void*) SkMatrixGlue::postTranslate}, 335 {"native_postScale","(JFFFF)V", (void*) SkMatrixGlue::postScale__FFFF}, 336 {"native_postScale","(JFF)V", (void*) SkMatrixGlue::postScale__FF}, 337 {"native_postRotate","(JFFF)V", (void*) SkMatrixGlue::postRotate__FFF}, 338 {"native_postRotate","(JF)V", (void*) SkMatrixGlue::postRotate__F}, 339 {"native_postSkew","(JFFFF)V", (void*) SkMatrixGlue::postSkew__FFFF}, 340 {"native_postSkew","(JFF)V", (void*) SkMatrixGlue::postSkew__FF}, 341 {"native_postConcat","(JJ)V", (void*) SkMatrixGlue::postConcat}, 342 {"native_setRectToRect","(JLandroid/graphics/RectF;Landroid/graphics/RectF;I)Z", (void*) SkMatrixGlue::setRectToRect}, 343 {"native_setPolyToPoly","(J[FI[FII)Z", (void*) SkMatrixGlue::setPolyToPoly}, 344 {"native_invert","(JJ)Z", (void*) SkMatrixGlue::invert}, 345 {"native_mapPoints","(J[FI[FIIZ)V", (void*) SkMatrixGlue::mapPoints}, 346 {"native_mapRect","(JLandroid/graphics/RectF;Landroid/graphics/RectF;)Z", (void*) SkMatrixGlue::mapRect__RectFRectF}, 347 {"native_mapRadius","(JF)F", (void*) SkMatrixGlue::mapRadius}, 348 {"native_getValues","(J[F)V", (void*) SkMatrixGlue::getValues}, 349 {"native_setValues","(J[F)V", (void*) SkMatrixGlue::setValues}, 350 {"native_equals", "(JJ)Z", (void*) SkMatrixGlue::equals} 351 }; 352 353 static jfieldID sNativeInstanceField; 354 355 int register_android_graphics_Matrix(JNIEnv* env) { 356 int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Matrix", methods, 357 sizeof(methods) / sizeof(methods[0])); 358 359 jclass clazz = env->FindClass("android/graphics/Matrix"); 360 sNativeInstanceField = env->GetFieldID(clazz, "native_instance", "J"); 361 362 return result; 363 } 364 365 SkMatrix* android_graphics_Matrix_getSkMatrix(JNIEnv* env, jobject matrixObj) { 366 return reinterpret_cast<SkMatrix*>(env->GetLongField(matrixObj, sNativeInstanceField)); 367 } 368 369 } 370