xref: /aosp_15_r20/external/skia/modules/skottie/tests/Expression.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 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 #include <iostream>
9 #include "include/core/SkFontMgr.h"
10 #include "include/core/SkStream.h"
11 #include "modules/skottie/include/Skottie.h"
12 #include "modules/skottie/include/SkottieProperty.h"
13 #include "tests/Test.h"
14 #include "tools/fonts/FontToolUtils.h"
15 
16 using namespace skottie;
17 
18 namespace {
19 
20 class FakeScalarExpressionEvaluator : public ExpressionEvaluator<float> {
21 public:
evaluate(float t)22     float evaluate(float t) override { return 7.0f; }
23 };
24 
25 class FakeVectorExpressionEvaluator : public ExpressionEvaluator<std::vector<float>> {
26 public:
evaluate(float t)27     std::vector<float> evaluate(float t) override { return {0.1f, 0.2f, 0.3f, 1.0f}; }
28 };
29 
30 class FakeStringExpressionEvaluator : public ExpressionEvaluator<SkString> {
31 public:
evaluate(float t)32     SkString evaluate(float t) override { return SkString("Hello, world!"); }
33 };
34 
35 class FakeExpressionManager : public ExpressionManager {
36 public:
createNumberExpressionEvaluator(const char expression[])37     sk_sp<ExpressionEvaluator<float>> createNumberExpressionEvaluator(
38             const char expression[]) override {
39         return sk_make_sp<FakeScalarExpressionEvaluator>();
40     }
41 
createStringExpressionEvaluator(const char expression[])42     sk_sp<ExpressionEvaluator<SkString>> createStringExpressionEvaluator(
43             const char expression[]) override {
44         return sk_make_sp<FakeStringExpressionEvaluator>();
45     }
46 
createArrayExpressionEvaluator(const char expression[])47     sk_sp<ExpressionEvaluator<std::vector<float>>> createArrayExpressionEvaluator(
48             const char expression[]) override {
49         return sk_make_sp<FakeVectorExpressionEvaluator>();
50     }
51 };
52 
53 class FakePropertyObserver : public PropertyObserver {
54 public:
onOpacityProperty(const char node_name[],const LazyHandle<OpacityPropertyHandle> & opacity_handle)55     void onOpacityProperty(const char node_name[],
56                            const LazyHandle<OpacityPropertyHandle>& opacity_handle) override {
57         opacity_handle_ = opacity_handle();
58     }
59 
onTransformProperty(const char node_name[],const LazyHandle<TransformPropertyHandle> & transform_handle)60     void onTransformProperty(const char node_name[],
61                              const LazyHandle<TransformPropertyHandle>& transform_handle) override {
62         transform_handle_ = transform_handle();
63     }
64 
onColorProperty(const char node_name[],const LazyHandle<ColorPropertyHandle> & color_handle)65     void onColorProperty(const char node_name[],
66                          const LazyHandle<ColorPropertyHandle>& color_handle) override {
67         color_handle_ = color_handle();
68     }
69 
onTextProperty(const char node_name[],const LazyHandle<TextPropertyHandle> & text_handle)70     void onTextProperty(const char node_name[],
71                         const LazyHandle<TextPropertyHandle>& text_handle) override {
72         text_handle_ = text_handle();
73     }
74 
75     std::unique_ptr<OpacityPropertyHandle> opacity_handle_;
76     std::unique_ptr<TransformPropertyHandle> transform_handle_;
77     std::unique_ptr<ColorPropertyHandle> color_handle_;
78     std::unique_ptr<TextPropertyHandle> text_handle_;
79 };
80 }  // namespace
81 
DEF_TEST(Skottie_Expression,r)82 DEF_TEST(Skottie_Expression, r) {
83     static constexpr char json[] =
84         R"({
85              "v": "5.2.1",
86              "w": 100,
87              "h": 100,
88              "fr": 10,
89              "ip": 0,
90              "op": 100,
91              "layers": [
92                {
93                  "ip": 0,
94                  "op": 100,
95                  "ty": 1,
96                  "nm": "My Layer",
97                  "sr": 1,
98                  "ks": {
99                    "o": {
100                      "a": 0,
101                      "k": 100,
102                      "ix": 11,
103                      "x": "fake; return value is specified by the FakeScalarExpressionEvaluator."
104                    },
105                     "r": {
106                         "a": 0,
107                         "k": 0,
108                         "ix": 10
109                     },
110                     "p": {
111                         "a": 0,
112                         "k": [
113                             50,
114                             50,
115                             0
116                         ],
117                         "ix": 2,
118                         "l": 2
119                     },
120                     "a": {
121                         "a": 0,
122                         "k": [
123                             50,
124                             50,
125                             0
126                         ],
127                         "ix": 1,
128                         "l": 2,
129                         "x": "fake; return value is specified by the FakeArrayExpressionEvaluator."
130                     },
131                     "s": {
132                         "a": 0,
133                         "k": [
134                             100,
135                             100,
136                             100
137                         ],
138                         "ix": 6,
139                         "l": 2
140                     }
141                 },
142                 "ef": [
143                 {
144                     "ty": 21,
145                     "nm": "Fill",
146                     "np": 9,
147                     "mn": "ADBE Fill",
148                     "ix": 1,
149                     "en": 1,
150                     "ef": [
151                         {
152                             "ty": 10,
153                             "nm": "Fill Mask",
154                             "mn": "ADBE Fill-0001",
155                             "ix": 1,
156                             "v": {
157                                 "a": 0,
158                                 "k": 0,
159                                 "ix": 1
160                             }
161                         },
162                         {
163                             "ty": 7,
164                             "nm": "All Masks",
165                             "mn": "ADBE Fill-0007",
166                             "ix": 2,
167                             "v": {
168                                 "a": 0,
169                                 "k": 0,
170                                 "ix": 2
171                             }
172                         },
173                         {
174                             "ty": 2,
175                             "nm": "Color",
176                             "mn": "ADBE Fill-0002",
177                             "ix": 3,
178                             "v": {
179                                 "a": 0,
180                                 "k": [
181                                     1,
182                                     0,
183                                     0,
184                                     1
185                                 ],
186                                 "ix": 3,
187                                 "x": "fake; return value is specified by the FakeArrayExpressionEvaluator."
188                             }
189                         },
190                         {
191                             "ty": 7,
192                             "nm": "Invert",
193                             "mn": "ADBE Fill-0006",
194                             "ix": 4,
195                             "v": {
196                                 "a": 0,
197                                 "k": 0,
198                                 "ix": 4
199                             }
200                         },
201                         {
202                             "ty": 0,
203                             "nm": "Horizontal Feather",
204                             "mn": "ADBE Fill-0003",
205                             "ix": 5,
206                             "v": {
207                                 "a": 0,
208                                 "k": 0,
209                                 "ix": 5
210                             }
211                         },
212                         {
213                             "ty": 0,
214                             "nm": "Vertical Feather",
215                             "mn": "ADBE Fill-0004",
216                             "ix": 6,
217                             "v": {
218                                 "a": 0,
219                                 "k": 0,
220                                 "ix": 6
221                             }
222                         },
223                         {
224                             "ty": 0,
225                             "nm": "Opacity",
226                             "mn": "ADBE Fill-0005",
227                             "ix": 7,
228                             "v": {
229                                 "a": 0,
230                                 "k": 1,
231                                 "ix": 7
232                             }
233                         }
234                     ]
235                 }
236                 ],
237                 "ao": 0,
238                 "sw": 100,
239                 "sh": 100,
240                 "sc": "#000000",
241                 "st": 0,
242                 "bm": 0
243                }
244              ]
245            })";
246 
247     SkMemoryStream stream(json, strlen(json));
248 
249     auto em = sk_make_sp<FakeExpressionManager>();
250     auto observer = sk_make_sp<FakePropertyObserver>();
251 
252     auto anim = Animation::Builder()
253         .setExpressionManager(em)
254         .setFontManager(ToolUtils::TestFontMgr())
255         .setPropertyObserver(observer)
256         .make(&stream);
257 
258     REPORTER_ASSERT(r, anim);
259 
260     anim->seekFrameTime(0);
261 
262     REPORTER_ASSERT(r, SkScalarNearlyEqual(observer->opacity_handle_->get(), 7.0f));
263     SkPoint anchor_point = observer->transform_handle_->get().fAnchorPoint;
264     REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fX, 0.1f));
265     REPORTER_ASSERT(r, SkScalarNearlyEqual(anchor_point.fY, 0.2f));
266     REPORTER_ASSERT(r, (observer->color_handle_->get() == SkColor4f{0.1f, 0.2f, 0.3f, 1.0f}.toSkColor()));
267 }
268 
DEF_TEST(Skottie_ExpressionText,r)269 DEF_TEST(Skottie_ExpressionText, r) {
270     static constexpr char text_json[] =
271     R"({
272      "layers":[
273         {
274            "ty":5,
275            "ks":{
276               "a":{
277                  "k":[
278                     0,
279                     0
280                  ]
281               },
282               "p":{
283                  "k":[
284                     128,
285                     144
286                  ]
287               },
288               "o":{
289                  "k":100
290               }
291            },
292            "ind":0,
293            "ip":0,
294            "op":2,
295            "nm":"TextLayer_0",
296            "t":{
297               "d":{
298                  "k":[
299                     {
300                        "t":0,
301                        "s":{
302                           "f": "Helvetica",
303                           "s":14,
304                           "t":"will be replaced.",
305                           "j":0,
306                           "ps":[
307                              0,
308                              0
309                           ],
310                           "sz":[
311                              384,
312                              360
313                           ],
314                           "fc":[
315                              0.95686274766921997,
316                              0.37254902720451355,
317                              0.25490197539329529,
318                              1
319                           ],
320                           "lh":16
321                        }
322                     }
323                  ],
324                  "x": "fake; return value is specified by the FakeStringExpressionEvaluator."
325               }
326            }
327         }
328      ],
329      "ip":0,
330      "op":2,
331      "fr":25,
332      "w":1280,
333      "h":720,
334      "ddd":false,
335      "v":"5.2.2",
336      "nm":"skottie_animation",
337      "fonts":{
338         "list":[
339            {
340               "fName": "Helvetica",
341               "fFamily":"external_font_family",
342               "fStyle":"Regular"
343            }
344         ]
345      }
346   })";
347 
348     SkMemoryStream stream(text_json, strlen(text_json));
349 
350     auto em = sk_make_sp<FakeExpressionManager>();
351     auto observer = sk_make_sp<FakePropertyObserver>();
352 
353     auto anim = Animation::Builder()
354                         .setExpressionManager(em)
355                         .setFontManager(ToolUtils::TestFontMgr())
356                         .setPropertyObserver(observer)
357                         .make(&stream);
358 
359     REPORTER_ASSERT(r, anim);
360 
361     anim->seekFrameTime(0);
362 
363     REPORTER_ASSERT(r, observer->text_handle_->get().fText == SkString("Hello, world!"));
364 }
365