1 /*
2  * Copyright 2018 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 SkottieProperty_DEFINED
9 #define SkottieProperty_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkPoint.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/core/SkTypeface.h"
15 #include "include/utils/SkTextUtils.h"
16 #include "modules/skottie/src/text/SkottieShaper.h"
17 
18 #include <functional>
19 
20 class SkMatrix;
21 
22 namespace sksg {
23 
24 class Color;
25 class OpacityEffect;
26 
27 } // namespace sksg
28 
29 namespace skottie {
30 
31 using ColorPropertyValue   = SkColor;
32 using OpacityPropertyValue = float;
33 
34 enum class TextPaintOrder : uint8_t {
35     kFillStroke,
36     kStrokeFill,
37 };
38 
39 struct TextPropertyValue {
40     sk_sp<SkTypeface>       fTypeface;
41     SkString                fText;
42     float                   fTextSize    = 0,
43                             fMinTextSize = 0,                                 // when auto-sizing
44                             fMaxTextSize = std::numeric_limits<float>::max(), // when auto-sizing
45                             fStrokeWidth = 0,
46                             fLineHeight  = 0,
47                             fLineShift   = 0,
48                             fAscent      = 0;
49     SkTextUtils::Align      fHAlign      = SkTextUtils::kLeft_Align;
50     Shaper::VAlign          fVAlign      = Shaper::VAlign::kTop;
51     Shaper::ResizePolicy    fResize      = Shaper::ResizePolicy::kNone;
52     Shaper::LinebreakPolicy fLineBreak   = Shaper::LinebreakPolicy::kExplicit;
53     Shaper::Direction       fDirection   = Shaper::Direction::kLTR;
54     SkRect                  fBox         = SkRect::MakeEmpty();
55     SkColor                 fFillColor   = SK_ColorTRANSPARENT,
56                             fStrokeColor = SK_ColorTRANSPARENT;
57     TextPaintOrder          fPaintOrder  = TextPaintOrder::kFillStroke;
58     bool                    fHasFill     = false,
59                             fHasStroke   = false;
60 
61     bool operator==(const TextPropertyValue& other) const;
62     bool operator!=(const TextPropertyValue& other) const;
63 };
64 
65 struct TransformPropertyValue {
66     SkPoint  fAnchorPoint,
67              fPosition;
68     SkVector fScale;
69     SkScalar fRotation,
70              fSkew,
71              fSkewAxis;
72 
73     bool operator==(const TransformPropertyValue& other) const;
74     bool operator!=(const TransformPropertyValue& other) const;
75 };
76 
77 namespace internal { class AnimationBuilder; }
78 
79 /**
80  * Property handles are adapters between user-facing AE model/values
81  * and the internal scene-graph representation.
82  */
83 template <typename ValueT, typename NodeT>
84 class SK_API PropertyHandle final {
85 public:
PropertyHandle(sk_sp<NodeT> node)86     explicit PropertyHandle(sk_sp<NodeT> node) : fNode(std::move(node)) {}
87     ~PropertyHandle();
88 
89     ValueT get() const;
90     void set(const ValueT&);
91 
92 private:
93     const sk_sp<NodeT> fNode;
94 };
95 
96 namespace internal {
97 
98 class TextAdapter;
99 class TransformAdapter2D;
100 
101 } // namespace internal
102 
103 using ColorPropertyHandle     = PropertyHandle<ColorPropertyValue,
104                                                sksg::Color>;
105 using OpacityPropertyHandle   = PropertyHandle<OpacityPropertyValue,
106                                                sksg::OpacityEffect>;
107 using TextPropertyHandle      = PropertyHandle<TextPropertyValue,
108                                                internal::TextAdapter>;
109 using TransformPropertyHandle = PropertyHandle<TransformPropertyValue,
110                                                internal::TransformAdapter2D>;
111 
112 /**
113  * A PropertyObserver can be used to track and manipulate certain properties of "interesting"
114  * Lottie nodes.
115  *
116  * When registered with an animation builder, PropertyObserver receives notifications for
117  * various properties of layer and shape nodes.  The |node_name| argument corresponds to the
118  * name ("nm") node property.
119  */
120 class SK_API PropertyObserver : public SkRefCnt {
121 public:
122     template <typename T>
123     using LazyHandle = std::function<std::unique_ptr<T>()>;
124 
125     virtual void onColorProperty    (const char node_name[],
126                                      const LazyHandle<ColorPropertyHandle>&);
127     virtual void onOpacityProperty  (const char node_name[],
128                                      const LazyHandle<OpacityPropertyHandle>&);
129     virtual void onTextProperty     (const char node_name[],
130                                      const LazyHandle<TextPropertyHandle>&);
131     virtual void onTransformProperty(const char node_name[],
132                                      const LazyHandle<TransformPropertyHandle>&);
133     virtual void onEnterNode(const char node_name[]);
134     virtual void onLeavingNode(const char node_name[]);
135 };
136 
137 } // namespace skottie
138 
139 #endif // SkottieProperty_DEFINED
140