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 adjustLineProps(const TextAnimator::ModulatorBuffer&, |
75 | const TextAnimator::DomainSpan&, |
76 | const SkV2& line_offset, |
77 | float line_tracking) const; |
78 | |
79 | SkV2 fragmentAnchorPoint(const FragmentRec&, const SkV2&, |
80 | const TextAnimator::DomainSpan*) const; |
81 | uint32_t shaperFlags() const; |
82 | |
83 | const sk_sp<sksg::Group> fRoot; |
84 | const sk_sp<SkFontMgr> fFontMgr; |
85 | sk_sp<Logger> fLogger; |
86 | const AnchorPointGrouping fAnchorPointGrouping; |
87 | |
88 | std::vector<sk_sp<TextAnimator>> fAnimators; |
89 | std::vector<FragmentRec> fFragments; |
90 | TextAnimator::DomainMaps fMaps; |
91 | |
92 | // Helps detect external value changes. |
93 | struct TextValueTracker { |
94 | TextValue fCurrentValue; |
95 | |
96 | bool hasChanged() const { |
97 | if (fCurrentValue != fPrevValue) { |
98 | fPrevValue = fCurrentValue; |
99 | return true; |
100 | } |
101 | return false; |
102 | } |
103 | |
104 | const TextValue* operator->() const { return &fCurrentValue; } |
105 | |
106 | private: |
107 | mutable TextValue fPrevValue; |
108 | }; |
109 | |
110 | TextValueTracker fText; |
111 | Vec2Value fGroupingAlignment = {0,0}; |
112 | |
113 | bool fHasBlurAnimator : 1, |
114 | fRequiresAnchorPoint : 1; |
115 | }; |
116 | |
117 | } // namespace internal |
118 | } // namespace skottie |
119 | |
120 | #endif // SkottieTextAdapter_DEFINED |
121 | |