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, SkMatrix* obj) {
     35         delete obj;
     36     }
     37 
     38     static SkMatrix* create(JNIEnv* env, jobject clazz, const SkMatrix* src) {
     39         SkMatrix* obj = new SkMatrix();
     40         if (src)
     41             *obj = *src;
     42         else
     43             obj->reset();
     44         return obj;
     45     }
     46 
     47     static jboolean isIdentity(JNIEnv* env, jobject clazz, SkMatrix* obj) {
     48         return obj->isIdentity();
     49     }
     50 
     51     static jboolean rectStaysRect(JNIEnv* env, jobject clazz, SkMatrix* obj) {
     52         return obj->rectStaysRect();
     53     }
     54 
     55     static void reset(JNIEnv* env, jobject clazz, SkMatrix* obj) {
     56         obj->reset();
     57     }
     58 
     59     static void set(JNIEnv* env, jobject clazz, SkMatrix* obj, SkMatrix* other) {
     60         *obj = *other;
     61     }
     62 
     63     static void setTranslate(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat dx, jfloat dy) {
     64         SkScalar dx_ = SkFloatToScalar(dx);
     65         SkScalar dy_ = SkFloatToScalar(dy);
     66         obj->setTranslate(dx_, dy_);
     67     }
     68 
     69     static void setScale__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy, jfloat px, jfloat py) {
     70         SkScalar sx_ = SkFloatToScalar(sx);
     71         SkScalar sy_ = SkFloatToScalar(sy);
     72         SkScalar px_ = SkFloatToScalar(px);
     73         SkScalar py_ = SkFloatToScalar(py);
     74         obj->setScale(sx_, sy_, px_, py_);
     75     }
     76 
     77     static void setScale__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy) {
     78         SkScalar sx_ = SkFloatToScalar(sx);
     79         SkScalar sy_ = SkFloatToScalar(sy);
     80         obj->setScale(sx_, sy_);
     81     }
     82 
     83     static void setRotate__FFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees, jfloat px, jfloat py) {
     84         SkScalar degrees_ = SkFloatToScalar(degrees);
     85         SkScalar px_ = SkFloatToScalar(px);
     86         SkScalar py_ = SkFloatToScalar(py);
     87         obj->setRotate(degrees_, px_, py_);
     88     }
     89 
     90     static void setRotate__F(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees) {
     91         SkScalar degrees_ = SkFloatToScalar(degrees);
     92         obj->setRotate(degrees_);
     93     }
     94 
     95     static void setSinCos__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sinValue, jfloat cosValue, jfloat px, jfloat py) {
     96         SkScalar sinValue_ = SkFloatToScalar(sinValue);
     97         SkScalar cosValue_ = SkFloatToScalar(cosValue);
     98         SkScalar px_ = SkFloatToScalar(px);
     99         SkScalar py_ = SkFloatToScalar(py);
    100         obj->setSinCos(sinValue_, cosValue_, px_, py_);
    101     }
    102 
    103     static void setSinCos__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sinValue, jfloat cosValue) {
    104         SkScalar sinValue_ = SkFloatToScalar(sinValue);
    105         SkScalar cosValue_ = SkFloatToScalar(cosValue);
    106         obj->setSinCos(sinValue_, cosValue_);
    107     }
    108 
    109     static void setSkew__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat kx, jfloat ky, jfloat px, jfloat py) {
    110         SkScalar kx_ = SkFloatToScalar(kx);
    111         SkScalar ky_ = SkFloatToScalar(ky);
    112         SkScalar px_ = SkFloatToScalar(px);
    113         SkScalar py_ = SkFloatToScalar(py);
    114         obj->setSkew(kx_, ky_, px_, py_);
    115     }
    116 
    117     static void setSkew__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat kx, jfloat ky) {
    118         SkScalar kx_ = SkFloatToScalar(kx);
    119         SkScalar ky_ = SkFloatToScalar(ky);
    120         obj->setSkew(kx_, ky_);
    121     }
    122 
    123     static jboolean setConcat(JNIEnv* env, jobject clazz, SkMatrix* obj, SkMatrix* a, SkMatrix* b) {
    124         return obj->setConcat(*a, *b);
    125     }
    126 
    127     static jboolean preTranslate(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat dx, jfloat dy) {
    128         SkScalar dx_ = SkFloatToScalar(dx);
    129         SkScalar dy_ = SkFloatToScalar(dy);
    130         return obj->preTranslate(dx_, dy_);
    131     }
    132 
    133     static jboolean preScale__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy, jfloat px, jfloat py) {
    134         SkScalar sx_ = SkFloatToScalar(sx);
    135         SkScalar sy_ = SkFloatToScalar(sy);
    136         SkScalar px_ = SkFloatToScalar(px);
    137         SkScalar py_ = SkFloatToScalar(py);
    138         return obj->preScale(sx_, sy_, px_, py_);
    139     }
    140 
    141     static jboolean preScale__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy) {
    142         SkScalar sx_ = SkFloatToScalar(sx);
    143         SkScalar sy_ = SkFloatToScalar(sy);
    144         return obj->preScale(sx_, sy_);
    145     }
    146 
    147     static jboolean preRotate__FFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees, jfloat px, jfloat py) {
    148         SkScalar degrees_ = SkFloatToScalar(degrees);
    149         SkScalar px_ = SkFloatToScalar(px);
    150         SkScalar py_ = SkFloatToScalar(py);
    151         return obj->preRotate(degrees_, px_, py_);
    152     }
    153 
    154     static jboolean preRotate__F(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees) {
    155         SkScalar degrees_ = SkFloatToScalar(degrees);
    156         return obj->preRotate(degrees_);
    157     }
    158 
    159     static jboolean preSkew__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat kx, jfloat ky, jfloat px, jfloat py) {
    160         SkScalar kx_ = SkFloatToScalar(kx);
    161         SkScalar ky_ = SkFloatToScalar(ky);
    162         SkScalar px_ = SkFloatToScalar(px);
    163         SkScalar py_ = SkFloatToScalar(py);
    164         return obj->preSkew(kx_, ky_, px_, py_);
    165     }
    166 
    167     static jboolean preSkew__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat kx, jfloat ky) {
    168         SkScalar kx_ = SkFloatToScalar(kx);
    169         SkScalar ky_ = SkFloatToScalar(ky);
    170         return obj->preSkew(kx_, ky_);
    171     }
    172 
    173     static jboolean preConcat(JNIEnv* env, jobject clazz, SkMatrix* obj, SkMatrix* other) {
    174         return obj->preConcat(*other);
    175     }
    176 
    177     static jboolean postTranslate(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat dx, jfloat dy) {
    178         SkScalar dx_ = SkFloatToScalar(dx);
    179         SkScalar dy_ = SkFloatToScalar(dy);
    180         return obj->postTranslate(dx_, dy_);
    181     }
    182 
    183     static jboolean postScale__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy, jfloat px, jfloat py) {
    184         SkScalar sx_ = SkFloatToScalar(sx);
    185         SkScalar sy_ = SkFloatToScalar(sy);
    186         SkScalar px_ = SkFloatToScalar(px);
    187         SkScalar py_ = SkFloatToScalar(py);
    188         return obj->postScale(sx_, sy_, px_, py_);
    189     }
    190 
    191     static jboolean postScale__FF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy) {
    192         SkScalar sx_ = SkFloatToScalar(sx);
    193         SkScalar sy_ = SkFloatToScalar(sy);
    194         return obj->postScale(sx_, sy_);
    195     }
    196 
    197     static jboolean postRotate__FFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees, jfloat px, jfloat py) {
    198         SkScalar degrees_ = SkFloatToScalar(degrees);
    199         SkScalar px_ = SkFloatToScalar(px);
    200         SkScalar py_ = SkFloatToScalar(py);
    201         return obj->postRotate(degrees_, px_, py_);
    202     }
    203 
    204     static jboolean postRotate__F(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat degrees) {
    205         SkScalar degrees_ = SkFloatToScalar(degrees);
    206         return obj->postRotate(degrees_);
    207     }
    208 
    209     static jboolean postSkew__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat kx, jfloat ky, jfloat px, jfloat py) {
    210         SkScalar kx_ = SkFloatToScalar(kx);
    211         SkScalar ky_ = SkFloatToScalar(ky);
    212         SkScalar px_ = SkFloatToScalar(px);
    213         SkScalar py_ = SkFloatToScalar(py);
    214         return obj->postSkew(kx_, ky_, px_, py_);
    215     }
    216 
    217     static jboolean postSkew__FF(JNIEnv* env, jobject clazz, SkMatrix* matrix, jfloat kx, jfloat ky) {
    218         SkScalar kx_ = SkFloatToScalar(kx);
    219         SkScalar ky_ = SkFloatToScalar(ky);
    220         return matrix->postSkew(kx_, ky_);
    221     }
    222 
    223     static jboolean postConcat(JNIEnv* env, jobject clazz, SkMatrix* matrix, SkMatrix* other) {
    224         return matrix->postConcat(*other);
    225     }
    226 
    227     static jboolean setRectToRect(JNIEnv* env, jobject clazz, SkMatrix* matrix, jobject src, jobject dst, SkMatrix::ScaleToFit stf) {
    228         SkRect src_;
    229         GraphicsJNI::jrectf_to_rect(env, src, &src_);
    230         SkRect dst_;
    231         GraphicsJNI::jrectf_to_rect(env, dst, &dst_);
    232         return matrix->setRectToRect(src_, dst_, stf);
    233     }
    234 
    235     static jboolean setPolyToPoly(JNIEnv* env, jobject clazz, SkMatrix* matrix,
    236                                   jfloatArray jsrc, int srcIndex,
    237                                   jfloatArray jdst, int dstIndex, int ptCount) {
    238         SkASSERT(srcIndex >= 0);
    239         SkASSERT(dstIndex >= 0);
    240         SkASSERT((unsigned)ptCount <= 4);
    241 
    242         AutoJavaFloatArray autoSrc(env, jsrc, srcIndex + (ptCount << 1));
    243         AutoJavaFloatArray autoDst(env, jdst, dstIndex + (ptCount << 1));
    244         float* src = autoSrc.ptr() + srcIndex;
    245         float* dst = autoDst.ptr() + dstIndex;
    246 
    247 #ifdef SK_SCALAR_IS_FIXED
    248         SkPoint srcPt[4], dstPt[4];
    249         for (int i = 0; i < ptCount; i++) {
    250             int x = i << 1;
    251             int y = x + 1;
    252             srcPt[i].set(SkFloatToScalar(src[x]), SkFloatToScalar(src[y]));
    253             dstPt[i].set(SkFloatToScalar(dst[x]), SkFloatToScalar(dst[y]));
    254         }
    255         return matrix->setPolyToPoly(srcPt, dstPt, ptCount);
    256 #else
    257         return matrix->setPolyToPoly((const SkPoint*)src, (const SkPoint*)dst,
    258                                      ptCount);
    259 #endif
    260     }
    261 
    262     static jboolean invert(JNIEnv* env, jobject clazz, SkMatrix* matrix, SkMatrix* inverse) {
    263         return matrix->invert(inverse);
    264     }
    265 
    266     static void mapPoints(JNIEnv* env, jobject clazz, SkMatrix* matrix,
    267                               jfloatArray dst, int dstIndex,
    268                               jfloatArray src, int srcIndex,
    269                               int ptCount, bool isPts) {
    270         SkASSERT(ptCount >= 0);
    271         AutoJavaFloatArray autoSrc(env, src, srcIndex + (ptCount << 1));
    272         AutoJavaFloatArray autoDst(env, dst, dstIndex + (ptCount << 1));
    273         float* srcArray = autoSrc.ptr() + srcIndex;
    274         float* dstArray = autoDst.ptr() + dstIndex;
    275 
    276 #ifdef SK_SCALAR_IS_FIXED
    277         // we allocate twice the count, 1 set for src, 1 for dst
    278         SkAutoSTMalloc<32, SkPoint> storage(ptCount * 2);
    279         SkPoint* pts = storage.get();
    280         SkPoint* srcPt = pts;
    281         SkPoint* dstPt = pts + ptCount;
    282 
    283         int i;
    284         for (i = 0; i < ptCount; i++) {
    285             srcPt[i].set(SkFloatToScalar(srcArray[i << 1]),
    286                          SkFloatToScalar(srcArray[(i << 1) + 1]));
    287         }
    288 
    289         if (isPts)
    290             matrix->mapPoints(dstPt, srcPt, ptCount);
    291         else
    292             matrix->mapVectors(dstPt, srcPt, ptCount);
    293 
    294         for (i = 0; i < ptCount; i++) {
    295             dstArray[i << 1]  = SkScalarToFloat(dstPt[i].fX);
    296             dstArray[(i << 1) + 1]  = SkScalarToFloat(dstPt[i].fY);
    297         }
    298 #else
    299         if (isPts)
    300             matrix->mapPoints((SkPoint*)dstArray, (const SkPoint*)srcArray,
    301                               ptCount);
    302         else
    303             matrix->mapVectors((SkVector*)dstArray, (const SkVector*)srcArray,
    304                                ptCount);
    305 #endif
    306     }
    307 
    308     static jboolean mapRect__RectFRectF(JNIEnv* env, jobject clazz, SkMatrix* matrix, jobjectArray dst, jobject src) {
    309         SkRect dst_, src_;
    310         GraphicsJNI::jrectf_to_rect(env, src, &src_);
    311         jboolean rectStaysRect = matrix->mapRect(&dst_, src_);
    312         GraphicsJNI::rect_to_jrectf(dst_, env, dst);
    313         return rectStaysRect;
    314     }
    315 
    316     static jfloat mapRadius(JNIEnv* env, jobject clazz, SkMatrix* matrix, jfloat radius) {
    317         return SkScalarToFloat(matrix->mapRadius(SkFloatToScalar(radius)));
    318     }
    319 
    320     static void getValues(JNIEnv* env, jobject clazz, SkMatrix* matrix, jfloatArray values) {
    321         AutoJavaFloatArray autoValues(env, values, 9);
    322         float* dst = autoValues.ptr();
    323 
    324 #ifdef SK_SCALAR_IS_FIXED
    325         for (int i = 0; i < 6; i++) {
    326             dst[i] = SkFixedToFloat(matrix->get(i));
    327         }
    328         for (int j = 6; j < 9; j++) {
    329             dst[j] = SkFractToFloat(matrix->get(j));
    330         }
    331 #else
    332         for (int i = 0; i < 9; i++) {
    333             dst[i] = matrix->get(i);
    334         }
    335 #endif
    336     }
    337 
    338     static void setValues(JNIEnv* env, jobject clazz, SkMatrix* matrix, jfloatArray values) {
    339         AutoJavaFloatArray autoValues(env, values, 9);
    340         const float* src = autoValues.ptr();
    341 
    342 #ifdef SK_SCALAR_IS_FIXED
    343         for (int i = 0; i < 6; i++) {
    344             matrix->set(i, SkFloatToFixed(src[i]));
    345         }
    346         for (int j = 6; j < 9; j++) {
    347             matrix->set(j, SkFloatToFract(src[j]));
    348         }
    349 #else
    350         for (int i = 0; i < 9; i++) {
    351             matrix->set(i, src[i]);
    352         }
    353 #endif
    354     }
    355 
    356     static jboolean equals(JNIEnv* env, jobject clazz, const SkMatrix* a, const SkMatrix* b) {
    357         return *a == *b;
    358     }
    359  };
    360 
    361 static JNINativeMethod methods[] = {
    362     {"finalizer", "(I)V", (void*) SkMatrixGlue::finalizer},
    363     {"native_create","(I)I", (void*) SkMatrixGlue::create},
    364     {"native_isIdentity","(I)Z", (void*) SkMatrixGlue::isIdentity},
    365     {"native_rectStaysRect","(I)Z", (void*) SkMatrixGlue::rectStaysRect},
    366     {"native_reset","(I)V", (void*) SkMatrixGlue::reset},
    367     {"native_set","(II)V", (void*) SkMatrixGlue::set},
    368     {"native_setTranslate","(IFF)V", (void*) SkMatrixGlue::setTranslate},
    369     {"native_setScale","(IFFFF)V", (void*) SkMatrixGlue::setScale__FFFF},
    370     {"native_setScale","(IFF)V", (void*) SkMatrixGlue::setScale__FF},
    371     {"native_setRotate","(IFFF)V", (void*) SkMatrixGlue::setRotate__FFF},
    372     {"native_setRotate","(IF)V", (void*) SkMatrixGlue::setRotate__F},
    373     {"native_setSinCos","(IFFFF)V", (void*) SkMatrixGlue::setSinCos__FFFF},
    374     {"native_setSinCos","(IFF)V", (void*) SkMatrixGlue::setSinCos__FF},
    375     {"native_setSkew","(IFFFF)V", (void*) SkMatrixGlue::setSkew__FFFF},
    376     {"native_setSkew","(IFF)V", (void*) SkMatrixGlue::setSkew__FF},
    377     {"native_setConcat","(III)Z", (void*) SkMatrixGlue::setConcat},
    378     {"native_preTranslate","(IFF)Z", (void*) SkMatrixGlue::preTranslate},
    379     {"native_preScale","(IFFFF)Z", (void*) SkMatrixGlue::preScale__FFFF},
    380     {"native_preScale","(IFF)Z", (void*) SkMatrixGlue::preScale__FF},
    381     {"native_preRotate","(IFFF)Z", (void*) SkMatrixGlue::preRotate__FFF},
    382     {"native_preRotate","(IF)Z", (void*) SkMatrixGlue::preRotate__F},
    383     {"native_preSkew","(IFFFF)Z", (void*) SkMatrixGlue::preSkew__FFFF},
    384     {"native_preSkew","(IFF)Z", (void*) SkMatrixGlue::preSkew__FF},
    385     {"native_preConcat","(II)Z", (void*) SkMatrixGlue::preConcat},
    386     {"native_postTranslate","(IFF)Z", (void*) SkMatrixGlue::postTranslate},
    387     {"native_postScale","(IFFFF)Z", (void*) SkMatrixGlue::postScale__FFFF},
    388     {"native_postScale","(IFF)Z", (void*) SkMatrixGlue::postScale__FF},
    389     {"native_postRotate","(IFFF)Z", (void*) SkMatrixGlue::postRotate__FFF},
    390     {"native_postRotate","(IF)Z", (void*) SkMatrixGlue::postRotate__F},
    391     {"native_postSkew","(IFFFF)Z", (void*) SkMatrixGlue::postSkew__FFFF},
    392     {"native_postSkew","(IFF)Z", (void*) SkMatrixGlue::postSkew__FF},
    393     {"native_postConcat","(II)Z", (void*) SkMatrixGlue::postConcat},
    394     {"native_setRectToRect","(ILandroid/graphics/RectF;Landroid/graphics/RectF;I)Z", (void*) SkMatrixGlue::setRectToRect},
    395     {"native_setPolyToPoly","(I[FI[FII)Z", (void*) SkMatrixGlue::setPolyToPoly},
    396     {"native_invert","(II)Z", (void*) SkMatrixGlue::invert},
    397     {"native_mapPoints","(I[FI[FIIZ)V", (void*) SkMatrixGlue::mapPoints},
    398     {"native_mapRect","(ILandroid/graphics/RectF;Landroid/graphics/RectF;)Z", (void*) SkMatrixGlue::mapRect__RectFRectF},
    399     {"native_mapRadius","(IF)F", (void*) SkMatrixGlue::mapRadius},
    400     {"native_getValues","(I[F)V", (void*) SkMatrixGlue::getValues},
    401     {"native_setValues","(I[F)V", (void*) SkMatrixGlue::setValues},
    402     {"native_equals", "(II)Z", (void*) SkMatrixGlue::equals}
    403 };
    404 
    405 static jfieldID sNativeInstanceField;
    406 
    407 int register_android_graphics_Matrix(JNIEnv* env) {
    408     int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Matrix", methods,
    409         sizeof(methods) / sizeof(methods[0]));
    410 
    411     jclass clazz = env->FindClass("android/graphics/Matrix");
    412     sNativeInstanceField = env->GetFieldID(clazz, "native_instance", "I");
    413 
    414     return result;
    415 }
    416 
    417 SkMatrix* android_graphics_Matrix_getSkMatrix(JNIEnv* env, jobject matrixObj) {
    418     return reinterpret_cast<SkMatrix*>(env->GetIntField(matrixObj, sNativeInstanceField));
    419 }
    420 
    421 }
    422