1 /* 2 * Copyright 2019 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkottieTextAnimator_DEFINED 9 #define SkottieTextAnimator_DEFINED 10 11 #include "include/core/SkM44.h" 12 #include "include/core/SkRefCnt.h" 13 #include "modules/skottie/src/SkottiePriv.h" 14 #include "modules/skottie/src/SkottieValue.h" 15 #include "modules/sksg/include/SkSGScene.h" 16 17 #include <memory> 18 #include <vector> 19 20 namespace skottie { 21 namespace internal { 22 23 class AnimatablePropertyContainer; 24 class AnimationBuilder; 25 class RangeSelector; 26 27 class TextAnimator final : public SkNVRefCnt<TextAnimator> { 28 public: 29 static sk_sp<TextAnimator> Make(const skjson::ObjectValue*, 30 const AnimationBuilder*, 31 AnimatablePropertyContainer* acontainer); 32 33 // Direct mapping of AE properties. 34 struct AnimatedProps { 35 VectorValue position, 36 scale = { 100, 100, 100 }, 37 fill_color, 38 stroke_color; 39 // unlike pos/scale which are animated vectors, rotation is separated in each dimension. 40 SkV3 rotation = { 0, 0, 0 }; 41 Vec2Value blur = { 0, 0 }, 42 line_spacing = { 0, 0 }; 43 ScalarValue opacity = 100, 44 fill_opacity = 100, 45 stroke_opacity = 100, 46 tracking = 0, 47 stroke_width = 0; 48 }; 49 50 struct ResolvedProps { 51 SkV3 position = { 0, 0, 0 }, 52 scale = { 1, 1, 1 }, 53 rotation = { 0, 0, 0 }; 54 float opacity = 1, 55 tracking = 0, 56 stroke_width = 0; 57 SkColor fill_color = SK_ColorTRANSPARENT, 58 stroke_color = SK_ColorTRANSPARENT; 59 SkV2 blur = { 0, 0 }, 60 line_spacing = { 0, 0 }; 61 }; 62 63 struct AnimatedPropsModulator { 64 ResolvedProps props; // accumulates properties across *all* animators 65 float coverage; // accumulates range selector coverage for a given animator 66 }; 67 using ModulatorBuffer = std::vector<AnimatedPropsModulator>; 68 69 // Domain maps describe how a given index domain (words, lines, etc) relates 70 // to the full fragment index range. 71 // 72 // Each domain[i] represents a [domain[i].fOffset.. domain[i].fOffset+domain[i].fCount-1] 73 // fragment subset. 74 struct DomainSpan { 75 size_t fOffset, 76 fCount; 77 float fAdvance, // cumulative advance for all fragments in span 78 fAscent; // max ascent for all fragments in span 79 }; 80 using DomainMap = std::vector<DomainSpan>; 81 82 struct DomainMaps { 83 DomainMap fNonWhitespaceMap, 84 fWordsMap, 85 fLinesMap; 86 }; 87 88 void modulateProps(const DomainMaps&, ModulatorBuffer&) const; 89 hasBlur()90 bool hasBlur() const { return fHasBlur; } 91 requiresAnchorPoint()92 bool requiresAnchorPoint() const { return fRequiresAnchorPoint; } requiresLineAdjustments()93 bool requiresLineAdjustments() const { return fRequiresLineAdjustments; } 94 95 private: 96 TextAnimator(std::vector<sk_sp<RangeSelector>>&&, 97 const skjson::ObjectValue&, 98 const AnimationBuilder*, 99 AnimatablePropertyContainer*); 100 101 ResolvedProps modulateProps(const ResolvedProps&, float amount) const; 102 103 const std::vector<sk_sp<RangeSelector>> fSelectors; 104 105 AnimatedProps fTextProps; 106 bool fHasFillColor : 1, 107 fHasStrokeColor : 1, 108 fHasFillOpacity : 1, 109 fHasStrokeOpacity : 1, 110 fHasOpacity : 1, 111 fHasBlur : 1, 112 fRequiresAnchorPoint : 1, // animator sensitive to transform origin? 113 fRequiresLineAdjustments : 1; // animator effects line-wide fragment adjustments 114 }; 115 116 } // namespace internal 117 } // namespace skottie 118 119 #endif // SkottieTextAnimator_DEFINED 120