• 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     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 
hasChangedTextValueTracker96         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