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