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
18class SkFontMgr;
19
20namespace sksg {
21class BlurImageFilter;
22class Group;
23template <typename T>
24class Matrix;
25} // namespace sksg
26
27namespace skottie {
28namespace internal {
29
30class TextAdapter final : public AnimatablePropertyContainer {
31public:
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
42protected:
43 void onSync() override;
44
45private:
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