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