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 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