Matrix.java revision 36bef0bf30d6bae48cf3837df351075ca4fce654
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
17package android.graphics;
18
19import java.io.PrintWriter;
20
21
22/**
23 * The Matrix class holds a 3x3 matrix for transforming coordinates.
24 */
25public class Matrix {
26
27    public static final int MSCALE_X = 0;   //!< use with getValues/setValues
28    public static final int MSKEW_X  = 1;   //!< use with getValues/setValues
29    public static final int MTRANS_X = 2;   //!< use with getValues/setValues
30    public static final int MSKEW_Y  = 3;   //!< use with getValues/setValues
31    public static final int MSCALE_Y = 4;   //!< use with getValues/setValues
32    public static final int MTRANS_Y = 5;   //!< use with getValues/setValues
33    public static final int MPERSP_0 = 6;   //!< use with getValues/setValues
34    public static final int MPERSP_1 = 7;   //!< use with getValues/setValues
35    public static final int MPERSP_2 = 8;   //!< use with getValues/setValues
36
37    /** @hide */
38    public static Matrix IDENTITY_MATRIX = new Matrix() {
39        void oops() {
40            throw new IllegalStateException("Matrix can not be modified");
41        }
42
43        @Override
44        public void set(Matrix src) {
45            oops();
46        }
47
48        @Override
49        public void reset() {
50            oops();
51        }
52
53        @Override
54        public void setTranslate(float dx, float dy) {
55            oops();
56        }
57
58        @Override
59        public void setScale(float sx, float sy, float px, float py) {
60            oops();
61        }
62
63        @Override
64        public void setScale(float sx, float sy) {
65            oops();
66        }
67
68        @Override
69        public void setRotate(float degrees, float px, float py) {
70            oops();
71        }
72
73        @Override
74        public void setRotate(float degrees) {
75            oops();
76        }
77
78        @Override
79        public void setSinCos(float sinValue, float cosValue, float px, float py) {
80            oops();
81        }
82
83        @Override
84        public void setSinCos(float sinValue, float cosValue) {
85            oops();
86        }
87
88        @Override
89        public void setSkew(float kx, float ky, float px, float py) {
90            oops();
91        }
92
93        @Override
94        public void setSkew(float kx, float ky) {
95            oops();
96        }
97
98        @Override
99        public boolean setConcat(Matrix a, Matrix b) {
100            oops();
101            return false;
102        }
103
104        @Override
105        public boolean preTranslate(float dx, float dy) {
106            oops();
107            return false;
108        }
109
110        @Override
111        public boolean preScale(float sx, float sy, float px, float py) {
112            oops();
113            return false;
114        }
115
116        @Override
117        public boolean preScale(float sx, float sy) {
118            oops();
119            return false;
120        }
121
122        @Override
123        public boolean preRotate(float degrees, float px, float py) {
124            oops();
125            return false;
126        }
127
128        @Override
129        public boolean preRotate(float degrees) {
130            oops();
131            return false;
132        }
133
134        @Override
135        public boolean preSkew(float kx, float ky, float px, float py) {
136            oops();
137            return false;
138        }
139
140        @Override
141        public boolean preSkew(float kx, float ky) {
142            oops();
143            return false;
144        }
145
146        @Override
147        public boolean preConcat(Matrix other) {
148            oops();
149            return false;
150        }
151
152        @Override
153        public boolean postTranslate(float dx, float dy) {
154            oops();
155            return false;
156        }
157
158        @Override
159        public boolean postScale(float sx, float sy, float px, float py) {
160            oops();
161            return false;
162        }
163
164        @Override
165        public boolean postScale(float sx, float sy) {
166            oops();
167            return false;
168        }
169
170        @Override
171        public boolean postRotate(float degrees, float px, float py) {
172            oops();
173            return false;
174        }
175
176        @Override
177        public boolean postRotate(float degrees) {
178            oops();
179            return false;
180        }
181
182        @Override
183        public boolean postSkew(float kx, float ky, float px, float py) {
184            oops();
185            return false;
186        }
187
188        @Override
189        public boolean postSkew(float kx, float ky) {
190            oops();
191            return false;
192        }
193
194        @Override
195        public boolean postConcat(Matrix other) {
196            oops();
197            return false;
198        }
199
200        @Override
201        public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
202            oops();
203            return false;
204        }
205
206        @Override
207        public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex,
208                int pointCount) {
209            oops();
210            return false;
211        }
212
213        @Override
214        public void setValues(float[] values) {
215            oops();
216        }
217    };
218
219    /**
220     * @hide
221     */
222    public long native_instance;
223
224    /**
225     * Create an identity matrix
226     */
227    public Matrix() {
228        native_instance = native_create(0);
229    }
230
231    /**
232     * Create a matrix that is a (deep) copy of src
233     * @param src The matrix to copy into this matrix
234     */
235    public Matrix(Matrix src) {
236        native_instance = native_create(src != null ? src.native_instance : 0);
237    }
238
239    /**
240     * Returns true if the matrix is identity.
241     * This maybe faster than testing if (getType() == 0)
242     */
243    public boolean isIdentity() {
244        return native_isIdentity(native_instance);
245    }
246
247    /**
248     * Returns true if will map a rectangle to another rectangle. This can be
249     * true if the matrix is identity, scale-only, or rotates a multiple of 90
250     * degrees.
251     */
252    public boolean rectStaysRect() {
253        return native_rectStaysRect(native_instance);
254    }
255
256    /**
257     * (deep) copy the src matrix into this matrix. If src is null, reset this
258     * matrix to the identity matrix.
259     */
260    public void set(Matrix src) {
261        if (src == null) {
262            reset();
263        } else {
264            native_set(native_instance, src.native_instance);
265        }
266    }
267
268    /** Returns true iff obj is a Matrix and its values equal our values.
269    */
270    @Override
271    public boolean equals(Object obj) {
272        //if (obj == this) return true;     -- NaN value would mean matrix != itself
273        if (!(obj instanceof Matrix)) return false;
274        return native_equals(native_instance, ((Matrix)obj).native_instance);
275    }
276
277    @Override
278    public int hashCode() {
279        // This should generate the hash code by performing some arithmetic operation on all
280        // the matrix elements -- our equals() does an element-by-element comparison, and we
281        // need to ensure that the hash code for two equal objects is the same.  We're not
282        // really using this at the moment, so we take the easy way out.
283        return 44;
284    }
285
286    /** Set the matrix to identity */
287    public void reset() {
288        native_reset(native_instance);
289    }
290
291    /** Set the matrix to translate by (dx, dy). */
292    public void setTranslate(float dx, float dy) {
293        native_setTranslate(native_instance, dx, dy);
294    }
295
296    /**
297     * Set the matrix to scale by sx and sy, with a pivot point at (px, py).
298     * The pivot point is the coordinate that should remain unchanged by the
299     * specified transformation.
300     */
301    public void setScale(float sx, float sy, float px, float py) {
302        native_setScale(native_instance, sx, sy, px, py);
303    }
304
305    /** Set the matrix to scale by sx and sy. */
306    public void setScale(float sx, float sy) {
307        native_setScale(native_instance, sx, sy);
308    }
309
310    /**
311     * Set the matrix to rotate by the specified number of degrees, with a pivot
312     * point at (px, py). The pivot point is the coordinate that should remain
313     * unchanged by the specified transformation.
314     */
315    public void setRotate(float degrees, float px, float py) {
316        native_setRotate(native_instance, degrees, px, py);
317    }
318
319    /**
320     * Set the matrix to rotate about (0,0) by the specified number of degrees.
321     */
322    public void setRotate(float degrees) {
323        native_setRotate(native_instance, degrees);
324    }
325
326    /**
327     * Set the matrix to rotate by the specified sine and cosine values, with a
328     * pivot point at (px, py). The pivot point is the coordinate that should
329     * remain unchanged by the specified transformation.
330     */
331    public void setSinCos(float sinValue, float cosValue, float px, float py) {
332        native_setSinCos(native_instance, sinValue, cosValue, px, py);
333    }
334
335    /** Set the matrix to rotate by the specified sine and cosine values. */
336    public void setSinCos(float sinValue, float cosValue) {
337        native_setSinCos(native_instance, sinValue, cosValue);
338    }
339
340    /**
341     * Set the matrix to skew by sx and sy, with a pivot point at (px, py).
342     * The pivot point is the coordinate that should remain unchanged by the
343     * specified transformation.
344     */
345    public void setSkew(float kx, float ky, float px, float py) {
346        native_setSkew(native_instance, kx, ky, px, py);
347    }
348
349    /** Set the matrix to skew by sx and sy. */
350    public void setSkew(float kx, float ky) {
351        native_setSkew(native_instance, kx, ky);
352    }
353
354    /**
355     * Set the matrix to the concatenation of the two specified matrices,
356     * returning true if the the result can be represented. Either of the two
357     * matrices may also be the target matrix. this = a * b
358     */
359    public boolean setConcat(Matrix a, Matrix b) {
360        return native_setConcat(native_instance, a.native_instance,
361                                b.native_instance);
362    }
363
364    /**
365     * Preconcats the matrix with the specified translation.
366     * M' = M * T(dx, dy)
367     */
368    public boolean preTranslate(float dx, float dy) {
369        return native_preTranslate(native_instance, dx, dy);
370    }
371
372    /**
373     * Preconcats the matrix with the specified scale.
374     * M' = M * S(sx, sy, px, py)
375     */
376    public boolean preScale(float sx, float sy, float px, float py) {
377        return native_preScale(native_instance, sx, sy, px, py);
378    }
379
380    /**
381     * Preconcats the matrix with the specified scale.
382     * M' = M * S(sx, sy)
383     */
384    public boolean preScale(float sx, float sy) {
385        return native_preScale(native_instance, sx, sy);
386    }
387
388    /**
389     * Preconcats the matrix with the specified rotation.
390     * M' = M * R(degrees, px, py)
391     */
392    public boolean preRotate(float degrees, float px, float py) {
393        return native_preRotate(native_instance, degrees, px, py);
394    }
395
396    /**
397     * Preconcats the matrix with the specified rotation.
398     * M' = M * R(degrees)
399     */
400    public boolean preRotate(float degrees) {
401        return native_preRotate(native_instance, degrees);
402    }
403
404    /**
405     * Preconcats the matrix with the specified skew.
406     * M' = M * K(kx, ky, px, py)
407     */
408    public boolean preSkew(float kx, float ky, float px, float py) {
409        return native_preSkew(native_instance, kx, ky, px, py);
410    }
411
412    /**
413     * Preconcats the matrix with the specified skew.
414     * M' = M * K(kx, ky)
415     */
416    public boolean preSkew(float kx, float ky) {
417        return native_preSkew(native_instance, kx, ky);
418    }
419
420    /**
421     * Preconcats the matrix with the specified matrix.
422     * M' = M * other
423     */
424    public boolean preConcat(Matrix other) {
425        return native_preConcat(native_instance, other.native_instance);
426    }
427
428    /**
429     * Postconcats the matrix with the specified translation.
430     * M' = T(dx, dy) * M
431     */
432    public boolean postTranslate(float dx, float dy) {
433        return native_postTranslate(native_instance, dx, dy);
434    }
435
436    /**
437     * Postconcats the matrix with the specified scale.
438     * M' = S(sx, sy, px, py) * M
439     */
440    public boolean postScale(float sx, float sy, float px, float py) {
441        return native_postScale(native_instance, sx, sy, px, py);
442    }
443
444    /**
445     * Postconcats the matrix with the specified scale.
446     * M' = S(sx, sy) * M
447     */
448    public boolean postScale(float sx, float sy) {
449        return native_postScale(native_instance, sx, sy);
450    }
451
452    /**
453     * Postconcats the matrix with the specified rotation.
454     * M' = R(degrees, px, py) * M
455     */
456    public boolean postRotate(float degrees, float px, float py) {
457        return native_postRotate(native_instance, degrees, px, py);
458    }
459
460    /**
461     * Postconcats the matrix with the specified rotation.
462     * M' = R(degrees) * M
463     */
464    public boolean postRotate(float degrees) {
465        return native_postRotate(native_instance, degrees);
466    }
467
468    /**
469     * Postconcats the matrix with the specified skew.
470     * M' = K(kx, ky, px, py) * M
471     */
472    public boolean postSkew(float kx, float ky, float px, float py) {
473        return native_postSkew(native_instance, kx, ky, px, py);
474    }
475
476    /**
477     * Postconcats the matrix with the specified skew.
478     * M' = K(kx, ky) * M
479     */
480    public boolean postSkew(float kx, float ky) {
481        return native_postSkew(native_instance, kx, ky);
482    }
483
484    /**
485     * Postconcats the matrix with the specified matrix.
486     * M' = other * M
487     */
488    public boolean postConcat(Matrix other) {
489        return native_postConcat(native_instance, other.native_instance);
490    }
491
492    /** Controlls how the src rect should align into the dst rect for
493        setRectToRect().
494    */
495    public enum ScaleToFit {
496        /**
497         * Scale in X and Y independently, so that src matches dst exactly.
498         * This may change the aspect ratio of the src.
499         */
500        FILL    (0),
501        /**
502         * Compute a scale that will maintain the original src aspect ratio,
503         * but will also ensure that src fits entirely inside dst. At least one
504         * axis (X or Y) will fit exactly. START aligns the result to the
505         * left and top edges of dst.
506         */
507        START   (1),
508        /**
509         * Compute a scale that will maintain the original src aspect ratio,
510         * but will also ensure that src fits entirely inside dst. At least one
511         * axis (X or Y) will fit exactly. The result is centered inside dst.
512         */
513        CENTER  (2),
514        /**
515         * Compute a scale that will maintain the original src aspect ratio,
516         * but will also ensure that src fits entirely inside dst. At least one
517         * axis (X or Y) will fit exactly. END aligns the result to the
518         * right and bottom edges of dst.
519         */
520        END     (3);
521
522        // the native values must match those in SkMatrix.h
523        ScaleToFit(int nativeInt) {
524            this.nativeInt = nativeInt;
525        }
526        final int nativeInt;
527    }
528
529    /**
530     * Set the matrix to the scale and translate values that map the source
531     * rectangle to the destination rectangle, returning true if the the result
532     * can be represented.
533     *
534     * @param src the source rectangle to map from.
535     * @param dst the destination rectangle to map to.
536     * @param stf the ScaleToFit option
537     * @return true if the matrix can be represented by the rectangle mapping.
538     */
539    public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
540        if (dst == null || src == null) {
541            throw new NullPointerException();
542        }
543        return native_setRectToRect(native_instance, src, dst, stf.nativeInt);
544    }
545
546    // private helper to perform range checks on arrays of "points"
547    private static void checkPointArrays(float[] src, int srcIndex,
548                                         float[] dst, int dstIndex,
549                                         int pointCount) {
550        // check for too-small and too-big indices
551        int srcStop = srcIndex + (pointCount << 1);
552        int dstStop = dstIndex + (pointCount << 1);
553        if ((pointCount | srcIndex | dstIndex | srcStop | dstStop) < 0 ||
554                srcStop > src.length || dstStop > dst.length) {
555            throw new ArrayIndexOutOfBoundsException();
556        }
557    }
558
559    /**
560     * Set the matrix such that the specified src points would map to the
561     * specified dst points. The "points" are represented as an array of floats,
562     * order [x0, y0, x1, y1, ...], where each "point" is 2 float values.
563     *
564     * @param src   The array of src [x,y] pairs (points)
565     * @param srcIndex Index of the first pair of src values
566     * @param dst   The array of dst [x,y] pairs (points)
567     * @param dstIndex Index of the first pair of dst values
568     * @param pointCount The number of pairs/points to be used. Must be [0..4]
569     * @return true if the matrix was set to the specified transformation
570     */
571    public boolean setPolyToPoly(float[] src, int srcIndex,
572                                 float[] dst, int dstIndex,
573                                 int pointCount) {
574        if (pointCount > 4) {
575            throw new IllegalArgumentException();
576        }
577        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
578        return native_setPolyToPoly(native_instance, src, srcIndex,
579                                    dst, dstIndex, pointCount);
580    }
581
582    /**
583     * If this matrix can be inverted, return true and if inverse is not null,
584     * set inverse to be the inverse of this matrix. If this matrix cannot be
585     * inverted, ignore inverse and return false.
586     */
587    public boolean invert(Matrix inverse) {
588        return native_invert(native_instance, inverse.native_instance);
589    }
590
591    /**
592    * Apply this matrix to the array of 2D points specified by src, and write
593     * the transformed points into the array of points specified by dst. The
594     * two arrays represent their "points" as pairs of floats [x, y].
595     *
596     * @param dst   The array of dst points (x,y pairs)
597     * @param dstIndex The index of the first [x,y] pair of dst floats
598     * @param src   The array of src points (x,y pairs)
599     * @param srcIndex The index of the first [x,y] pair of src floats
600     * @param pointCount The number of points (x,y pairs) to transform
601     */
602    public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
603                          int pointCount) {
604        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
605        native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
606                         pointCount, true);
607    }
608
609    /**
610    * Apply this matrix to the array of 2D vectors specified by src, and write
611     * the transformed vectors into the array of vectors specified by dst. The
612     * two arrays represent their "vectors" as pairs of floats [x, y].
613     *
614     * Note: this method does not apply the translation associated with the matrix. Use
615     * {@link Matrix#mapPoints(float[], int, float[], int, int)} if you want the translation
616     * to be applied.
617     *
618     * @param dst   The array of dst vectors (x,y pairs)
619     * @param dstIndex The index of the first [x,y] pair of dst floats
620     * @param src   The array of src vectors (x,y pairs)
621     * @param srcIndex The index of the first [x,y] pair of src floats
622     * @param vectorCount The number of vectors (x,y pairs) to transform
623     */
624    public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,
625                          int vectorCount) {
626        checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount);
627        native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
628                         vectorCount, false);
629    }
630
631    /**
632     * Apply this matrix to the array of 2D points specified by src, and write
633     * the transformed points into the array of points specified by dst. The
634     * two arrays represent their "points" as pairs of floats [x, y].
635     *
636     * @param dst   The array of dst points (x,y pairs)
637     * @param src   The array of src points (x,y pairs)
638     */
639    public void mapPoints(float[] dst, float[] src) {
640        if (dst.length != src.length) {
641            throw new ArrayIndexOutOfBoundsException();
642        }
643        mapPoints(dst, 0, src, 0, dst.length >> 1);
644    }
645
646    /**
647     * Apply this matrix to the array of 2D vectors specified by src, and write
648     * the transformed vectors into the array of vectors specified by dst. The
649     * two arrays represent their "vectors" as pairs of floats [x, y].
650     *
651     * Note: this method does not apply the translation associated with the matrix. Use
652     * {@link Matrix#mapPoints(float[], float[])} if you want the translation to be applied.
653     *
654     * @param dst   The array of dst vectors (x,y pairs)
655     * @param src   The array of src vectors (x,y pairs)
656     */
657    public void mapVectors(float[] dst, float[] src) {
658        if (dst.length != src.length) {
659            throw new ArrayIndexOutOfBoundsException();
660        }
661        mapVectors(dst, 0, src, 0, dst.length >> 1);
662    }
663
664    /**
665     * Apply this matrix to the array of 2D points, and write the transformed
666     * points back into the array
667     *
668     * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
669     */
670    public void mapPoints(float[] pts) {
671        mapPoints(pts, 0, pts, 0, pts.length >> 1);
672    }
673
674    /**
675     * Apply this matrix to the array of 2D vectors, and write the transformed
676     * vectors back into the array.
677     *
678     * Note: this method does not apply the translation associated with the matrix. Use
679     * {@link Matrix#mapPoints(float[])} if you want the translation to be applied.
680     *
681     * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform.
682     */
683    public void mapVectors(float[] vecs) {
684        mapVectors(vecs, 0, vecs, 0, vecs.length >> 1);
685    }
686
687    /**
688     * Apply this matrix to the src rectangle, and write the transformed
689     * rectangle into dst. This is accomplished by transforming the 4 corners of
690     * src, and then setting dst to the bounds of those points.
691     *
692     * @param dst Where the transformed rectangle is written.
693     * @param src The original rectangle to be transformed.
694     * @return the result of calling rectStaysRect()
695     */
696    public boolean mapRect(RectF dst, RectF src) {
697        if (dst == null || src == null) {
698            throw new NullPointerException();
699        }
700        return native_mapRect(native_instance, dst, src);
701    }
702
703    /**
704     * Apply this matrix to the rectangle, and write the transformed rectangle
705     * back into it. This is accomplished by transforming the 4 corners of rect,
706     * and then setting it to the bounds of those points
707     *
708     * @param rect The rectangle to transform.
709     * @return the result of calling rectStaysRect()
710     */
711    public boolean mapRect(RectF rect) {
712        return mapRect(rect, rect);
713    }
714
715    /**
716     * Return the mean radius of a circle after it has been mapped by
717     * this matrix. NOTE: in perspective this value assumes the circle
718     * has its center at the origin.
719     */
720    public float mapRadius(float radius) {
721        return native_mapRadius(native_instance, radius);
722    }
723
724    /** Copy 9 values from the matrix into the array.
725    */
726    public void getValues(float[] values) {
727        if (values.length < 9) {
728            throw new ArrayIndexOutOfBoundsException();
729        }
730        native_getValues(native_instance, values);
731    }
732
733    /** Copy 9 values from the array into the matrix.
734        Depending on the implementation of Matrix, these may be
735        transformed into 16.16 integers in the Matrix, such that
736        a subsequent call to getValues() will not yield exactly
737        the same values.
738    */
739    public void setValues(float[] values) {
740        if (values.length < 9) {
741            throw new ArrayIndexOutOfBoundsException();
742        }
743        native_setValues(native_instance, values);
744    }
745
746    @Override
747    public String toString() {
748        StringBuilder sb = new StringBuilder(64);
749        sb.append("Matrix{");
750        toShortString(sb);
751        sb.append('}');
752        return sb.toString();
753
754    }
755
756    public String toShortString() {
757        StringBuilder sb = new StringBuilder(64);
758        toShortString(sb);
759        return sb.toString();
760    }
761
762    /**
763     * @hide
764     */
765    public void toShortString(StringBuilder sb) {
766        float[] values = new float[9];
767        getValues(values);
768        sb.append('[');
769        sb.append(values[0]); sb.append(", "); sb.append(values[1]); sb.append(", ");
770        sb.append(values[2]); sb.append("][");
771        sb.append(values[3]); sb.append(", "); sb.append(values[4]); sb.append(", ");
772        sb.append(values[5]); sb.append("][");
773        sb.append(values[6]); sb.append(", "); sb.append(values[7]); sb.append(", ");
774        sb.append(values[8]); sb.append(']');
775    }
776
777    /**
778     * Print short string, to optimize dumping.
779     * @hide
780     */
781    public void printShortString(PrintWriter pw) {
782        float[] values = new float[9];
783        getValues(values);
784        pw.print('[');
785        pw.print(values[0]); pw.print(", "); pw.print(values[1]); pw.print(", ");
786                pw.print(values[2]); pw.print("][");
787        pw.print(values[3]); pw.print(", "); pw.print(values[4]); pw.print(", ");
788                pw.print(values[5]); pw.print("][");
789        pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", ");
790                pw.print(values[8]); pw.print(']');
791
792    }
793
794    @Override
795    protected void finalize() throws Throwable {
796        try {
797            finalizer(native_instance);
798        } finally {
799            super.finalize();
800        }
801    }
802
803    /*package*/ final long ni() {
804        return native_instance;
805    }
806
807    private static native long native_create(long native_src_or_zero);
808    private static native boolean native_isIdentity(long native_object);
809    private static native boolean native_rectStaysRect(long native_object);
810    private static native void native_reset(long native_object);
811    private static native void native_set(long native_object,
812                                          long native_other);
813    private static native void native_setTranslate(long native_object,
814                                                   float dx, float dy);
815    private static native void native_setScale(long native_object,
816                                        float sx, float sy, float px, float py);
817    private static native void native_setScale(long native_object,
818                                               float sx, float sy);
819    private static native void native_setRotate(long native_object,
820                                            float degrees, float px, float py);
821    private static native void native_setRotate(long native_object,
822                                                float degrees);
823    private static native void native_setSinCos(long native_object,
824                            float sinValue, float cosValue, float px, float py);
825    private static native void native_setSinCos(long native_object,
826                                                float sinValue, float cosValue);
827    private static native void native_setSkew(long native_object,
828                                        float kx, float ky, float px, float py);
829    private static native void native_setSkew(long native_object,
830                                              float kx, float ky);
831    private static native boolean native_setConcat(long native_object,
832                                                   long native_a,
833                                                   long native_b);
834    private static native boolean native_preTranslate(long native_object,
835                                                      float dx, float dy);
836    private static native boolean native_preScale(long native_object,
837                                        float sx, float sy, float px, float py);
838    private static native boolean native_preScale(long native_object,
839                                                  float sx, float sy);
840    private static native boolean native_preRotate(long native_object,
841                                            float degrees, float px, float py);
842    private static native boolean native_preRotate(long native_object,
843                                                   float degrees);
844    private static native boolean native_preSkew(long native_object,
845                                        float kx, float ky, float px, float py);
846    private static native boolean native_preSkew(long native_object,
847                                                 float kx, float ky);
848    private static native boolean native_preConcat(long native_object,
849                                                   long native_other_matrix);
850    private static native boolean native_postTranslate(long native_object,
851                                                       float dx, float dy);
852    private static native boolean native_postScale(long native_object,
853                                        float sx, float sy, float px, float py);
854    private static native boolean native_postScale(long native_object,
855                                                   float sx, float sy);
856    private static native boolean native_postRotate(long native_object,
857                                            float degrees, float px, float py);
858    private static native boolean native_postRotate(long native_object,
859                                                    float degrees);
860    private static native boolean native_postSkew(long native_object,
861                                        float kx, float ky, float px, float py);
862    private static native boolean native_postSkew(long native_object,
863                                                  float kx, float ky);
864    private static native boolean native_postConcat(long native_object,
865                                                    long native_other_matrix);
866    private static native boolean native_setRectToRect(long native_object,
867                                                RectF src, RectF dst, int stf);
868    private static native boolean native_setPolyToPoly(long native_object,
869        float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount);
870    private static native boolean native_invert(long native_object,
871                                                long native_inverse);
872    private static native void native_mapPoints(long native_object,
873                        float[] dst, int dstIndex, float[] src, int srcIndex,
874                        int ptCount, boolean isPts);
875    private static native boolean native_mapRect(long native_object,
876                                                 RectF dst, RectF src);
877    private static native float native_mapRadius(long native_object,
878                                                 float radius);
879    private static native void native_getValues(long native_object,
880                                                float[] values);
881    private static native void native_setValues(long native_object,
882                                                float[] values);
883    private static native boolean native_equals(long native_a, long native_b);
884    private static native void finalizer(long native_instance);
885}
886