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