120 lines
4.4 KiB
C
120 lines
4.4 KiB
C
|
/*
|
||
|
* Copyright (C) 2006 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#ifndef SkiaInterpolator_DEFINED
|
||
|
#define SkiaInterpolator_DEFINED
|
||
|
|
||
|
#include "include/private/SkTo.h"
|
||
|
|
||
|
class SkiaInterpolatorBase {
|
||
|
public:
|
||
|
enum Result { kNormal_Result, kFreezeStart_Result, kFreezeEnd_Result };
|
||
|
|
||
|
protected:
|
||
|
SkiaInterpolatorBase();
|
||
|
~SkiaInterpolatorBase();
|
||
|
|
||
|
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(uint32_t* startTime, uint32_t* 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(float 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); }
|
||
|
|
||
|
Result timeToT(uint32_t time, float* T, int* index, bool* exact) const;
|
||
|
|
||
|
protected:
|
||
|
enum Flags { kMirror = 1, kReset = 2, kHasBlend = 4 };
|
||
|
static float ComputeRelativeT(uint32_t time, uint32_t prevTime, uint32_t nextTime,
|
||
|
const float blend[4] = nullptr);
|
||
|
int16_t fFrameCount;
|
||
|
uint8_t fElemCount;
|
||
|
uint8_t fFlags;
|
||
|
float fRepeat;
|
||
|
struct SkTimeCode {
|
||
|
uint32_t fTime;
|
||
|
float fBlend[4];
|
||
|
};
|
||
|
SkTimeCode* fTimes; // pointer into fStorage
|
||
|
void* fStorage;
|
||
|
#ifdef SK_DEBUG
|
||
|
SkTimeCode (*fTimesArray)[10];
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
class SkiaInterpolator : public SkiaInterpolatorBase {
|
||
|
public:
|
||
|
SkiaInterpolator();
|
||
|
SkiaInterpolator(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, uint32_t time, const float values[],
|
||
|
const float blend[4] = nullptr);
|
||
|
|
||
|
/** 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.
|
||
|
*/
|
||
|
Result timeToValues(uint32_t time, float values[] = nullptr) const;
|
||
|
|
||
|
private:
|
||
|
float* fValues; // pointer into fStorage
|
||
|
|
||
|
using INHERITED = SkiaInterpolatorBase;
|
||
|
};
|
||
|
|
||
|
#endif
|