1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/utils/SkInterpolator.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,131 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkInterpolator_DEFINED 1.14 +#define SkInterpolator_DEFINED 1.15 + 1.16 +#include "SkScalar.h" 1.17 + 1.18 +class SkInterpolatorBase : SkNoncopyable { 1.19 +public: 1.20 + enum Result { 1.21 + kNormal_Result, 1.22 + kFreezeStart_Result, 1.23 + kFreezeEnd_Result 1.24 + }; 1.25 +protected: 1.26 + SkInterpolatorBase(); 1.27 + ~SkInterpolatorBase(); 1.28 +public: 1.29 + void reset(int elemCount, int frameCount); 1.30 + 1.31 + /** Return the start and end time for this interpolator. 1.32 + If there are no key frames, return false. 1.33 + @param startTime If not null, returns the time (in milliseconds) of the 1.34 + first keyframe. If there are no keyframes, this param 1.35 + is ignored (left unchanged). 1.36 + @param endTime If not null, returns the time (in milliseconds) of the 1.37 + last keyframe. If there are no keyframes, this parameter 1.38 + is ignored (left unchanged). 1.39 + @return True if there are key frames, or false if there are none. 1.40 + */ 1.41 + bool getDuration(SkMSec* startTime, SkMSec* endTime) const; 1.42 + 1.43 + 1.44 + /** Set the whether the repeat is mirrored. 1.45 + @param mirror If true, the odd repeats interpolate from the last key 1.46 + frame and the first. 1.47 + */ 1.48 + void setMirror(bool mirror) { 1.49 + fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror); 1.50 + } 1.51 + 1.52 + /** Set the repeat count. The repeat count may be fractional. 1.53 + @param repeatCount Multiplies the total time by this scalar. 1.54 + */ 1.55 + void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; } 1.56 + 1.57 + /** Set the whether the repeat is mirrored. 1.58 + @param reset If true, the odd repeats interpolate from the last key 1.59 + frame and the first. 1.60 + */ 1.61 + void setReset(bool reset) { 1.62 + fFlags = SkToU8((fFlags & ~kReset) | (int)reset); 1.63 + } 1.64 + 1.65 + Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const; 1.66 + 1.67 +protected: 1.68 + enum Flags { 1.69 + kMirror = 1, 1.70 + kReset = 2, 1.71 + kHasBlend = 4 1.72 + }; 1.73 + static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime, 1.74 + SkMSec nextTime, const SkScalar blend[4] = NULL); 1.75 + int16_t fFrameCount; 1.76 + uint8_t fElemCount; 1.77 + uint8_t fFlags; 1.78 + SkScalar fRepeat; 1.79 + struct SkTimeCode { 1.80 + SkMSec fTime; 1.81 + SkScalar fBlend[4]; 1.82 + }; 1.83 + SkTimeCode* fTimes; // pointer into fStorage 1.84 + void* fStorage; 1.85 +#ifdef SK_DEBUG 1.86 + SkTimeCode(* fTimesArray)[10]; 1.87 +#endif 1.88 +}; 1.89 + 1.90 +class SkInterpolator : public SkInterpolatorBase { 1.91 +public: 1.92 + SkInterpolator(); 1.93 + SkInterpolator(int elemCount, int frameCount); 1.94 + void reset(int elemCount, int frameCount); 1.95 + 1.96 + /** Add or replace a key frame, copying the values[] data into the 1.97 + interpolator. 1.98 + @param index The index of this frame (frames must be ordered by time) 1.99 + @param time The millisecond time for this frame 1.100 + @param values The array of values [elemCount] for this frame. The data 1.101 + is copied into the interpolator. 1.102 + @param blend A positive scalar specifying how to blend between this 1.103 + and the next key frame. [0...1) is a cubic lag/log/lag 1.104 + blend (slow to change at the beginning and end) 1.105 + 1 is a linear blend (default) 1.106 + */ 1.107 + bool setKeyFrame(int index, SkMSec time, const SkScalar values[], 1.108 + const SkScalar blend[4] = NULL); 1.109 + 1.110 + /** Return the computed values given the specified time. Return whether 1.111 + those values are the result of pinning to either the first 1.112 + (kFreezeStart) or last (kFreezeEnd), or from interpolated the two 1.113 + nearest key values (kNormal). 1.114 + @param time The time to sample (in milliseconds) 1.115 + @param (may be null) where to write the computed values. 1.116 + */ 1.117 + Result timeToValues(SkMSec time, SkScalar values[] = NULL) const; 1.118 + 1.119 + SkDEBUGCODE(static void UnitTest();) 1.120 +private: 1.121 + SkScalar* fValues; // pointer into fStorage 1.122 +#ifdef SK_DEBUG 1.123 + SkScalar(* fScalarsArray)[10]; 1.124 +#endif 1.125 + typedef SkInterpolatorBase INHERITED; 1.126 +}; 1.127 + 1.128 +/** Given all the parameters are [0...1], apply the cubic specified by (0,0) 1.129 + (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1]. 1.130 +*/ 1.131 +SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by, 1.132 + SkScalar cx, SkScalar cy); 1.133 + 1.134 +#endif