11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkInterpolator_DEFINED 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkInterpolator_DEFINED 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalar.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkInterpolatorBase : SkNoncopyable { 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum Result { 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kNormal_Result, 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kFreezeStart_Result, 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kFreezeEnd_Result 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkInterpolatorBase(); 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ~SkInterpolatorBase(); 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void reset(int elemCount, int frameCount); 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return the start and end time for this interpolator. 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project If there are no key frames, return false. 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param startTime If not null, returns the time (in milliseconds) of the 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project first keyframe. If there are no keyframes, this param 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project is ignored (left unchanged). 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param endTime If not null, returns the time (in milliseconds) of the 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project last keyframe. If there are no keyframes, this parameter 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project is ignored (left unchanged). 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @return True if there are key frames, or false if there are none. 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool getDuration(SkMSec* startTime, SkMSec* endTime) const; 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Set the whether the repeat is mirrored. 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param mirror If true, the odd repeats interpolate from the last key 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project frame and the first. 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void setMirror(bool mirror) { 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror); 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Set the repeat count. The repeat count may be fractional. 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param repeatCount Multiplies the total time by this scalar. 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; } 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Set the whether the repeat is mirrored. 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param reset If true, the odd repeats interpolate from the last key 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project frame and the first. 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void setReset(bool reset) { 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = SkToU8((fFlags & ~kReset) | (int)reset); 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const; 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected: 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum Flags { 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kMirror = 1, 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kReset = 2, 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kHasBlend = 4 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime, 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMSec nextTime, const SkScalar blend[4] = NULL); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int16_t fFrameCount; 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint8_t fElemCount; 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint8_t fFlags; 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fRepeat; 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project struct SkTimeCode { 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMSec fTime; 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fBlend[4]; 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTimeCode* fTimes; // pointer into fStorage 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void* fStorage; 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTimeCode(* fTimesArray)[10]; 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkInterpolator : public SkInterpolatorBase { 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkInterpolator(); 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkInterpolator(int elemCount, int frameCount); 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void reset(int elemCount, int frameCount); 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Add or replace a key frame, copying the values[] data into the 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project interpolator. 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param index The index of this frame (frames must be ordered by time) 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param time The millisecond time for this frame 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param values The array of values [elemCount] for this frame. The data 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project is copied into the interpolator. 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param blend A positive scalar specifying how to blend between this 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project and the next key frame. [0...1) is a cubic lag/log/lag 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project blend (slow to change at the beginning and end) 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1 is a linear blend (default) 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool setKeyFrame(int index, SkMSec time, const SkScalar values[], 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkScalar blend[4] = NULL); 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return the computed values given the specified time. Return whether 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project those values are the result of pinning to either the first 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (kFreezeStart) or last (kFreezeEnd), or from interpolated the two 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project nearest key values (kNormal). 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param time The time to sample (in milliseconds) 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project @param (may be null) where to write the computed values. 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Result timeToValues(SkMSec time, SkScalar values[] = NULL) const; 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(static void UnitTest();) 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar* fValues; // pointer into fStorage 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar(* fScalarsArray)[10]; 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkInterpolatorBase INHERITED; 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** Given all the parameters are [0...1], apply the cubic specified by (0,0) 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1]. 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by, 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar cx, SkScalar cy); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 133