1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "modules/skottie/src/SkottieJson.h" 9cb93a386Sopenharmony_ci#include "modules/skottie/src/SkottieValue.h" 10cb93a386Sopenharmony_ci#include "modules/skottie/src/animator/KeyframeAnimator.h" 11cb93a386Sopenharmony_ci#include "modules/skottie/src/text/TextValue.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_cinamespace skottie::internal { 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cinamespace { 16cb93a386Sopenharmony_ciclass TextKeyframeAnimator final : public KeyframeAnimator { 17cb93a386Sopenharmony_cipublic: 18cb93a386Sopenharmony_ci TextKeyframeAnimator(std::vector<Keyframe> kfs, std::vector<SkCubicMap> cms, 19cb93a386Sopenharmony_ci std::vector<TextValue> vs, TextValue* target_value) 20cb93a386Sopenharmony_ci : INHERITED(std::move(kfs), std::move(cms)) 21cb93a386Sopenharmony_ci , fValues(std::move(vs)) 22cb93a386Sopenharmony_ci , fTarget(target_value) {} 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciprivate: 25cb93a386Sopenharmony_ci StateChanged onSeek(float t) override { 26cb93a386Sopenharmony_ci const auto& lerp_info = this->getLERPInfo(t); 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci // Text value keyframes are treated as selectors, not as interpolated values. 29cb93a386Sopenharmony_ci if (*fTarget != fValues[SkToSizeT(lerp_info.vrec0.idx)]) { 30cb93a386Sopenharmony_ci *fTarget = fValues[SkToSizeT(lerp_info.vrec0.idx)]; 31cb93a386Sopenharmony_ci return true; 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci return false; 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci const std::vector<TextValue> fValues; 38cb93a386Sopenharmony_ci TextValue* fTarget; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci using INHERITED = KeyframeAnimator; 41cb93a386Sopenharmony_ci}; 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ciclass TextExpressionAnimator final : public Animator { 44cb93a386Sopenharmony_cipublic: 45cb93a386Sopenharmony_ci TextExpressionAnimator(sk_sp<ExpressionEvaluator<SkString>> expression_evaluator, 46cb93a386Sopenharmony_ci TextValue* target_value) 47cb93a386Sopenharmony_ci : fExpressionEvaluator(std::move(expression_evaluator)) 48cb93a386Sopenharmony_ci , fTarget(target_value) {} 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ciprivate: 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci StateChanged onSeek(float t) override { 53cb93a386Sopenharmony_ci SkString old_value = fTarget->fText; 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci fTarget->fText = fExpressionEvaluator->evaluate(t); 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci return fTarget->fText != old_value; 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci sk_sp<ExpressionEvaluator<SkString>> fExpressionEvaluator; 61cb93a386Sopenharmony_ci TextValue* fTarget; 62cb93a386Sopenharmony_ci}; 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ciclass TextAnimatorBuilder final : public AnimatorBuilder { 65cb93a386Sopenharmony_cipublic: 66cb93a386Sopenharmony_ci explicit TextAnimatorBuilder(TextValue* target) 67cb93a386Sopenharmony_ci : INHERITED(Keyframe::Value::Type::kIndex) 68cb93a386Sopenharmony_ci , fTarget(target) {} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci sk_sp<KeyframeAnimator> makeFromKeyframes(const AnimationBuilder& abuilder, 71cb93a386Sopenharmony_ci const skjson::ArrayValue& jkfs) override { 72cb93a386Sopenharmony_ci SkASSERT(jkfs.size() > 0); 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci fValues.reserve(jkfs.size()); 75cb93a386Sopenharmony_ci if (!this->parseKeyframes(abuilder, jkfs)) { 76cb93a386Sopenharmony_ci return nullptr; 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci fValues.shrink_to_fit(); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci return sk_sp<TextKeyframeAnimator>( 81cb93a386Sopenharmony_ci new TextKeyframeAnimator(std::move(fKFs), 82cb93a386Sopenharmony_ci std::move(fCMs), 83cb93a386Sopenharmony_ci std::move(fValues), 84cb93a386Sopenharmony_ci fTarget)); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci sk_sp<Animator> makeFromExpression(ExpressionManager& em, const char* expr) override { 88cb93a386Sopenharmony_ci sk_sp<ExpressionEvaluator<SkString>> expression_evaluator = 89cb93a386Sopenharmony_ci em.createStringExpressionEvaluator(expr); 90cb93a386Sopenharmony_ci return sk_make_sp<TextExpressionAnimator>(expression_evaluator, fTarget); 91cb93a386Sopenharmony_ci } 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci bool parseValue(const AnimationBuilder& abuilder, const skjson::Value& jv) const override { 94cb93a386Sopenharmony_ci return Parse(jv, abuilder, fTarget); 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ciprivate: 98cb93a386Sopenharmony_ci bool parseKFValue(const AnimationBuilder& abuilder, 99cb93a386Sopenharmony_ci const skjson::ObjectValue&, 100cb93a386Sopenharmony_ci const skjson::Value& jv, 101cb93a386Sopenharmony_ci Keyframe::Value* v) override { 102cb93a386Sopenharmony_ci TextValue val; 103cb93a386Sopenharmony_ci if (!Parse(jv, abuilder, &val)) { 104cb93a386Sopenharmony_ci return false; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci // TODO: full deduping? 108cb93a386Sopenharmony_ci if (fValues.empty() || val != fValues.back()) { 109cb93a386Sopenharmony_ci fValues.push_back(std::move(val)); 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci v->idx = SkToU32(fValues.size() - 1); 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci return true; 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci std::vector<TextValue> fValues; 118cb93a386Sopenharmony_ci TextValue* fTarget; 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci using INHERITED = AnimatorBuilder; 121cb93a386Sopenharmony_ci}; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci} // namespace 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_citemplate <> 126cb93a386Sopenharmony_cibool AnimatablePropertyContainer::bind<TextValue>(const AnimationBuilder& abuilder, 127cb93a386Sopenharmony_ci const skjson::ObjectValue* jprop, 128cb93a386Sopenharmony_ci TextValue* v) { 129cb93a386Sopenharmony_ci TextAnimatorBuilder builder(v); 130cb93a386Sopenharmony_ci return this->bindImpl(abuilder, jprop, builder); 131cb93a386Sopenharmony_ci} 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci} // namespace skottie::internal 134