|  | /* | 
|  | * 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 |