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 "include/core/SkSurface.h"
9 #include "modules/skottie/include/Skottie.h"
10 #include "tests/Test.h"
11
12 using namespace skottie;
13
DEF_TEST(Skottie_Image_CustomTransform,r)14 DEF_TEST(Skottie_Image_CustomTransform, r) {
15 static constexpr char json[] =
16 R"({
17 "v": "5.2.1",
18 "w": 100,
19 "h": 100,
20 "fr": 10,
21 "ip": 0,
22 "op": 100,
23 "assets": [{
24 "id": "img_0",
25 "p" : "img_0.png",
26 "u" : "images/",
27 "w" : 100,
28 "h" : 50
29 }],
30 "layers": [
31 {
32 "ip": 0,
33 "op": 100,
34 "ty": 2,
35 "refId": "img_0",
36 "ks": {
37 "p": { "a": 0, "k": [0,25] }
38 }
39 }
40 ]
41 })";
42
43 SkMemoryStream stream(json, strlen(json));
44
45 static const struct TestData {
46 float t;
47 SkMatrix m;
48 SkColor c[5]; // expected color samples at center/L/T/R/B
49 } tests[] {
50 { 0, SkMatrix::I(),
51 {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xff00ff00}},
52 { 1, SkMatrix::Translate(50,25) * SkMatrix::Scale(.5f,.5f) * SkMatrix::Translate(-50,-25),
53 {0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
54 { 2, SkMatrix::Translate(-50, 0),
55 {0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00, 0xff00ff00}},
56 { 3, SkMatrix::Translate(0, -25),
57 {0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00, 0xff00ff00}},
58 { 4, SkMatrix::Translate(50, 0),
59 {0xffff0000, 0xff00ff00, 0xff00ff00, 0xffff0000, 0xff00ff00}},
60 { 5, SkMatrix::Translate(0, 25),
61 {0xffff0000, 0xffff0000, 0xff00ff00, 0xffff0000, 0xffff0000}},
62 };
63
64 class TestImageAsset final : public ImageAsset {
65 public:
66 TestImageAsset(const TestData* tst, skiatest::Reporter* r)
67 : fTest(tst)
68 , fReporter(r) {
69
70 auto surf = SkSurface::MakeRasterN32Premul(200, 100);
71 surf->getCanvas()->drawColor(0xffff0000);
72 fImage = surf->makeImageSnapshot();
73 }
74
75 private:
76 bool isMultiFrame() override { return true; }
77
78 FrameData getFrameData(float t) override {
79 REPORTER_ASSERT(fReporter, t == fTest->t);
80
81 return { fImage, SkSamplingOptions(), fTest++->m };
82 }
83
84 sk_sp<SkImage> fImage;
85 const TestData* fTest;
86 skiatest::Reporter* fReporter;
87 };
88
89 class TestResourceProvider final : public ResourceProvider {
90 public:
91 TestResourceProvider(const TestData* tst, skiatest::Reporter* r)
92 : fTest(tst)
93 , fReporter(r) {}
94
95 private:
96 sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override {
97 return sk_make_sp<TestImageAsset>(fTest, fReporter);
98 }
99
100 const TestData* fTest;
101 skiatest::Reporter* fReporter;
102 };
103
104 auto anim = Animation::Builder()
105 .setResourceProvider(sk_make_sp<TestResourceProvider>(tests, r))
106 .make(&stream);
107
108 REPORTER_ASSERT(r, anim);
109
110 static constexpr SkSize render_size{100, 100};
111 auto surf = SkSurface::MakeRasterN32Premul(render_size.width(), render_size.height());
112 auto rect = SkRect::MakeSize(render_size);
113
114 SkPixmap pmap;
115 surf->peekPixels(&pmap);
116
117 for (const auto& tst : tests) {
118 surf->getCanvas()->clear(0xff00ff00);
119 anim->seekFrameTime(tst.t);
120 anim->render(surf->getCanvas(), &rect);
121
122 REPORTER_ASSERT(r,
123 tst.c[0] == pmap.getColor(render_size.width() / 2, render_size.height() / 2));
124 REPORTER_ASSERT(r,
125 tst.c[1] == pmap.getColor(1 , render_size.height() / 2));
126 REPORTER_ASSERT(r,
127 tst.c[2] == pmap.getColor(render_size.width() / 2, 1));
128 REPORTER_ASSERT(r,
129 tst.c[3] == pmap.getColor(render_size.width() - 1, render_size.height() / 2));
130 REPORTER_ASSERT(r,
131 tst.c[4] == pmap.getColor(render_size.width() /2 , render_size.height() - 1));
132 }
133 }
134