Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Expression.cpp
Go to the documentation of this file.
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>
13#include "tests/Test.h"
15
16using namespace skottie;
17
18namespace {
19
20class FakeScalarExpressionEvaluator : public ExpressionEvaluator<float> {
21public:
22 float evaluate(float t) override { return 7.0f; }
23};
24
25class FakeVectorExpressionEvaluator : public ExpressionEvaluator<std::vector<float>> {
26public:
27 std::vector<float> evaluate(float t) override { return {0.1f, 0.2f, 0.3f, 1.0f}; }
28};
29
30class FakeStringExpressionEvaluator : public ExpressionEvaluator<SkString> {
31public:
32 SkString evaluate(float t) override { return SkString("Hello, world!"); }
33};
34
35class FakeExpressionManager : public ExpressionManager {
36public:
38 const char expression[]) override {
39 return sk_make_sp<FakeScalarExpressionEvaluator>();
40 }
41
43 const char expression[]) override {
44 return sk_make_sp<FakeStringExpressionEvaluator>();
45 }
46
48 const char expression[]) override {
49 return sk_make_sp<FakeVectorExpressionEvaluator>();
50 }
51};
52
53class FakePropertyObserver : public PropertyObserver {
54public:
55 void onOpacityProperty(const char node_name[],
56 const LazyHandle<OpacityPropertyHandle>& opacity_handle) override {
57 opacity_handle_ = opacity_handle();
58 }
59
60 void onTransformProperty(const char node_name[],
61 const LazyHandle<TransformPropertyHandle>& transform_handle) override {
62 transform_handle_ = transform_handle();
63 }
64
65 void onColorProperty(const char node_name[],
66 const LazyHandle<ColorPropertyHandle>& color_handle) override {
67 color_handle_ = color_handle();
68 }
69
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
82DEF_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()
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
269DEF_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()
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}
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
Builder & setExpressionManager(sk_sp< ExpressionManager >)
Definition Skottie.cpp:339
Builder & setPropertyObserver(sk_sp< PropertyObserver >)
Definition Skottie.cpp:319
Builder & setFontManager(sk_sp< SkFontMgr >)
Definition Skottie.cpp:314
sk_sp< Animation > make(SkStream *)
Definition Skottie.cpp:349
virtual T evaluate(float t)=0
virtual sk_sp< ExpressionEvaluator< std::vector< float > > > createArrayExpressionEvaluator(const char expression[])=0
virtual sk_sp< ExpressionEvaluator< SkString > > createStringExpressionEvaluator(const char expression[])=0
virtual sk_sp< ExpressionEvaluator< float > > createNumberExpressionEvaluator(const char expression[])=0
virtual void onTransformProperty(const char node_name[], const LazyHandle< TransformPropertyHandle > &)
virtual void onOpacityProperty(const char node_name[], const LazyHandle< OpacityPropertyHandle > &)
virtual void onTextProperty(const char node_name[], const LazyHandle< TextPropertyHandle > &)
virtual void onColorProperty(const char node_name[], const LazyHandle< ColorPropertyHandle > &)
sk_sp< SkFontMgr > TestFontMgr()
float fX
x-axis value
float fY
y-axis value