Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.graphics;
     18 
     19 import java.io.PrintWriter;
     20 
     21 
     22 /**
     23  * The Matrix class holds a 3x3 matrix for transforming coordinates.
     24  * Matrix does not have a constructor, so it must be explicitly initialized
     25  * using either reset() - to construct an identity matrix, or one of the set..()
     26  * functions (e.g. setTranslate, setRotate, etc.).
     27  */
     28 public class Matrix {
     29 
     30     public static final int MSCALE_X = 0;   //!< use with getValues/setValues
     31     public static final int MSKEW_X  = 1;   //!< use with getValues/setValues
     32     public static final int MTRANS_X = 2;   //!< use with getValues/setValues
     33     public static final int MSKEW_Y  = 3;   //!< use with getValues/setValues
     34     public static final int MSCALE_Y = 4;   //!< use with getValues/setValues
     35     public static final int MTRANS_Y = 5;   //!< use with getValues/setValues
     36     public static final int MPERSP_0 = 6;   //!< use with getValues/setValues
     37     public static final int MPERSP_1 = 7;   //!< use with getValues/setValues
     38     public static final int MPERSP_2 = 8;   //!< use with getValues/setValues
     39 
     40     /* package */ int native_instance;
     41 
     42     /**
     43      * Create an identity matrix
     44      */
     45     public Matrix() {
     46         native_instance = native_create(0);
     47     }
     48 
     49     /**
     50      * Create a matrix that is a (deep) copy of src
     51      * @param src The matrix to copy into this matrix
     52      */
     53     public Matrix(Matrix src) {
     54         native_instance = native_create(src != null ? src.native_instance : 0);
     55     }
     56 
     57     /**
     58      * Returns true if the matrix is identity.
     59      * This maybe faster than testing if (getType() == 0)
     60      */
     61     public boolean isIdentity() {
     62         return native_isIdentity(native_instance);
     63     }
     64 
     65     /**
     66      * Returns true if will map a rectangle to another rectangle. This can be
     67      * true if the matrix is identity, scale-only, or rotates a multiple of 90
     68      * degrees.
     69      */
     70     public boolean rectStaysRect() {
     71         return native_rectStaysRect(native_instance);
     72     }
     73 
     74     /**
     75      * (deep) copy the src matrix into this matrix. If src is null, reset this
     76      * matrix to the identity matrix.
     77      */
     78     public void set(Matrix src) {
     79         if (src == null) {
     80             reset();
     81         } else {
     82             native_set(native_instance, src.native_instance);
     83         }
     84     }
     85 
     86     /** Returns true iff obj is a Matrix and its values equal our values.
     87     */
     88     public boolean equals(Object obj) {
     89         return obj != null &&
     90                obj instanceof Matrix &&
     91                native_equals(native_instance, ((Matrix)obj).native_instance);
     92     }
     93 
     94     /** Set the matrix to identity */
     95     public void reset() {
     96         native_reset(native_instance);
     97     }
     98 
     99     /** Set the matrix to translate by (dx, dy). */
    100     public void setTranslate(float dx, float dy) {
    101         native_setTranslate(native_instance, dx, dy);
    102     }
    103 
    104     /**
    105      * Set the matrix to scale by sx and sy, with a pivot point at (px, py).
    106      * The pivot point is the coordinate that should remain unchanged by the
    107      * specified transformation.
    108      */
    109     public void setScale(float sx, float sy, float px, float py) {
    110         native_setScale(native_instance, sx, sy, px, py);
    111     }
    112 
    113     /** Set the matrix to scale by sx and sy. */
    114     public void setScale(float sx, float sy) {
    115         native_setScale(native_instance, sx, sy);
    116     }
    117 
    118     /**
    119      * Set the matrix to rotate by the specified number of degrees, with a pivot
    120      * point at (px, py). The pivot point is the coordinate that should remain
    121      * unchanged by the specified transformation.
    122      */
    123     public void setRotate(float degrees, float px, float py) {
    124         native_setRotate(native_instance, degrees, px, py);
    125     }
    126 
    127     /**
    128      * Set the matrix to rotate about (0,0) by the specified number of degrees.
    129      */
    130     public void setRotate(float degrees) {
    131         native_setRotate(native_instance, degrees);
    132     }
    133 
    134     /**
    135      * Set the matrix to rotate by the specified sine and cosine values, with a
    136      * pivot point at (px, py). The pivot point is the coordinate that should
    137      * remain unchanged by the specified transformation.
    138      */
    139     public void setSinCos(float sinValue, float cosValue, float px, float py) {
    140         native_setSinCos(native_instance, sinValue, cosValue, px, py);
    141     }
    142 
    143     /** Set the matrix to rotate by the specified sine and cosine values. */
    144     public void setSinCos(float sinValue, float cosValue) {
    145         native_setSinCos(native_instance, sinValue, cosValue);
    146     }
    147 
    148     /**
    149      * Set the matrix to skew by sx and sy, with a pivot point at (px, py).
    150      * The pivot point is the coordinate that should remain unchanged by the
    151      * specified transformation.
    152      */
    153     public void setSkew(float kx, float ky, float px, float py) {
    154         native_setSkew(native_instance, kx, ky, px, py);
    155     }
    156 
    157     /** Set the matrix to skew by sx and sy. */
    158     public void setSkew(float kx, float ky) {
    159         native_setSkew(native_instance, kx, ky);
    160     }
    161 
    162     /**
    163      * Set the matrix to the concatenation of the two specified matrices,
    164      * returning true if the the result can be represented. Either of the two
    165      * matrices may also be the target matrix. this = a * b
    166      */
    167     public boolean setConcat(Matrix a, Matrix b) {
    168         return native_setConcat(native_instance, a.native_instance,
    169                                 b.native_instance);
    170     }
    171 
    172     /**
    173      * Preconcats the matrix with the specified translation.
    174      * M' = M * T(dx, dy)
    175      */
    176     public boolean preTranslate(float dx, float dy) {
    177         return native_preTranslate(native_instance, dx, dy);
    178     }
    179 
    180     /**
    181      * Preconcats the matrix with the specified scale.
    182      * M' = M * S(sx, sy, px, py)
    183      */
    184     public boolean preScale(float sx, float sy, float px, float py) {
    185         return native_preScale(native_instance, sx, sy, px, py);
    186     }
    187 
    188     /**
    189      * Preconcats the matrix with the specified scale.
    190      * M' = M * S(sx, sy)
    191      */
    192     public boolean preScale(float sx, float sy) {
    193         return native_preScale(native_instance, sx, sy);
    194     }
    195 
    196     /**
    197      * Preconcats the matrix with the specified rotation.
    198      * M' = M * R(degrees, px, py)
    199      */
    200     public boolean preRotate(float degrees, float px, float py) {
    201         return native_preRotate(native_instance, degrees, px, py);
    202     }
    203 
    204     /**
    205      * Preconcats the matrix with the specified rotation.
    206      * M' = M * R(degrees)
    207      */
    208     public boolean preRotate(float degrees) {
    209         return native_preRotate(native_instance, degrees);
    210     }
    211 
    212     /**
    213      * Preconcats the matrix with the specified skew.
    214      * M' = M * K(kx, ky, px, py)
    215      */
    216     public boolean preSkew(float kx, float ky, float px, float py) {
    217         return native_preSkew(native_instance, kx, ky, px, py);
    218     }
    219 
    220     /**
    221      * Preconcats the matrix with the specified skew.
    222      * M' = M * K(kx, ky)
    223      */
    224     public boolean preSkew(float kx, float ky) {
    225         return native_preSkew(native_instance, kx, ky);
    226     }
    227 
    228     /**
    229      * Preconcats the matrix with the specified matrix.
    230      * M' = M * other
    231      */
    232     public boolean preConcat(Matrix other) {
    233         return native_preConcat(native_instance, other.native_instance);
    234     }
    235 
    236     /**
    237      * Postconcats the matrix with the specified translation.
    238      * M' = T(dx, dy) * M
    239      */
    240     public boolean postTranslate(float dx, float dy) {
    241         return native_postTranslate(native_instance, dx, dy);
    242     }
    243 
    244     /**
    245      * Postconcats the matrix with the specified scale.
    246      * M' = S(sx, sy, px, py) * M
    247      */
    248     public boolean postScale(float sx, float sy, float px, float py) {
    249         return native_postScale(native_instance, sx, sy, px, py);
    250     }
    251 
    252     /**
    253      * Postconcats the matrix with the specified scale.
    254      * M' = S(sx, sy) * M
    255      */
    256     public boolean postScale(float sx, float sy) {
    257         return native_postScale(native_instance, sx, sy);
    258     }
    259 
    260     /**
    261      * Postconcats the matrix with the specified rotation.
    262      * M' = R(degrees, px, py) * M
    263      */
    264     public boolean postRotate(float degrees, float px, float py) {
    265         return native_postRotate(native_instance, degrees, px, py);
    266     }
    267 
    268     /**
    269      * Postconcats the matrix with the specified rotation.
    270      * M' = R(degrees) * M
    271      */
    272     public boolean postRotate(float degrees) {
    273         return native_postRotate(native_instance, degrees);
    274     }
    275 
    276     /**
    277      * Postconcats the matrix with the specified skew.
    278      * M' = K(kx, ky, px, py) * M
    279      */
    280     public boolean postSkew(float kx, float ky, float px, float py) {
    281         return native_postSkew(native_instance, kx, ky, px, py);
    282     }
    283 
    284     /**
    285      * Postconcats the matrix with the specified skew.
    286      * M' = K(kx, ky) * M
    287      */
    288     public boolean postSkew(float kx, float ky) {
    289         return native_postSkew(native_instance, kx, ky);
    290     }
    291 
    292     /**
    293      * Postconcats the matrix with the specified matrix.
    294      * M' = other * M
    295      */
    296     public boolean postConcat(Matrix other) {
    297         return native_postConcat(native_instance, other.native_instance);
    298     }
    299 
    300     /** Controlls how the src rect should align into the dst rect for
    301         setRectToRect().
    302     */
    303     public enum ScaleToFit {
    304         /**
    305          * Scale in X and Y independently, so that src matches dst exactly.
    306          * This may change the aspect ratio of the src.
    307          */
    308         FILL    (0),
    309         /**
    310          * Compute a scale that will maintain the original src aspect ratio,
    311          * but will also ensure that src fits entirely inside dst. At least one
    312          * axis (X or Y) will fit exactly. START aligns the result to the
    313          * left and top edges of dst.
    314          */
    315         START   (1),
    316         /**
    317          * Compute a scale that will maintain the original src aspect ratio,
    318          * but will also ensure that src fits entirely inside dst. At least one
    319          * axis (X or Y) will fit exactly. The result is centered inside dst.
    320          */
    321         CENTER  (2),
    322         /**
    323          * Compute a scale that will maintain the original src aspect ratio,
    324          * but will also ensure that src fits entirely inside dst. At least one
    325          * axis (X or Y) will fit exactly. END aligns the result to the
    326          * right and bottom edges of dst.
    327          */
    328         END     (3);
    329 
    330         // the native values must match those in SkMatrix.h
    331         ScaleToFit(int nativeInt) {
    332             this.nativeInt = nativeInt;
    333         }
    334         final int nativeInt;
    335     }
    336 
    337     /**
    338      * Set the matrix to the scale and translate values that map the source
    339      * rectangle to the destination rectangle, returning true if the the result
    340      * can be represented.
    341      *
    342      * @param src the source rectangle to map from.
    343      * @param dst the destination rectangle to map to.
    344      * @param stf the ScaleToFit option
    345      * @return true if the matrix can be represented by the rectangle mapping.
    346      */
    347     public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
    348         if (dst == null || src == null) {
    349             throw new NullPointerException();
    350         }
    351         return native_setRectToRect(native_instance, src, dst, stf.nativeInt);
    352     }
    353 
    354     // private helper to perform range checks on arrays of "points"
    355     private static void checkPointArrays(float[] src, int srcIndex,
    356                                          float[] dst, int dstIndex,
    357                                          int pointCount) {
    358         // check for too-small and too-big indices
    359         int srcStop = srcIndex + (pointCount << 1);
    360         int dstStop = dstIndex + (pointCount << 1);
    361         if ((pointCount | srcIndex | dstIndex | srcStop | dstStop) < 0 ||
    362                 srcStop > src.length || dstStop > dst.length) {
    363             throw new ArrayIndexOutOfBoundsException();
    364         }
    365     }
    366 
    367     /**
    368      * Set the matrix such that the specified src points would map to the
    369      * specified dst points. The "points" are represented as an array of floats,
    370      * order [x0, y0, x1, y1, ...], where each "point" is 2 float values.
    371      *
    372      * @param src   The array of src [x,y] pairs (points)
    373      * @param srcIndex Index of the first pair of src values
    374      * @param dst   The array of dst [x,y] pairs (points)
    375      * @param dstIndex Index of the first pair of dst values
    376      * @param pointCount The number of pairs/points to be used. Must be [0..4]
    377      * @return true if the matrix was set to the specified transformation
    378      */
    379     public boolean setPolyToPoly(float[] src, int srcIndex,
    380                                  float[] dst, int dstIndex,
    381                                  int pointCount) {
    382         if (pointCount > 4) {
    383             throw new IllegalArgumentException();
    384         }
    385         checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
    386         return native_setPolyToPoly(native_instance, src, srcIndex,
    387                                     dst, dstIndex, pointCount);
    388     }
    389 
    390     /**
    391      * If this matrix can be inverted, return true and if inverse is not null,
    392      * set inverse to be the inverse of this matrix. If this matrix cannot be
    393      * inverted, ignore inverse and return false.
    394      */
    395     public boolean invert(Matrix inverse) {
    396         return native_invert(native_instance, inverse.native_instance);
    397     }
    398 
    399     /**
    400     * Apply this matrix to the array of 2D points specified by src, and write
    401      * the transformed points into the array of points specified by dst. The
    402      * two arrays represent their "points" as pairs of floats [x, y].
    403      *
    404      * @param dst   The array of dst points (x,y pairs)
    405      * @param dstIndex The index of the first [x,y] pair of dst floats
    406      * @param src   The array of src points (x,y pairs)
    407      * @param srcIndex The index of the first [x,y] pair of src floats
    408      * @param pointCount The number of points (x,y pairs) to transform
    409      */
    410     public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
    411                           int pointCount) {
    412         checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
    413         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
    414                          pointCount, true);
    415     }
    416 
    417     /**
    418     * Apply this matrix to the array of 2D vectors specified by src, and write
    419      * the transformed vectors into the array of vectors specified by dst. The
    420      * two arrays represent their "vectors" as pairs of floats [x, y].
    421      *
    422      * @param dst   The array of dst vectors (x,y pairs)
    423      * @param dstIndex The index of the first [x,y] pair of dst floats
    424      * @param src   The array of src vectors (x,y pairs)
    425      * @param srcIndex The index of the first [x,y] pair of src floats
    426      * @param vectorCount The number of vectors (x,y pairs) to transform
    427      */
    428     public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,
    429                           int vectorCount) {
    430         checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount);
    431         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
    432                          vectorCount, false);
    433     }
    434 
    435     /**
    436      * Apply this matrix to the array of 2D points specified by src, and write
    437      * the transformed points into the array of points specified by dst. The
    438      * two arrays represent their "points" as pairs of floats [x, y].
    439      *
    440      * @param dst   The array of dst points (x,y pairs)
    441      * @param src   The array of src points (x,y pairs)
    442      */
    443     public void mapPoints(float[] dst, float[] src) {
    444         if (dst.length != src.length) {
    445             throw new ArrayIndexOutOfBoundsException();
    446         }
    447         mapPoints(dst, 0, src, 0, dst.length >> 1);
    448     }
    449 
    450     /**
    451      * Apply this matrix to the array of 2D vectors specified by src, and write
    452      * the transformed vectors into the array of vectors specified by dst. The
    453      * two arrays represent their "vectors" as pairs of floats [x, y].
    454      *
    455      * @param dst   The array of dst vectors (x,y pairs)
    456      * @param src   The array of src vectors (x,y pairs)
    457      */
    458     public void mapVectors(float[] dst, float[] src) {
    459         if (dst.length != src.length) {
    460             throw new ArrayIndexOutOfBoundsException();
    461         }
    462         mapVectors(dst, 0, src, 0, dst.length >> 1);
    463     }
    464 
    465     /**
    466      * Apply this matrix to the array of 2D points, and write the transformed
    467      * points back into the array
    468      *
    469      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
    470      */
    471     public void mapPoints(float[] pts) {
    472         mapPoints(pts, 0, pts, 0, pts.length >> 1);
    473     }
    474 
    475     /**
    476      * Apply this matrix to the array of 2D vectors, and write the transformed
    477      * vectors back into the array.
    478      * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform.
    479      */
    480     public void mapVectors(float[] vecs) {
    481         mapVectors(vecs, 0, vecs, 0, vecs.length >> 1);
    482     }
    483 
    484     /**
    485      * Apply this matrix to the src rectangle, and write the transformed
    486      * rectangle into dst. This is accomplished by transforming the 4 corners of
    487      * src, and then setting dst to the bounds of those points.
    488      *
    489      * @param dst Where the transformed rectangle is written.
    490      * @param src The original rectangle to be transformed.
    491      * @return the result of calling rectStaysRect()
    492      */
    493     public boolean mapRect(RectF dst, RectF src) {
    494         if (dst == null || src == null) {
    495             throw new NullPointerException();
    496         }
    497         return native_mapRect(native_instance, dst, src);
    498     }
    499 
    500     /**
    501      * Apply this matrix to the rectangle, and write the transformed rectangle
    502      * back into it. This is accomplished by transforming the 4 corners of rect,
    503      * and then setting it to the bounds of those points
    504      *
    505      * @param rect The rectangle to transform.
    506      * @return the result of calling rectStaysRect()
    507      */
    508     public boolean mapRect(RectF rect) {
    509         return mapRect(rect, rect);
    510     }
    511 
    512     /**
    513      * Return the mean radius of a circle after it has been mapped by
    514      * this matrix. NOTE: in perspective this value assumes the circle
    515      * has its center at the origin.
    516      */
    517     public float mapRadius(float radius) {
    518         return native_mapRadius(native_instance, radius);
    519     }
    520 
    521     /** Copy 9 values from the matrix into the array.
    522     */
    523     public void getValues(float[] values) {
    524         if (values.length < 9) {
    525             throw new ArrayIndexOutOfBoundsException();
    526         }
    527         native_getValues(native_instance, values);
    528     }
    529 
    530     /** Copy 9 values from the array into the matrix.
    531         Depending on the implementation of Matrix, these may be
    532         transformed into 16.16 integers in the Matrix, such that
    533         a subsequent call to getValues() will not yield exactly
    534         the same values.
    535     */
    536     public void setValues(float[] values) {
    537         if (values.length < 9) {
    538             throw new ArrayIndexOutOfBoundsException();
    539         }
    540         native_setValues(native_instance, values);
    541     }
    542 
    543     public String toString() {
    544         StringBuilder sb = new StringBuilder(64);
    545         sb.append("Matrix{");
    546         toShortString(sb);
    547         sb.append('}');
    548         return sb.toString();
    549 
    550     }
    551 
    552     public String toShortString() {
    553         StringBuilder sb = new StringBuilder(64);
    554         toShortString(sb);
    555         return sb.toString();
    556     }
    557 
    558     /**
    559      * @hide
    560      */
    561     public void toShortString(StringBuilder sb) {
    562         float[] values = new float[9];
    563         getValues(values);
    564         sb.append('[');
    565         sb.append(values[0]); sb.append(", "); sb.append(values[1]); sb.append(", ");
    566         sb.append(values[2]); sb.append("][");
    567         sb.append(values[3]); sb.append(", "); sb.append(values[4]); sb.append(", ");
    568         sb.append(values[5]); sb.append("][");
    569         sb.append(values[6]); sb.append(", "); sb.append(values[7]); sb.append(", ");
    570         sb.append(values[8]); sb.append(']');
    571     }
    572 
    573     /**
    574      * Print short string, to optimize dumping.
    575      * @hide
    576      */
    577     public void printShortString(PrintWriter pw) {
    578         float[] values = new float[9];
    579         getValues(values);
    580         pw.print('[');
    581         pw.print(values[0]); pw.print(", "); pw.print(values[1]); pw.print(", ");
    582                 pw.print(values[2]); pw.print("][");
    583         pw.print(values[3]); pw.print(", "); pw.print(values[4]); pw.print(", ");
    584                 pw.print(values[5]); pw.print("][");
    585         pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", ");
    586                 pw.print(values[8]); pw.print(']');
    587 
    588     }
    589 
    590     protected void finalize() throws Throwable {
    591         finalizer(native_instance);
    592     }
    593 
    594     /*package*/ final int ni() {
    595         return native_instance;
    596     }
    597 
    598     private static native int native_create(int native_src_or_zero);
    599     private static native boolean native_isIdentity(int native_object);
    600     private static native boolean native_rectStaysRect(int native_object);
    601     private static native void native_reset(int native_object);
    602     private static native void native_set(int native_object, int other);
    603     private static native void native_setTranslate(int native_object,
    604                                                    float dx, float dy);
    605     private static native void native_setScale(int native_object,
    606                                         float sx, float sy, float px, float py);
    607     private static native void native_setScale(int native_object,
    608                                                float sx, float sy);
    609     private static native void native_setRotate(int native_object,
    610                                             float degrees, float px, float py);
    611     private static native void native_setRotate(int native_object,
    612                                                 float degrees);
    613     private static native void native_setSinCos(int native_object,
    614                             float sinValue, float cosValue, float px, float py);
    615     private static native void native_setSinCos(int native_object,
    616                                                 float sinValue, float cosValue);
    617     private static native void native_setSkew(int native_object,
    618                                         float kx, float ky, float px, float py);
    619     private static native void native_setSkew(int native_object,
    620                                               float kx, float ky);
    621     private static native boolean native_setConcat(int native_object,
    622                                                    int a, int b);
    623     private static native boolean native_preTranslate(int native_object,
    624                                                       float dx, float dy);
    625     private static native boolean native_preScale(int native_object,
    626                                         float sx, float sy, float px, float py);
    627     private static native boolean native_preScale(int native_object,
    628                                                   float sx, float sy);
    629     private static native boolean native_preRotate(int native_object,
    630                                             float degrees, float px, float py);
    631     private static native boolean native_preRotate(int native_object,
    632                                                    float degrees);
    633     private static native boolean native_preSkew(int native_object,
    634                                         float kx, float ky, float px, float py);
    635     private static native boolean native_preSkew(int native_object,
    636                                                  float kx, float ky);
    637     private static native boolean native_preConcat(int native_object,
    638                                                    int other_matrix);
    639     private static native boolean native_postTranslate(int native_object,
    640                                                        float dx, float dy);
    641     private static native boolean native_postScale(int native_object,
    642                                         float sx, float sy, float px, float py);
    643     private static native boolean native_postScale(int native_object,
    644                                                    float sx, float sy);
    645     private static native boolean native_postRotate(int native_object,
    646                                             float degrees, float px, float py);
    647     private static native boolean native_postRotate(int native_object,
    648                                                     float degrees);
    649     private static native boolean native_postSkew(int native_object,
    650                                         float kx, float ky, float px, float py);
    651     private static native boolean native_postSkew(int native_object,
    652                                                   float kx, float ky);
    653     private static native boolean native_postConcat(int native_object,
    654                                                     int other_matrix);
    655     private static native boolean native_setRectToRect(int native_object,
    656                                                 RectF src, RectF dst, int stf);
    657     private static native boolean native_setPolyToPoly(int native_object,
    658         float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount);
    659     private static native boolean native_invert(int native_object, int inverse);
    660     private static native void native_mapPoints(int native_object,
    661                         float[] dst, int dstIndex, float[] src, int srcIndex,
    662                         int ptCount, boolean isPts);
    663     private static native boolean native_mapRect(int native_object,
    664                                                  RectF dst, RectF src);
    665     private static native float native_mapRadius(int native_object,
    666                                                  float radius);
    667     private static native void native_getValues(int native_object,
    668                                                 float[] values);
    669     private static native void native_setValues(int native_object,
    670                                                 float[] values);
    671     private static native boolean native_equals(int native_a, int native_b);
    672     private static native void finalizer(int native_instance);
    673 }
    674