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