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