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