Home | History | Annotate | Download | only in graphics
      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 
     23     public Interpolator(int valueCount) {
     24         mValueCount = valueCount;
     25         mFrameCount = 2;
     26         native_instance = nativeConstructor(valueCount, 2);
     27     }
     28 
     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      */
     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      */
     49     public void reset(int valueCount, int frameCount) {
     50         mValueCount = valueCount;
     51         mFrameCount = frameCount;
     52         nativeReset(native_instance, valueCount, frameCount);
     53     }
     54 
     55     public final int getKeyFrameCount() {
     56         return mFrameCount;
     57     }
     58 
     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      */
     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      */
     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      */
    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      */
    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      */
    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
    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 
    157     private static native long nativeConstructor(int valueCount, int frameCount);
    158     private static native void nativeDestructor(long native_instance);
    159     private static native void nativeReset(long native_instance, int valueCount, int frameCount);
    160     private static native void nativeSetKeyFrame(long native_instance, int index, int msec, float[] values, float[] blend);
    161     private static native void nativeSetRepeatMirror(long native_instance, float repeatCount, boolean mirror);
    162     private static native int  nativeTimeToValues(long native_instance, int msec, float[] values);
    163 }
    164 
    165