Home | History | Annotate | Download | only in graphics
      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