19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Interpolator {
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Interpolator(int valueCount) {
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mValueCount = valueCount;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFrameCount = 2;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        native_instance = nativeConstructor(valueCount, 2);
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Interpolator(int valueCount, int frameCount) {
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mValueCount = valueCount;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFrameCount = frameCount;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        native_instance = nativeConstructor(valueCount, frameCount);
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Reset the Interpolator to have the specified number of values and an
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implicit keyFrame count of 2 (just a start and end). After this call the
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values for each keyFrame must be assigned using setKeyFrame().
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reset(int valueCount) {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        reset(valueCount, 2);
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Reset the Interpolator to have the specified number of values and
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * keyFrames. After this call the values for each keyFrame must be assigned
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * using setKeyFrame().
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reset(int valueCount, int frameCount) {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mValueCount = valueCount;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFrameCount = frameCount;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeReset(native_instance, valueCount, frameCount);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getKeyFrameCount() {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFrameCount;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getValueCount() {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mValueCount;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Assign the keyFrame (specified by index) a time value and an array of key
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values (with an implicity blend array of [0, 0, 1, 1] giving linear
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * transition to the next set of key values).
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the key frame to assign
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param msec The time (in mililiseconds) for this key frame. Based on the
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        SystemClock.uptimeMillis() clock
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values Array of values associated with theis key frame
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setKeyFrame(int index, int msec, float[] values) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setKeyFrame(index, msec, values, null);
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Assign the keyFrame (specified by index) a time value and an array of key
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values and blend array.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the key frame to assign
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param msec The time (in mililiseconds) for this key frame. Based on the
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        SystemClock.uptimeMillis() clock
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values Array of values associated with theis key frame
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param blend (may be null) Optional array of 4 blend values
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setKeyFrame(int index, int msec, float[] values, float[] blend) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0 || index >= mFrameCount) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (values.length < mValueCount) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayStoreException();
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (blend != null && blend.length < 4) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayStoreException();
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeSetKeyFrame(native_instance, index, msec, values, blend);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a repeat count (which may be fractional) for the interpolator, and
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * whether the interpolator should mirror its repeats. The default settings
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are repeatCount = 1, and mirror = false.
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setRepeatMirror(float repeatCount, boolean mirror) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (repeatCount >= 0) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nativeSetRepeatMirror(native_instance, repeatCount, mirror);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Result {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NORMAL,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FREEZE_START,
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FREEZE_END
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Calls timeToValues(msec, values) with the msec set to now (by calling
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (int)SystemClock.uptimeMillis().)
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Result timeToValues(float[] values) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return timeToValues((int)SystemClock.uptimeMillis(), values);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given a millisecond time value (msec), return the interpolated values and
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * return whether the specified time was within the range of key times
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (NORMAL), was before the first key time (FREEZE_START) or after the last
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * key time (FREEZE_END). In any event, computed values are always returned.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param msec The time (in milliseconds) used to sample into the
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        Interpolator. Based on the SystemClock.uptimeMillis() clock
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values Where to write the computed values (may be NULL).
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return how the values were computed (even if values == null)
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Result timeToValues(int msec, float[] values) {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (values != null && values.length < mValueCount) {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayStoreException();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (nativeTimeToValues(native_instance, msec, values)) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 0: return Result.NORMAL;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 1: return Result.FREEZE_START;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default: return Result.FREEZE_END;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeDestructor(native_instance);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mValueCount;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mFrameCount;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final int native_instance;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int  nativeConstructor(int valueCount, int frameCount);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeDestructor(int native_instance);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeReset(int native_instance, int valueCount, int frameCount);
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeSetKeyFrame(int native_instance, int index, int msec, float[] values, float[] blend);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeSetRepeatMirror(int native_instance, float repeatCount, boolean mirror);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int  nativeTimeToValues(int native_instance, int msec, float[] values);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
164