• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
node()37     const sk_sp<sksg::Group>& node() const { return fRoot; }
38 
getText()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     SkM44 fragmentMatrix(const TextAnimator::ResolvedProps&, const FragmentRec&, const SkV2&) const;
84 
85     const sk_sp<sksg::Group>         fRoot;
86     const sk_sp<SkFontMgr>           fFontMgr;
87     sk_sp<Logger>                    fLogger;
88     const AnchorPointGrouping        fAnchorPointGrouping;
89 
90     std::vector<sk_sp<TextAnimator>> fAnimators;
91     std::vector<FragmentRec>         fFragments;
92     TextAnimator::DomainMaps         fMaps;
93 
94     // Helps detect external value changes.
95     struct TextValueTracker {
96         TextValue fCurrentValue;
97 
hasChangedTextValueTracker98         bool hasChanged() const {
99             if (fCurrentValue != fPrevValue) {
100                 fPrevValue = fCurrentValue;
101                 return true;
102             }
103             return false;
104         }
105 
106         const TextValue* operator->() const { return &fCurrentValue; }
107 
108     private:
109         mutable TextValue fPrevValue;
110     };
111 
112     TextValueTracker          fText;
113     Vec2Value                 fGroupingAlignment = {0,0};
114 
115     // Optional text path.
116     struct PathInfo;
117     std::unique_ptr<PathInfo> fPathInfo;
118 
119     bool                      fHasBlurAnimator     : 1,
120                               fRequiresAnchorPoint : 1;
121 };
122 
123 } // namespace internal
124 } // namespace skottie
125 
126 #endif // SkottieTextAdapter_DEFINED
127