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