/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics;

import android.compat.annotation.UnsupportedAppUsage;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

import libcore.util.NativeAllocationRegistry;

import java.io.PrintWriter;

/**
 * The Matrix class holds a 3x3 matrix for transforming coordinates.
 */
public class Matrix {

    public static final int MSCALE_X = 0;   //!< use with getValues/setValues
    public static final int MSKEW_X  = 1;   //!< use with getValues/setValues
    public static final int MTRANS_X = 2;   //!< use with getValues/setValues
    public static final int MSKEW_Y  = 3;   //!< use with getValues/setValues
    public static final int MSCALE_Y = 4;   //!< use with getValues/setValues
    public static final int MTRANS_Y = 5;   //!< use with getValues/setValues
    public static final int MPERSP_0 = 6;   //!< use with getValues/setValues
    public static final int MPERSP_1 = 7;   //!< use with getValues/setValues
    public static final int MPERSP_2 = 8;   //!< use with getValues/setValues

    /** @hide */
    @UnsupportedAppUsage
    public final static Matrix IDENTITY_MATRIX = new Matrix() {
        void oops() {
            throw new IllegalStateException("Matrix can not be modified");
        }

        @Override
        public void set(Matrix src) {
            oops();
        }

        @Override
        public void reset() {
            oops();
        }

        @Override
        public void setTranslate(float dx, float dy) {
            oops();
        }

        @Override
        public void setScale(float sx, float sy, float px, float py) {
            oops();
        }

        @Override
        public void setScale(float sx, float sy) {
            oops();
        }

        @Override
        public void setRotate(float degrees, float px, float py) {
            oops();
        }

        @Override
        public void setRotate(float degrees) {
            oops();
        }

        @Override
        public void setSinCos(float sinValue, float cosValue, float px, float py) {
            oops();
        }

        @Override
        public void setSinCos(float sinValue, float cosValue) {
            oops();
        }

        @Override
        public void setSkew(float kx, float ky, float px, float py) {
            oops();
        }

        @Override
        public void setSkew(float kx, float ky) {
            oops();
        }

        @Override
        public boolean setConcat(Matrix a, Matrix b) {
            oops();
            return false;
        }

        @Override
        public boolean preTranslate(float dx, float dy) {
            oops();
            return false;
        }

        @Override
        public boolean preScale(float sx, float sy, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean preScale(float sx, float sy) {
            oops();
            return false;
        }

        @Override
        public boolean preRotate(float degrees, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean preRotate(float degrees) {
            oops();
            return false;
        }

        @Override
        public boolean preSkew(float kx, float ky, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean preSkew(float kx, float ky) {
            oops();
            return false;
        }

        @Override
        public boolean preConcat(Matrix other) {
            oops();
            return false;
        }

        @Override
        public boolean postTranslate(float dx, float dy) {
            oops();
            return false;
        }

        @Override
        public boolean postScale(float sx, float sy, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean postScale(float sx, float sy) {
            oops();
            return false;
        }

        @Override
        public boolean postRotate(float degrees, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean postRotate(float degrees) {
            oops();
            return false;
        }

        @Override
        public boolean postSkew(float kx, float ky, float px, float py) {
            oops();
            return false;
        }

        @Override
        public boolean postSkew(float kx, float ky) {
            oops();
            return false;
        }

        @Override
        public boolean postConcat(Matrix other) {
            oops();
            return false;
        }

        @Override
        public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
            oops();
            return false;
        }

        @Override
        public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex,
                int pointCount) {
            oops();
            return false;
        }

        @Override
        public void setValues(float[] values) {
            oops();
        }
    };

    private static class NoImagePreloadHolder {
        public static final NativeAllocationRegistry sRegistry =
                NativeAllocationRegistry.createMalloced(
                Matrix.class.getClassLoader(), nGetNativeFinalizer());
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public final long native_instance;

    /**
     * Create an identity matrix
     */
    public Matrix() {
        native_instance = nCreate(0);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, native_instance);
    }

    /**
     * Create a matrix that is a (deep) copy of src
     *
     * @param src The matrix to copy into this matrix
     */
    public Matrix(Matrix src) {
        native_instance = nCreate(src != null ? src.native_instance : 0);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, native_instance);
    }

    /**
     * Returns true if the matrix is identity. This maybe faster than testing if (getType() == 0)
     */
    public boolean isIdentity() {
        return nIsIdentity(native_instance);
    }

    /**
     * Gets whether this matrix is affine. An affine matrix preserves straight lines and has no
     * perspective.
     *
     * @return Whether the matrix is affine.
     */
    public boolean isAffine() {
        return nIsAffine(native_instance);
    }

    /**
     * Returns true if will map a rectangle to another rectangle. This can be true if the matrix is
     * identity, scale-only, or rotates a multiple of 90 degrees.
     */
    public boolean rectStaysRect() {
        return nRectStaysRect(native_instance);
    }

    /**
     * (deep) copy the src matrix into this matrix. If src is null, reset this matrix to the
     * identity matrix.
     */
    public void set(Matrix src) {
        if (src == null) {
            reset();
        } else {
            nSet(native_instance, src.native_instance);
        }
    }

    /**
     * Returns true iff obj is a Matrix and its values equal our values.
     */
    @Override
    public boolean equals(Object obj) {
        // if (obj == this) return true; -- NaN value would mean matrix != itself
        if (!(obj instanceof Matrix)) {
            return false;
        }
        return nEquals(native_instance, ((Matrix) obj).native_instance);
    }

    @Override
    public int hashCode() {
        // This should generate the hash code by performing some arithmetic operation on all
        // the matrix elements -- our equals() does an element-by-element comparison, and we
        // need to ensure that the hash code for two equal objects is the same. We're not
        // really using this at the moment, so we take the easy way out.
        return 44;
    }

    /** Set the matrix to identity */
    public void reset() {
        nReset(native_instance);
    }

    /** Set the matrix to translate by (dx, dy). */
    public void setTranslate(float dx, float dy) {
        nSetTranslate(native_instance, dx, dy);
    }

    /**
     * Set the matrix to scale by sx and sy, with a pivot point at (px, py). The pivot point is the
     * coordinate that should remain unchanged by the specified transformation.
     */
    public void setScale(float sx, float sy, float px, float py) {
        nSetScale(native_instance, sx, sy, px, py);
    }

    /** Set the matrix to scale by sx and sy. */
    public void setScale(float sx, float sy) {
        nSetScale(native_instance, sx, sy);
    }

    /**
     * Set the matrix to rotate by the specified number of degrees, with a pivot point at (px, py).
     * The pivot point is the coordinate that should remain unchanged by the specified
     * transformation.
     */
    public void setRotate(float degrees, float px, float py) {
        nSetRotate(native_instance, degrees, px, py);
    }

    /**
     * Set the matrix to rotate about (0,0) by the specified number of degrees.
     */
    public void setRotate(float degrees) {
        nSetRotate(native_instance, degrees);
    }

    /**
     * Set the matrix to rotate by the specified sine and cosine values, with a pivot point at (px,
     * py). The pivot point is the coordinate that should remain unchanged by the specified
     * transformation.
     */
    public void setSinCos(float sinValue, float cosValue, float px, float py) {
        nSetSinCos(native_instance, sinValue, cosValue, px, py);
    }

    /** Set the matrix to rotate by the specified sine and cosine values. */
    public void setSinCos(float sinValue, float cosValue) {
        nSetSinCos(native_instance, sinValue, cosValue);
    }

    /**
     * Set the matrix to skew by sx and sy, with a pivot point at (px, py). The pivot point is the
     * coordinate that should remain unchanged by the specified transformation.
     */
    public void setSkew(float kx, float ky, float px, float py) {
        nSetSkew(native_instance, kx, ky, px, py);
    }

    /** Set the matrix to skew by sx and sy. */
    public void setSkew(float kx, float ky) {
        nSetSkew(native_instance, kx, ky);
    }

    /**
     * Set the matrix to the concatenation of the two specified matrices and return true.
     * <p>
     * Either of the two matrices may also be the target matrix, that is
     * <code>matrixA.setConcat(matrixA, matrixB);</code> is valid.
     * </p>
     * <p class="note">
     * In {@link android.os.Build.VERSION_CODES#GINGERBREAD_MR1} and below, this function returns
     * true only if the result can be represented. In
     * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and above, it always returns true.
     * </p>
     */
    public boolean setConcat(Matrix a, Matrix b) {
        nSetConcat(native_instance, a.native_instance, b.native_instance);
        return true;
    }

    /**
     * Preconcats the matrix with the specified translation. M' = M * T(dx, dy)
     */
    public boolean preTranslate(float dx, float dy) {
        nPreTranslate(native_instance, dx, dy);
        return true;
    }

    /**
     * Preconcats the matrix with the specified scale. M' = M * S(sx, sy, px, py)
     */
    public boolean preScale(float sx, float sy, float px, float py) {
        nPreScale(native_instance, sx, sy, px, py);
        return true;
    }

    /**
     * Preconcats the matrix with the specified scale. M' = M * S(sx, sy)
     */
    public boolean preScale(float sx, float sy) {
        nPreScale(native_instance, sx, sy);
        return true;
    }

    /**
     * Preconcats the matrix with the specified rotation. M' = M * R(degrees, px, py)
     */
    public boolean preRotate(float degrees, float px, float py) {
        nPreRotate(native_instance, degrees, px, py);
        return true;
    }

    /**
     * Preconcats the matrix with the specified rotation. M' = M * R(degrees)
     */
    public boolean preRotate(float degrees) {
        nPreRotate(native_instance, degrees);
        return true;
    }

    /**
     * Preconcats the matrix with the specified skew. M' = M * K(kx, ky, px, py)
     */
    public boolean preSkew(float kx, float ky, float px, float py) {
        nPreSkew(native_instance, kx, ky, px, py);
        return true;
    }

    /**
     * Preconcats the matrix with the specified skew. M' = M * K(kx, ky)
     */
    public boolean preSkew(float kx, float ky) {
        nPreSkew(native_instance, kx, ky);
        return true;
    }

    /**
     * Preconcats the matrix with the specified matrix. M' = M * other
     */
    public boolean preConcat(Matrix other) {
        nPreConcat(native_instance, other.native_instance);
        return true;
    }

    /**
     * Postconcats the matrix with the specified translation. M' = T(dx, dy) * M
     */
    public boolean postTranslate(float dx, float dy) {
        nPostTranslate(native_instance, dx, dy);
        return true;
    }

    /**
     * Postconcats the matrix with the specified scale. M' = S(sx, sy, px, py) * M
     */
    public boolean postScale(float sx, float sy, float px, float py) {
        nPostScale(native_instance, sx, sy, px, py);
        return true;
    }

    /**
     * Postconcats the matrix with the specified scale. M' = S(sx, sy) * M
     */
    public boolean postScale(float sx, float sy) {
        nPostScale(native_instance, sx, sy);
        return true;
    }

    /**
     * Postconcats the matrix with the specified rotation. M' = R(degrees, px, py) * M
     */
    public boolean postRotate(float degrees, float px, float py) {
        nPostRotate(native_instance, degrees, px, py);
        return true;
    }

    /**
     * Postconcats the matrix with the specified rotation. M' = R(degrees) * M
     */
    public boolean postRotate(float degrees) {
        nPostRotate(native_instance, degrees);
        return true;
    }

    /**
     * Postconcats the matrix with the specified skew. M' = K(kx, ky, px, py) * M
     */
    public boolean postSkew(float kx, float ky, float px, float py) {
        nPostSkew(native_instance, kx, ky, px, py);
        return true;
    }

    /**
     * Postconcats the matrix with the specified skew. M' = K(kx, ky) * M
     */
    public boolean postSkew(float kx, float ky) {
        nPostSkew(native_instance, kx, ky);
        return true;
    }

    /**
     * Postconcats the matrix with the specified matrix. M' = other * M
     */
    public boolean postConcat(Matrix other) {
        nPostConcat(native_instance, other.native_instance);
        return true;
    }

    /**
     * Controlls how the src rect should align into the dst rect for setRectToRect().
     */
    public enum ScaleToFit {
        /**
         * Scale in X and Y independently, so that src matches dst exactly. This may change the
         * aspect ratio of the src.
         */
        FILL(0),
        /**
         * Compute a scale that will maintain the original src aspect ratio, but will also ensure
         * that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. START
         * aligns the result to the left and top edges of dst.
         */
        START(1),
        /**
         * Compute a scale that will maintain the original src aspect ratio, but will also ensure
         * that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. The
         * result is centered inside dst.
         */
        CENTER(2),
        /**
         * Compute a scale that will maintain the original src aspect ratio, but will also ensure
         * that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. END
         * aligns the result to the right and bottom edges of dst.
         */
        END(3);

        // the native values must match those in SkMatrix.h
        ScaleToFit(int nativeInt) {
            this.nativeInt = nativeInt;
        }

        final int nativeInt;
    }

    /**
     * Set the matrix to the scale and translate values that map the source rectangle to the
     * destination rectangle, returning true if the the result can be represented.
     *
     * @param src the source rectangle to map from.
     * @param dst the destination rectangle to map to.
     * @param stf the ScaleToFit option
     * @return true if the matrix can be represented by the rectangle mapping.
     */
    public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
        if (dst == null || src == null) {
            throw new NullPointerException();
        }
        return nSetRectToRect(native_instance, src, dst, stf.nativeInt);
    }

    // private helper to perform range checks on arrays of "points"
    private static void checkPointArrays(float[] src, int srcIndex,
            float[] dst, int dstIndex,
            int pointCount) {
        // check for too-small and too-big indices
        int srcStop = srcIndex + (pointCount << 1);
        int dstStop = dstIndex + (pointCount << 1);
        if ((pointCount | srcIndex | dstIndex | srcStop | dstStop) < 0 ||
                srcStop > src.length || dstStop > dst.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    /**
     * Set the matrix such that the specified src points would map to the specified dst points. The
     * "points" are represented as an array of floats, order [x0, y0, x1, y1, ...], where each
     * "point" is 2 float values.
     *
     * @param src The array of src [x,y] pairs (points)
     * @param srcIndex Index of the first pair of src values
     * @param dst The array of dst [x,y] pairs (points)
     * @param dstIndex Index of the first pair of dst values
     * @param pointCount The number of pairs/points to be used. Must be [0..4]
     * @return true if the matrix was set to the specified transformation
     */
    public boolean setPolyToPoly(float[] src, int srcIndex,
            float[] dst, int dstIndex,
            int pointCount) {
        if (pointCount > 4) {
            throw new IllegalArgumentException();
        }
        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
        return nSetPolyToPoly(native_instance, src, srcIndex,
                dst, dstIndex, pointCount);
    }

    /**
     * If this matrix can be inverted, return true and if inverse is not null, set inverse to be the
     * inverse of this matrix. If this matrix cannot be inverted, ignore inverse and return false.
     */
    public boolean invert(Matrix inverse) {
        return nInvert(native_instance, inverse.native_instance);
    }

    /**
     * Apply this matrix to the array of 2D points specified by src, and write the transformed
     * points into the array of points specified by dst. The two arrays represent their "points" as
     * pairs of floats [x, y].
     *
     * @param dst The array of dst points (x,y pairs)
     * @param dstIndex The index of the first [x,y] pair of dst floats
     * @param src The array of src points (x,y pairs)
     * @param srcIndex The index of the first [x,y] pair of src floats
     * @param pointCount The number of points (x,y pairs) to transform
     */
    public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
            int pointCount) {
        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
        nMapPoints(native_instance, dst, dstIndex, src, srcIndex,
                pointCount, true);
    }

    /**
     * Apply this matrix to the array of 2D vectors specified by src, and write the transformed
     * vectors into the array of vectors specified by dst. The two arrays represent their "vectors"
     * as pairs of floats [x, y]. Note: this method does not apply the translation associated with
     * the matrix. Use {@link Matrix#mapPoints(float[], int, float[], int, int)} if you want the
     * translation to be applied.
     *
     * @param dst The array of dst vectors (x,y pairs)
     * @param dstIndex The index of the first [x,y] pair of dst floats
     * @param src The array of src vectors (x,y pairs)
     * @param srcIndex The index of the first [x,y] pair of src floats
     * @param vectorCount The number of vectors (x,y pairs) to transform
     */
    public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,
            int vectorCount) {
        checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount);
        nMapPoints(native_instance, dst, dstIndex, src, srcIndex,
                vectorCount, false);
    }

    /**
     * Apply this matrix to the array of 2D points specified by src, and write the transformed
     * points into the array of points specified by dst. The two arrays represent their "points" as
     * pairs of floats [x, y].
     *
     * @param dst The array of dst points (x,y pairs)
     * @param src The array of src points (x,y pairs)
     */
    public void mapPoints(float[] dst, float[] src) {
        if (dst.length != src.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        mapPoints(dst, 0, src, 0, dst.length >> 1);
    }

    /**
     * Apply this matrix to the array of 2D vectors specified by src, and write the transformed
     * vectors into the array of vectors specified by dst. The two arrays represent their "vectors"
     * as pairs of floats [x, y]. Note: this method does not apply the translation associated with
     * the matrix. Use {@link Matrix#mapPoints(float[], float[])} if you want the translation to be
     * applied.
     *
     * @param dst The array of dst vectors (x,y pairs)
     * @param src The array of src vectors (x,y pairs)
     */
    public void mapVectors(float[] dst, float[] src) {
        if (dst.length != src.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        mapVectors(dst, 0, src, 0, dst.length >> 1);
    }

    /**
     * Apply this matrix to the array of 2D points, and write the transformed points back into the
     * array
     *
     * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
     */
    public void mapPoints(float[] pts) {
        mapPoints(pts, 0, pts, 0, pts.length >> 1);
    }

    /**
     * Apply this matrix to the array of 2D vectors, and write the transformed vectors back into the
     * array. Note: this method does not apply the translation associated with the matrix. Use
     * {@link Matrix#mapPoints(float[])} if you want the translation to be applied.
     *
     * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform.
     */
    public void mapVectors(float[] vecs) {
        mapVectors(vecs, 0, vecs, 0, vecs.length >> 1);
    }

    /**
     * Apply this matrix to the src rectangle, and write the transformed rectangle into dst. This is
     * accomplished by transforming the 4 corners of src, and then setting dst to the bounds of
     * those points.
     *
     * @param dst Where the transformed rectangle is written.
     * @param src The original rectangle to be transformed.
     * @return the result of calling rectStaysRect()
     */
    public boolean mapRect(RectF dst, RectF src) {
        if (dst == null || src == null) {
            throw new NullPointerException();
        }
        return nMapRect(native_instance, dst, src);
    }

    /**
     * Apply this matrix to the rectangle, and write the transformed rectangle back into it. This is
     * accomplished by transforming the 4 corners of rect, and then setting it to the bounds of
     * those points
     *
     * @param rect The rectangle to transform.
     * @return the result of calling rectStaysRect()
     */
    public boolean mapRect(RectF rect) {
        return mapRect(rect, rect);
    }

    /**
     * Return the mean radius of a circle after it has been mapped by this matrix. NOTE: in
     * perspective this value assumes the circle has its center at the origin.
     */
    public float mapRadius(float radius) {
        return nMapRadius(native_instance, radius);
    }

    /**
     * Copy 9 values from the matrix into the array.
     */
    public void getValues(float[] values) {
        if (values.length < 9) {
            throw new ArrayIndexOutOfBoundsException();
        }
        nGetValues(native_instance, values);
    }

    /**
     * Copy 9 values from the array into the matrix. Depending on the implementation of Matrix,
     * these may be transformed into 16.16 integers in the Matrix, such that a subsequent call to
     * getValues() will not yield exactly the same values.
     */
    public void setValues(float[] values) {
        if (values.length < 9) {
            throw new ArrayIndexOutOfBoundsException();
        }
        nSetValues(native_instance, values);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(64);
        sb.append("Matrix{");
        toShortString(sb);
        sb.append('}');
        return sb.toString();

    }

    public String toShortString() {
        StringBuilder sb = new StringBuilder(64);
        toShortString(sb);
        return sb.toString();
    }

    /**
     * @hide
     */
    public void toShortString(StringBuilder sb) {
        float[] values = new float[9];
        getValues(values);
        sb.append('[');
        sb.append(values[0]);
        sb.append(", ");
        sb.append(values[1]);
        sb.append(", ");
        sb.append(values[2]);
        sb.append("][");
        sb.append(values[3]);
        sb.append(", ");
        sb.append(values[4]);
        sb.append(", ");
        sb.append(values[5]);
        sb.append("][");
        sb.append(values[6]);
        sb.append(", ");
        sb.append(values[7]);
        sb.append(", ");
        sb.append(values[8]);
        sb.append(']');
    }

    /**
     * Print short string, to optimize dumping.
     *
     * @hide
     */
    public void printShortString(PrintWriter pw) {
        float[] values = new float[9];
        getValues(values);
        pw.print('[');
        pw.print(values[0]);
        pw.print(", ");
        pw.print(values[1]);
        pw.print(", ");
        pw.print(values[2]);
        pw.print("][");
        pw.print(values[3]);
        pw.print(", ");
        pw.print(values[4]);
        pw.print(", ");
        pw.print(values[5]);
        pw.print("][");
        pw.print(values[6]);
        pw.print(", ");
        pw.print(values[7]);
        pw.print(", ");
        pw.print(values[8]);
        pw.print(']');

    }

    /** @hide */
    public final long ni() {
        return native_instance;
    }

    // ------------------ Regular JNI ------------------------

    private static native long nCreate(long nSrc_or_zero);
    private static native long nGetNativeFinalizer();


    // ------------------ Fast JNI ------------------------

    @FastNative
    private static native boolean nSetRectToRect(long nObject,
            RectF src, RectF dst, int stf);
    @FastNative
    private static native boolean nSetPolyToPoly(long nObject,
            float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount);
    @FastNative
    private static native void nMapPoints(long nObject,
            float[] dst, int dstIndex, float[] src, int srcIndex,
            int ptCount, boolean isPts);
    @FastNative
    private static native boolean nMapRect(long nObject, RectF dst, RectF src);
    @FastNative
    private static native void nGetValues(long nObject, float[] values);
    @FastNative
    private static native void nSetValues(long nObject, float[] values);


    // ------------------ Critical JNI ------------------------

    @CriticalNative
    private static native boolean nIsIdentity(long nObject);
    @CriticalNative
    private static native boolean nIsAffine(long nObject);
    @CriticalNative
    private static native boolean nRectStaysRect(long nObject);
    @CriticalNative
    private static native void nReset(long nObject);
    @CriticalNative
    private static native void nSet(long nObject, long nOther);
    @CriticalNative
    private static native void nSetTranslate(long nObject, float dx, float dy);
    @CriticalNative
    private static native void nSetScale(long nObject, float sx, float sy, float px, float py);
    @CriticalNative
    private static native void nSetScale(long nObject, float sx, float sy);
    @CriticalNative
    private static native void nSetRotate(long nObject, float degrees, float px, float py);
    @CriticalNative
    private static native void nSetRotate(long nObject, float degrees);
    @CriticalNative
    private static native void nSetSinCos(long nObject, float sinValue, float cosValue,
            float px, float py);
    @CriticalNative
    private static native void nSetSinCos(long nObject, float sinValue, float cosValue);
    @CriticalNative
    private static native void nSetSkew(long nObject, float kx, float ky, float px, float py);
    @CriticalNative
    private static native void nSetSkew(long nObject, float kx, float ky);
    @CriticalNative
    private static native void nSetConcat(long nObject, long nA, long nB);
    @CriticalNative
    private static native void nPreTranslate(long nObject, float dx, float dy);
    @CriticalNative
    private static native void nPreScale(long nObject, float sx, float sy, float px, float py);
    @CriticalNative
    private static native void nPreScale(long nObject, float sx, float sy);
    @CriticalNative
    private static native void nPreRotate(long nObject, float degrees, float px, float py);
    @CriticalNative
    private static native void nPreRotate(long nObject, float degrees);
    @CriticalNative
    private static native void nPreSkew(long nObject, float kx, float ky, float px, float py);
    @CriticalNative
    private static native void nPreSkew(long nObject, float kx, float ky);
    @CriticalNative
    private static native void nPreConcat(long nObject, long nOther_matrix);
    @CriticalNative
    private static native void nPostTranslate(long nObject, float dx, float dy);
    @CriticalNative
    private static native void nPostScale(long nObject, float sx, float sy, float px, float py);
    @CriticalNative
    private static native void nPostScale(long nObject, float sx, float sy);
    @CriticalNative
    private static native void nPostRotate(long nObject, float degrees, float px, float py);
    @CriticalNative
    private static native void nPostRotate(long nObject, float degrees);
    @CriticalNative
    private static native void nPostSkew(long nObject, float kx, float ky, float px, float py);
    @CriticalNative
    private static native void nPostSkew(long nObject, float kx, float ky);
    @CriticalNative
    private static native void nPostConcat(long nObject, long nOther_matrix);
    @CriticalNative
    private static native boolean nInvert(long nObject, long nInverse);
    @CriticalNative
    private static native float nMapRadius(long nObject, float radius);
    @CriticalNative
    private static native boolean nEquals(long nA, long nB);
}
