• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 "modules/skottie/include/ExternalLayer.h"
9 #include "modules/skottie/src/SkottiePriv.h"
10 #include "modules/skottie/src/SkottieValue.h"
11 #include "modules/skottie/src/animator/Animator.h"
12 #include "src/utils/SkJSON.h"
13 #include "tests/Test.h"
14 
15 #include <cmath>
16 
17 using namespace skottie;
18 using namespace skottie::internal;
19 
20 namespace  {
21 
22 template <typename T>
23 class MockProperty final : public AnimatablePropertyContainer {
24 public:
MockProperty(const char * jprop)25     explicit MockProperty(const char* jprop) {
26         AnimationBuilder abuilder(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
27                                   {100, 100}, 10, 1, 0);
28         skjson::DOM json_dom(jprop, strlen(jprop));
29 
30         fDidBind = this->bind(abuilder, json_dom.root(), &fValue);
31     }
32 
operator bool() const33     operator bool() const { return fDidBind; }
34 
operator ()(float t)35     const T& operator()(float t) { this->seek(t); return fValue; }
36 
37 private:
onSync()38     void onSync() override {}
39 
40     T     fValue = T();
41     bool  fDidBind;
42 };
43 
44 }  // namespace
45 
DEF_TEST(Skottie_Keyframe,reporter)46 DEF_TEST(Skottie_Keyframe, reporter) {
47     {
48         MockProperty<ScalarValue> prop(R"({})");
49         REPORTER_ASSERT(reporter, !prop);
50     }
51     {
52         MockProperty<ScalarValue> prop(R"({ "a": 1, "k": [] })");
53         REPORTER_ASSERT(reporter, !prop);
54     }
55     {
56         // New style
57         MockProperty<ScalarValue> prop(R"({
58                                          "a": 1,
59                                          "k": [
60                                            { "t":  1, "s": 1 },
61                                            { "t":  2, "s": 2 },
62                                            { "t":  3, "s": 4 }
63                                          ]
64                                        })");
65         REPORTER_ASSERT(reporter, prop);
66         REPORTER_ASSERT(reporter, !prop.isStatic());
67         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( -1), 1));
68         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(  0), 1));
69         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(  1), 1));
70         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1.5f));
71         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(  2), 2));
72         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 3));
73         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(  3), 4));
74         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(  4), 4));
75     }
76     {
77         // New style hold (hard stops)
78         MockProperty<ScalarValue> prop(R"({
79                                          "a": 1,
80                                          "k": [
81                                            { "t":  1, "s": 1, "h": true },
82                                            { "t":  2, "s": 2, "h": true },
83                                            { "t":  3, "s": 4, "h": true }
84                                          ]
85                                        })");
86         REPORTER_ASSERT(reporter, prop);
87         REPORTER_ASSERT(reporter, !prop.isStatic());
88         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0  ), 1));
89         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1  ), 1));
90         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1));
91         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(2.f, 0.f)), 1));
92         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2  ), 2));
93         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 2));
94         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(3.f, 0.f)), 2));
95         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(3  ), 4));
96         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(4  ), 4));
97     }
98     {
99         // Legacy style
100         MockProperty<ScalarValue> prop(R"({
101                                          "a": 1,
102                                          "k": [
103                                            { "t":  1, "s": 1, "e": 2 },
104                                            { "t":  2, "s": 2, "e": 4 },
105                                            { "t":  3 }
106                                          ]
107                                        })");
108         REPORTER_ASSERT(reporter, prop);
109         REPORTER_ASSERT(reporter, !prop.isStatic());
110         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(-1), 1));
111         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 0), 1));
112         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 1  ), 1));
113         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 1.5), 1.5f));
114         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 2  ), 2));
115         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 2.5), 3));
116         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 3  ), 4));
117         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 4  ), 4));
118     }
119     {
120         // Legacy style hold (hard stops)
121         MockProperty<ScalarValue> prop(R"({
122                                          "a": 1,
123                                          "k": [
124                                            { "t":  1, "s": 1, "e": 2, "h": true },
125                                            { "t":  2, "s": 2, "e": 4, "h": true },
126                                            { "t":  3 }
127                                          ]
128                                        })");
129         REPORTER_ASSERT(reporter, prop);
130         REPORTER_ASSERT(reporter, !prop.isStatic());
131         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0  ), 1));
132         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1  ), 1));
133         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1));
134         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(2.f, 0.f)), 1));
135         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2  ), 2));
136         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 2));
137         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(3.f, 0.f)), 2));
138         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(3  ), 4));
139         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(4  ), 4));
140     }
141     {
142         // Static scalar prop (all equal keyframes, using float kf Value)
143         MockProperty<ScalarValue> prop(R"({
144                                          "a": 1,
145                                          "k": [
146                                            { "t":  1, "s": 42, "e": 42 },
147                                            { "t":  2, "s": 42, "e": 42 },
148                                            { "t":  3 }
149                                          ]
150                                        })");
151         REPORTER_ASSERT(reporter, prop);
152         REPORTER_ASSERT(reporter, prop.isStatic());
153         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0), 42));
154     }
155     {
156         // Static vector prop (all equal keyframes, using uint32 kf Value)
157         MockProperty<Vec2Value> prop(R"({
158                                        "a": 1,
159                                        "k": [
160                                          { "t":  1, "s": [4,2], "e": [4,2] },
161                                          { "t":  2, "s": [4,2], "e": [4,2] },
162                                          { "t":  3 }
163                                        ]
164                                      })");
165         REPORTER_ASSERT(reporter, prop);
166         REPORTER_ASSERT(reporter, prop.isStatic());
167         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0).x, 4));
168         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0).y, 2));
169     }
170 }
171