2008-12-17 15:59:43 +00:00
|
|
|
/*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Copyright 2006 The Android Open Source Project
|
2008-12-17 15:59:43 +00:00
|
|
|
*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2008-12-17 15:59:43 +00:00
|
|
|
*/
|
|
|
|
|
2011-07-28 14:26:00 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#ifndef SkInterpolator_DEFINED
|
|
|
|
#define SkInterpolator_DEFINED
|
|
|
|
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "include/core/SkScalar.h"
|
|
|
|
#include "include/private/SkNoncopyable.h"
|
|
|
|
#include "include/private/SkTo.h"
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2017-09-20 19:51:08 +00:00
|
|
|
class SK_API SkInterpolatorBase : SkNoncopyable {
|
2008-12-17 15:59:43 +00:00
|
|
|
public:
|
|
|
|
enum Result {
|
|
|
|
kNormal_Result,
|
|
|
|
kFreezeStart_Result,
|
|
|
|
kFreezeEnd_Result
|
|
|
|
};
|
|
|
|
protected:
|
|
|
|
SkInterpolatorBase();
|
|
|
|
~SkInterpolatorBase();
|
|
|
|
public:
|
|
|
|
void reset(int elemCount, int frameCount);
|
|
|
|
|
|
|
|
/** Return the start and end time for this interpolator.
|
|
|
|
If there are no key frames, return false.
|
|
|
|
@param startTime If not null, returns the time (in milliseconds) of the
|
|
|
|
first keyframe. If there are no keyframes, this param
|
|
|
|
is ignored (left unchanged).
|
|
|
|
@param endTime If not null, returns the time (in milliseconds) of the
|
|
|
|
last keyframe. If there are no keyframes, this parameter
|
|
|
|
is ignored (left unchanged).
|
|
|
|
@return True if there are key frames, or false if there are none.
|
|
|
|
*/
|
|
|
|
bool getDuration(SkMSec* startTime, SkMSec* endTime) const;
|
|
|
|
|
|
|
|
|
|
|
|
/** Set the whether the repeat is mirrored.
|
|
|
|
@param mirror If true, the odd repeats interpolate from the last key
|
|
|
|
frame and the first.
|
|
|
|
*/
|
|
|
|
void setMirror(bool mirror) {
|
|
|
|
fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set the repeat count. The repeat count may be fractional.
|
|
|
|
@param repeatCount Multiplies the total time by this scalar.
|
|
|
|
*/
|
|
|
|
void setRepeatCount(SkScalar repeatCount) { fRepeat = repeatCount; }
|
|
|
|
|
|
|
|
/** Set the whether the repeat is mirrored.
|
|
|
|
@param reset If true, the odd repeats interpolate from the last key
|
|
|
|
frame and the first.
|
|
|
|
*/
|
|
|
|
void setReset(bool reset) {
|
|
|
|
fFlags = SkToU8((fFlags & ~kReset) | (int)reset);
|
|
|
|
}
|
|
|
|
|
2015-12-27 20:47:25 +00:00
|
|
|
Result timeToT(SkMSec time, SkScalar* T, int* index, bool* exact) const;
|
2008-12-17 15:59:43 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
enum Flags {
|
|
|
|
kMirror = 1,
|
|
|
|
kReset = 2,
|
|
|
|
kHasBlend = 4
|
|
|
|
};
|
2017-08-28 14:34:05 +00:00
|
|
|
static SkScalar ComputeRelativeT(SkMSec time, SkMSec prevTime, SkMSec nextTime,
|
|
|
|
const SkScalar blend[4] = nullptr);
|
2008-12-17 15:59:43 +00:00
|
|
|
int16_t fFrameCount;
|
|
|
|
uint8_t fElemCount;
|
|
|
|
uint8_t fFlags;
|
|
|
|
SkScalar fRepeat;
|
|
|
|
struct SkTimeCode {
|
|
|
|
SkMSec fTime;
|
|
|
|
SkScalar fBlend[4];
|
|
|
|
};
|
|
|
|
SkTimeCode* fTimes; // pointer into fStorage
|
|
|
|
void* fStorage;
|
|
|
|
#ifdef SK_DEBUG
|
|
|
|
SkTimeCode(* fTimesArray)[10];
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2017-09-20 19:51:08 +00:00
|
|
|
class SK_API SkInterpolator : public SkInterpolatorBase {
|
2008-12-17 15:59:43 +00:00
|
|
|
public:
|
|
|
|
SkInterpolator();
|
|
|
|
SkInterpolator(int elemCount, int frameCount);
|
|
|
|
void reset(int elemCount, int frameCount);
|
|
|
|
|
|
|
|
/** Add or replace a key frame, copying the values[] data into the
|
|
|
|
interpolator.
|
|
|
|
@param index The index of this frame (frames must be ordered by time)
|
|
|
|
@param time The millisecond time for this frame
|
|
|
|
@param values The array of values [elemCount] for this frame. The data
|
|
|
|
is copied into the interpolator.
|
|
|
|
@param blend A positive scalar specifying how to blend between this
|
|
|
|
and the next key frame. [0...1) is a cubic lag/log/lag
|
|
|
|
blend (slow to change at the beginning and end)
|
|
|
|
1 is a linear blend (default)
|
|
|
|
*/
|
|
|
|
bool setKeyFrame(int index, SkMSec time, const SkScalar values[],
|
2017-08-28 14:34:05 +00:00
|
|
|
const SkScalar blend[4] = nullptr);
|
2008-12-17 15:59:43 +00:00
|
|
|
|
|
|
|
/** Return the computed values given the specified time. Return whether
|
|
|
|
those values are the result of pinning to either the first
|
|
|
|
(kFreezeStart) or last (kFreezeEnd), or from interpolated the two
|
|
|
|
nearest key values (kNormal).
|
|
|
|
@param time The time to sample (in milliseconds)
|
|
|
|
@param (may be null) where to write the computed values.
|
|
|
|
*/
|
2017-08-28 14:34:05 +00:00
|
|
|
Result timeToValues(SkMSec time, SkScalar values[] = nullptr) const;
|
2008-12-17 15:59:43 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
SkScalar* fValues; // pointer into fStorage
|
|
|
|
#ifdef SK_DEBUG
|
|
|
|
SkScalar(* fScalarsArray)[10];
|
|
|
|
#endif
|
2020-09-03 02:42:33 +00:00
|
|
|
using INHERITED = SkInterpolatorBase;
|
2008-12-17 15:59:43 +00:00
|
|
|
};
|
|
|
|
|
2016-01-07 19:33:15 +00:00
|
|
|
/** Interpolate a cubic curve, typically to provide an ease-in ease-out transition.
|
|
|
|
All the parameters are in the range of [0...1].
|
|
|
|
The input value is treated as the x-coordinate of the cubic.
|
|
|
|
The output value is the y-coordinate on the cubic at the x-coordinate.
|
|
|
|
|
|
|
|
@param value The x-coordinate pinned between [0..1].
|
|
|
|
@param bx,by,cx,cy The cubic control points where the cubic is specified
|
|
|
|
as (0,0) (bx,by) (cx,cy) (1,1)
|
|
|
|
@return the corresponding y-coordinate value, from [0..1].
|
2008-12-17 15:59:43 +00:00
|
|
|
*/
|
|
|
|
SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by,
|
|
|
|
SkScalar cx, SkScalar cy);
|
|
|
|
|
|
|
|
#endif
|