180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkInterpolator_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkInterpolator_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScalar.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkInterpolatorBase : SkNoncopyable { 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum Result { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNormal_Result, 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kFreezeStart_Result, 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kFreezeEnd_Result 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkInterpolatorBase(); 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkInterpolatorBase(); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void reset(int elemCount, int frameCount); 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return the start and end time for this interpolator. 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru If there are no key frames, return false. 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param startTime If not null, returns the time (in milliseconds) of the 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru first keyframe. If there are no keyframes, this param 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru is ignored (left unchanged). 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param endTime If not null, returns the time (in milliseconds) of the 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru last keyframe. If there are no keyframes, this parameter 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru is ignored (left unchanged). 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @return True if there are key frames, or false if there are none. 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool getDuration(SkMSec* startTime, SkMSec* endTime) const; 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Set the whether the repeat is mirrored. 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param mirror If true, the odd repeats interpolate from the last key 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru frame and the first. 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setMirror(bool mirror) { 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror); 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Set the repeat count. The repeat count may be fractional. 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param repeatCount Multiplies the total time by this scalar. 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; } 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Set the whether the repeat is mirrored. 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param reset If true, the odd repeats interpolate from the last key 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru frame and the first. 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setReset(bool reset) { 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = SkToU8((fFlags & ~kReset) | (int)reset); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const; 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum Flags { 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kMirror = 1, 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kReset = 2, 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kHasBlend = 4 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime, 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMSec nextTime, const SkScalar blend[4] = NULL); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int16_t fFrameCount; 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t fElemCount; 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t fFlags; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar fRepeat; 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct SkTimeCode { 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMSec fTime; 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar fBlend[4]; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTimeCode* fTimes; // pointer into fStorage 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* fStorage; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTimeCode(* fTimesArray)[10]; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkInterpolator : public SkInterpolatorBase { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkInterpolator(); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkInterpolator(int elemCount, int frameCount); 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void reset(int elemCount, int frameCount); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Add or replace a key frame, copying the values[] data into the 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru interpolator. 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param index The index of this frame (frames must be ordered by time) 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param time The millisecond time for this frame 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param values The array of values [elemCount] for this frame. The data 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru is copied into the interpolator. 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param blend A positive scalar specifying how to blend between this 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru and the next key frame. [0...1) is a cubic lag/log/lag 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru blend (slow to change at the beginning and end) 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1 is a linear blend (default) 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setKeyFrame(int index, SkMSec time, const SkScalar values[], 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar blend[4] = NULL); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return the computed values given the specified time. Return whether 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru those values are the result of pinning to either the first 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (kFreezeStart) or last (kFreezeEnd), or from interpolated the two 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nearest key values (kNormal). 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param time The time to sample (in milliseconds) 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru @param (may be null) where to write the computed values. 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Result timeToValues(SkMSec time, SkScalar values[] = NULL) const; 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(static void UnitTest();) 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar* fValues; // pointer into fStorage 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar(* fScalarsArray)[10]; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkInterpolatorBase INHERITED; 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Given all the parameters are [0...1], apply the cubic specified by (0,0) 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1]. 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by, 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar cx, SkScalar cy); 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 132