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