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 SkottieTextAdapter_DEFINED |
9 | #define SkottieTextAdapter_DEFINED |
10 | |
11 | #include "modules/skottie/src/animator/Animator.h" |
12 | #include "modules/skottie/src/text/SkottieShaper.h" |
13 | #include "modules/skottie/src/text/TextAnimator.h" |
14 | #include "modules/skottie/src/text/TextValue.h" |
15 | |
16 | #include <vector> |
17 | |
18 | class SkFontMgr; |
19 | |
20 | namespace sksg { |
21 | class BlurImageFilter; |
22 | class Group; |
23 | template <typename T> |
24 | class Matrix; |
25 | } // namespace sksg |
26 | |
27 | namespace skottie { |
28 | namespace internal { |
29 | |
30 | class TextAdapter final : public AnimatablePropertyContainer { |
31 | public: |
32 | static sk_sp<TextAdapter> Make(const skjson::ObjectValue&, const AnimationBuilder*, |
33 | sk_sp<SkFontMgr>, sk_sp<Logger>); |
34 | |
35 | ~TextAdapter() override; |
36 | |
37 | const sk_sp<sksg::Group>& node() const { return fRoot; } |
38 | |
39 | const TextValue& getText() const { return fText.fCurrentValue; } |
40 | void setText(const TextValue&); |
41 | |
42 | protected: |
43 | void onSync() override; |
44 | |
45 | private: |
46 | enum class AnchorPointGrouping : uint8_t { |
47 | kCharacter, |
48 | kWord, |
49 | kLine, |
50 | kAll, |
51 | }; |
52 | |
53 | TextAdapter(sk_sp<SkFontMgr>, sk_sp<Logger>, AnchorPointGrouping); |
54 | |
55 | struct FragmentRec { |
56 | SkPoint fOrigin; // fragment position |
57 | |
58 | sk_sp<sksg::Matrix<SkM44>> fMatrixNode; |
59 | sk_sp<sksg::Color> fFillColorNode, |
60 | fStrokeColorNode; |
61 | sk_sp<sksg::BlurImageFilter> fBlur; |
62 | |
63 | float fAdvance, // used for transform anchor point calculations |
64 | fAscent; // ^ |
65 | }; |
66 | |
67 | void reshape(); |
68 | void addFragment(const Shaper::Fragment&); |
69 | void buildDomainMaps(const Shaper::Result&); |
70 | |
71 | void pushPropsToFragment(const TextAnimator::ResolvedProps&, const FragmentRec&, |
72 | const SkV2&, const TextAnimator::DomainSpan*) const; |
73 | |
74 | void adjustLineTracking(const TextAnimator::ModulatorBuffer&, |
75 | const TextAnimator::DomainSpan&, |
76 | float line_tracking) const; |
77 | |
78 | SkV2 fragmentAnchorPoint(const FragmentRec&, const SkV2&, |
79 | const TextAnimator::DomainSpan*) const; |
80 | uint32_t shaperFlags() const; |
81 | |
82 | const sk_sp<sksg::Group> fRoot; |
83 | const sk_sp<SkFontMgr> fFontMgr; |
84 | sk_sp<Logger> fLogger; |
85 | const AnchorPointGrouping fAnchorPointGrouping; |
86 | |
87 | std::vector<sk_sp<TextAnimator>> fAnimators; |
88 | std::vector<FragmentRec> fFragments; |
89 | TextAnimator::DomainMaps fMaps; |
90 | |
91 | // Helps detect external value changes. |
92 | struct TextValueTracker { |
93 | TextValue fCurrentValue; |
94 | |
95 | bool hasChanged() const { |
96 | if (fCurrentValue != fPrevValue) { |
97 | fPrevValue = fCurrentValue; |
98 | return true; |
99 | } |
100 | return false; |
101 | } |
102 | |
103 | const TextValue* operator->() const { return &fCurrentValue; } |
104 | |
105 | private: |
106 | mutable TextValue fPrevValue; |
107 | }; |
108 | |
109 | TextValueTracker fText; |
110 | Vec2Value fGroupingAlignment = {0,0}; |
111 | |
112 | bool fHasBlurAnimator : 1, |
113 | fRequiresAnchorPoint : 1; |
114 | }; |
115 | |
116 | } // namespace internal |
117 | } // namespace skottie |
118 | |
119 | #endif // SkottieTextAdapter_DEFINED |
120 | |