1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.graphics;
18 
19 import android.os.SystemClock;
20 
21 public class Interpolator {
22 
Interpolator(int valueCount)23     public Interpolator(int valueCount) {
24         mValueCount = valueCount;
25         mFrameCount = 2;
26         native_instance = nativeConstructor(valueCount, 2);
27     }
28 
Interpolator(int valueCount, int frameCount)29     public Interpolator(int valueCount, int frameCount) {
30         mValueCount = valueCount;
31         mFrameCount = frameCount;
32         native_instance = nativeConstructor(valueCount, frameCount);
33     }
34 
35     /**
36      * Reset the Interpolator to have the specified number of values and an
37      * implicit keyFrame count of 2 (just a start and end). After this call the
38      * values for each keyFrame must be assigned using setKeyFrame().
39      */
reset(int valueCount)40     public void reset(int valueCount) {
41         reset(valueCount, 2);
42     }
43 
44     /**
45      * Reset the Interpolator to have the specified number of values and
46      * keyFrames. After this call the values for each keyFrame must be assigned
47      * using setKeyFrame().
48      */
reset(int valueCount, int frameCount)49     public void reset(int valueCount, int frameCount) {
50         mValueCount = valueCount;
51         mFrameCount = frameCount;
52         nativeReset(native_instance, valueCount, frameCount);
53     }
54 
getKeyFrameCount()55     public final int getKeyFrameCount() {
56         return mFrameCount;
57     }
58 
getValueCount()59     public final int getValueCount() {
60         return mValueCount;
61     }
62 
63     /**
64      * Assign the keyFrame (specified by index) a time value and an array of key
65      * values (with an implicity blend array of [0, 0, 1, 1] giving linear
66      * transition to the next set of key values).
67      *
68      * @param index The index of the key frame to assign
69      * @param msec The time (in mililiseconds) for this key frame. Based on the
70      *        SystemClock.uptimeMillis() clock
71      * @param values Array of values associated with theis key frame
72      */
setKeyFrame(int index, int msec, float[] values)73     public void setKeyFrame(int index, int msec, float[] values) {
74         setKeyFrame(index, msec, values, null);
75     }
76 
77     /**
78      * Assign the keyFrame (specified by index) a time value and an array of key
79      * values and blend array.
80      *
81      * @param index The index of the key frame to assign
82      * @param msec The time (in mililiseconds) for this key frame. Based on the
83      *        SystemClock.uptimeMillis() clock
84      * @param values Array of values associated with theis key frame
85      * @param blend (may be null) Optional array of 4 blend values
86      */
setKeyFrame(int index, int msec, float[] values, float[] blend)87     public void setKeyFrame(int index, int msec, float[] values, float[] blend) {
88         if (index < 0 || index >= mFrameCount) {
89             throw new IndexOutOfBoundsException();
90         }
91         if (values.length < mValueCount) {
92             throw new ArrayStoreException();
93         }
94         if (blend != null && blend.length < 4) {
95             throw new ArrayStoreException();
96         }
97         nativeSetKeyFrame(native_instance, index, msec, values, blend);
98     }
99 
100     /**
101      * Set a repeat count (which may be fractional) for the interpolator, and
102      * whether the interpolator should mirror its repeats. The default settings
103      * are repeatCount = 1, and mirror = false.
104      */
setRepeatMirror(float repeatCount, boolean mirror)105     public void setRepeatMirror(float repeatCount, boolean mirror) {
106         if (repeatCount >= 0) {
107             nativeSetRepeatMirror(native_instance, repeatCount, mirror);
108         }
109     }
110 
111     public enum Result {
112         NORMAL,
113         FREEZE_START,
114         FREEZE_END
115     }
116 
117     /**
118      * Calls timeToValues(msec, values) with the msec set to now (by calling
119      * (int)SystemClock.uptimeMillis().)
120      */
timeToValues(float[] values)121     public Result timeToValues(float[] values) {
122         return timeToValues((int)SystemClock.uptimeMillis(), values);
123     }
124 
125     /**
126      * Given a millisecond time value (msec), return the interpolated values and
127      * return whether the specified time was within the range of key times
128      * (NORMAL), was before the first key time (FREEZE_START) or after the last
129      * key time (FREEZE_END). In any event, computed values are always returned.
130      *
131      * @param msec The time (in milliseconds) used to sample into the
132      *        Interpolator. Based on the SystemClock.uptimeMillis() clock
133      * @param values Where to write the computed values (may be NULL).
134      * @return how the values were computed (even if values == null)
135      */
timeToValues(int msec, float[] values)136     public Result timeToValues(int msec, float[] values) {
137         if (values != null && values.length < mValueCount) {
138             throw new ArrayStoreException();
139         }
140         switch (nativeTimeToValues(native_instance, msec, values)) {
141             case 0: return Result.NORMAL;
142             case 1: return Result.FREEZE_START;
143             default: return Result.FREEZE_END;
144         }
145     }
146 
147     @Override
finalize()148     protected void finalize() throws Throwable {
149         nativeDestructor(native_instance);
150         native_instance = 0;  // Other finalizers can still call us.
151     }
152 
153     private int mValueCount;
154     private int mFrameCount;
155     private long native_instance;
156 
nativeConstructor(int valueCount, int frameCount)157     private static native long nativeConstructor(int valueCount, int frameCount);
nativeDestructor(long native_instance)158     private static native void nativeDestructor(long native_instance);
nativeReset(long native_instance, int valueCount, int frameCount)159     private static native void nativeReset(long native_instance, int valueCount, int frameCount);
nativeSetKeyFrame(long native_instance, int index, int msec, float[] values, float[] blend)160     private static native void nativeSetKeyFrame(long native_instance, int index, int msec, float[] values, float[] blend);
nativeSetRepeatMirror(long native_instance, float repeatCount, boolean mirror)161     private static native void nativeSetRepeatMirror(long native_instance, float repeatCount, boolean mirror);
nativeTimeToValues(long native_instance, int msec, float[] values)162     private static native int  nativeTimeToValues(long native_instance, int msec, float[] values);
163 }
164 
165