xref: /aosp_15_r20/external/skia/modules/skottie/include/SkottieProperty.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkMatrix.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkSpan.h"
19 #include "include/core/SkString.h"
20 #include "include/core/SkTypeface.h"
21 #include "include/private/base/SkAPI.h"
22 #include "include/utils/SkTextUtils.h"
23 #include "modules/skottie/include/TextShaper.h"
24 
25 #include <cstddef>
26 #include <cstdint>
27 #include <functional>
28 #include <limits>
29 #include <memory>
30 #include <utility>
31 
32 class SkCanvas;
33 
34 namespace sksg {
35 
36 class Color;
37 class OpacityEffect;
38 
39 } // namespace sksg
40 
41 namespace skottie {
42 
43 using ColorPropertyValue   = SkColor;
44 using OpacityPropertyValue = float;
45 
46 enum class TextPaintOrder : uint8_t {
47     kFillStroke,
48     kStrokeFill,
49 };
50 
51 // Optional callback invoked when drawing text layers.
52 // Allows clients to render custom text decorations.
53 class GlyphDecorator : public SkRefCnt {
54 public:
55     struct GlyphInfo {
56         SkRect   fBounds;  // visual glyph bounds
57         SkMatrix fMatrix;  // glyph matrix
58         size_t   fCluster; // cluster index in the original text string
59         float    fAdvance; // horizontal glyph advance
60     };
61 
62     struct TextInfo {
63         SkSpan<const GlyphInfo> fGlyphs;
64         float                   fScale;  // Additional font scale applied by auto-sizing.
65     };
66 
67     virtual void onDecorate(SkCanvas*, const TextInfo&) = 0;
68 };
69 
70 struct TextPropertyValue {
71     sk_sp<SkTypeface>       fTypeface;
72     SkString                fText;
73     float                   fTextSize       = 0,
74                             fMinTextSize    = 0,                                 // when auto-sizing
75                             fMaxTextSize    = std::numeric_limits<float>::max(), // when auto-sizing
76                             fStrokeWidth    = 0,
77                             fLineHeight     = 0,
78                             fLineShift      = 0,
79                             fAscent         = 0;
80     size_t                  fMaxLines       = 0;                                 // when auto-sizing
81     SkTextUtils::Align      fHAlign         = SkTextUtils::kLeft_Align;
82     Shaper::VAlign          fVAlign         = Shaper::VAlign::kTop;
83     Shaper::ResizePolicy    fResize         = Shaper::ResizePolicy::kNone;
84     Shaper::LinebreakPolicy fLineBreak      = Shaper::LinebreakPolicy::kExplicit;
85     Shaper::Direction       fDirection      = Shaper::Direction::kLTR;
86     Shaper::Capitalization  fCapitalization = Shaper::Capitalization::kNone;
87     SkRect                  fBox            = SkRect::MakeEmpty();
88     SkColor                 fFillColor      = SK_ColorTRANSPARENT,
89                             fStrokeColor    = SK_ColorTRANSPARENT;
90     TextPaintOrder          fPaintOrder     = TextPaintOrder::kFillStroke;
91     SkPaint::Join           fStrokeJoin     = SkPaint::Join::kMiter_Join;
92     bool                    fHasFill        = false,
93                             fHasStroke      = false;
94     sk_sp<GlyphDecorator>   fDecorator;
95                             // The locale to be used for text shaping, in BCP47 form.  This includes
96                             // support for RFC6067 extensions, so one can e.g. select strict line
97                             // breaking rules for certain scripts: ja-u-lb-strict.
98                             // Pass an empty string to use the system locale.
99     SkString                fLocale;
100                             // Optional font family name, to be passed to the font manager for
101                             // fallback.
102     SkString                fFontFamily;
103 
104     bool operator==(const TextPropertyValue& other) const;
105     bool operator!=(const TextPropertyValue& other) const;
106 };
107 
108 struct TransformPropertyValue {
109     SkPoint  fAnchorPoint,
110              fPosition;
111     SkVector fScale;
112     SkScalar fRotation,
113              fSkew,
114              fSkewAxis;
115 
116     bool operator==(const TransformPropertyValue& other) const;
117     bool operator!=(const TransformPropertyValue& other) const;
118 };
119 
120 namespace internal { class SceneGraphRevalidator; }
121 
122 /**
123  * Property handles are adapters between user-facing AE model/values
124  * and the internal scene-graph representation.
125  */
126 template <typename ValueT, typename NodeT>
127 class SK_API PropertyHandle final {
128 public:
129     explicit PropertyHandle(sk_sp<NodeT>);
PropertyHandle(sk_sp<NodeT> node,sk_sp<internal::SceneGraphRevalidator> revalidator)130     PropertyHandle(sk_sp<NodeT> node, sk_sp<internal::SceneGraphRevalidator> revalidator)
131         : fNode(std::move(node))
132         , fRevalidator(std::move(revalidator)) {}
133     ~PropertyHandle();
134 
135     PropertyHandle(const PropertyHandle&);
136 
137     ValueT get() const;
138     void set(const ValueT&);
139 
140 private:
141     const sk_sp<NodeT>                           fNode;
142     const sk_sp<internal::SceneGraphRevalidator> fRevalidator;
143 };
144 
145 namespace internal {
146 
147 class TextAdapter;
148 class TransformAdapter2D;
149 
150 } // namespace internal
151 
152 using ColorPropertyHandle     = PropertyHandle<ColorPropertyValue,
153                                                sksg::Color>;
154 using OpacityPropertyHandle   = PropertyHandle<OpacityPropertyValue,
155                                                sksg::OpacityEffect>;
156 using TextPropertyHandle      = PropertyHandle<TextPropertyValue,
157                                                internal::TextAdapter>;
158 using TransformPropertyHandle = PropertyHandle<TransformPropertyValue,
159                                                internal::TransformAdapter2D>;
160 
161 /**
162  * A PropertyObserver can be used to track and manipulate certain properties of "interesting"
163  * Lottie nodes.
164  *
165  * When registered with an animation builder, PropertyObserver receives notifications for
166  * various properties of layer and shape nodes.  The |node_name| argument corresponds to the
167  * name ("nm") node property.
168  */
169 class SK_API PropertyObserver : public SkRefCnt {
170 public:
171     enum class NodeType {COMPOSITION, LAYER, EFFECT, OTHER};
172 
173     template <typename T>
174     using LazyHandle = std::function<std::unique_ptr<T>()>;
175 
176     virtual void onColorProperty    (const char node_name[],
177                                      const LazyHandle<ColorPropertyHandle>&);
178     virtual void onOpacityProperty  (const char node_name[],
179                                      const LazyHandle<OpacityPropertyHandle>&);
180     virtual void onTextProperty     (const char node_name[],
181                                      const LazyHandle<TextPropertyHandle>&);
182     virtual void onTransformProperty(const char node_name[],
183                                      const LazyHandle<TransformPropertyHandle>&);
184     virtual void onEnterNode(const char node_name[], NodeType node_type);
185     virtual void onLeavingNode(const char node_name[], NodeType node_type);
186 };
187 
188 } // namespace skottie
189 
190 #endif // SkottieProperty_DEFINED
191