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