test: enhanced the unit-test coverage

supplements animation/lottie/sw_engine test cases.

updated the page: https://github.com/thorvg/thorvg/wiki/Unit-Tests

Issue: https://github.com/thorvg/thorvg/issues/1669
This commit is contained in:
Hermet Park 2023-09-25 16:04:06 +09:00 committed by Hermet Park
parent fdd90605c7
commit c7123a1547
14 changed files with 561 additions and 18 deletions

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <thorvg_capi.h>
#include <string.h>
#include "config.h"
#include "../catch.hpp"
TEST_CASE("Animation Basic", "[capiAnimation]")
{
Tvg_Animation* animation = tvg_animation_new();
REQUIRE(animation);
Tvg_Paint* picture = tvg_animation_get_picture(animation);
REQUIRE(picture);
Tvg_Identifier id = TVG_IDENTIFIER_UNDEF;
REQUIRE(tvg_paint_get_identifier(picture, &id) == TVG_RESULT_SUCCESS);
REQUIRE(id == TVG_IDENTIFIER_PICTURE);
//Negative cases
REQUIRE(tvg_animation_set_frame(animation, 0) == TVG_RESULT_INSUFFICIENT_CONDITION);
uint32_t frame = 0;
REQUIRE(tvg_animation_set_frame(animation, frame) == TVG_RESULT_INSUFFICIENT_CONDITION);
REQUIRE(tvg_animation_get_frame(animation, nullptr) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_animation_get_frame(animation, &frame) == TVG_RESULT_SUCCESS);
REQUIRE(frame == 0);
REQUIRE(tvg_animation_get_total_frame(animation, nullptr) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_animation_get_total_frame(animation, &frame) == TVG_RESULT_SUCCESS);
REQUIRE(frame == 0);
REQUIRE(tvg_animation_get_duration(animation, nullptr) == TVG_RESULT_INVALID_ARGUMENT);
float duration = 0.0f;
REQUIRE(tvg_animation_get_duration(animation, &duration) == TVG_RESULT_SUCCESS);
REQUIRE(duration == 0.0f);
REQUIRE(tvg_animation_del(nullptr) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_animation_del(animation) == TVG_RESULT_SUCCESS);
}
#ifdef THORVG_LOTTIE_LOADER_SUPPORT
TEST_CASE("Animation Lottie", "[capiAnimation]")
{
REQUIRE(tvg_engine_init(TVG_ENGINE_SW, 0) == TVG_RESULT_SUCCESS);
Tvg_Animation* animation = tvg_animation_new();
REQUIRE(animation);
Tvg_Paint* picture = tvg_animation_get_picture(animation);
REQUIRE(picture);
Tvg_Identifier id = TVG_IDENTIFIER_UNDEF;
REQUIRE(tvg_paint_get_identifier(picture, &id) == TVG_RESULT_SUCCESS);
REQUIRE(id == TVG_IDENTIFIER_PICTURE);
REQUIRE(tvg_picture_load(picture, TEST_DIR"/invalid.json") == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_picture_load(picture, TEST_DIR"/test.json") == TVG_RESULT_SUCCESS);
uint32_t frame;
REQUIRE(tvg_animation_get_total_frame(animation, &frame) == TVG_RESULT_SUCCESS);
REQUIRE(frame == 120);
REQUIRE(tvg_animation_set_frame(animation, frame - 1) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_animation_get_frame(animation, &frame) == TVG_RESULT_SUCCESS);
REQUIRE(frame == 119);
float duration;
REQUIRE(tvg_animation_get_duration(animation, &duration) == TVG_RESULT_SUCCESS);
REQUIRE(duration == Approx(4).margin(004004));
REQUIRE(tvg_animation_del(animation) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_engine_term(TVG_ENGINE_SW) == TVG_RESULT_SUCCESS);
}
#endif

View file

@ -1,4 +1,5 @@
test_file = [
'capiAnimation.cpp',
'capiInitializer.cpp',
'capiFill.cpp',
'capiLinearGradient.cpp',

1
test/images/test.json Normal file
View file

@ -0,0 +1 @@
{"v":"5.2.1","fr":29.9700012207031,"ip":0,"op":120.0000048877,"w":150,"h":120,"nm":"logo 2","ddd":1,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[98,45.5,0],"ix":2},"a":{"a":0,"k":[-23,-14.5,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[19.25,-19.25],[0,0],[0,0]],"o":[[0,0],[0,0],[-20.25,20.25],[0,0],[0,0]],"v":[[19.5,-14],[-12.5,-45.25],[-51.25,-42.25],[-55.75,-5.25],[-23,28.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":8,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.584,0.894,0.929,0.5,0.692,0.733,0.965,1,0.8,0.573,1],"ix":8}},"s":{"a":0,"k":[-64.303,-9.492],"ix":4},"e":{"a":0,"k":[23.721,-13.33],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[100],"e":[0]},{"t":60.0000024438501}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,60,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[22.75,-19.25],[0,0],[0,0]],"o":[[0,0],[0,0],[-19.75,19.75],[0,0],[0,0]],"v":[[19.5,-14],[-12.5,-45.25],[-51.25,-42.25],[-55.75,-5.25],[-23,28.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":8,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,1,0.788,0.6,0.5,0.902,0.682,0.798,1,0.804,0.576,0.996],"ix":8}},"s":{"a":0,"k":[-64.303,-9.492],"ix":4},"e":{"a":0,"k":[23.721,-13.33],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[100],"e":[0]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.5,103,0],"ix":2},"a":{"a":0,"k":[0,42.5,0],"ix":1},"s":{"a":0,"k":[91.956,91.956,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[18.648,18.648],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.8,0.572549019608,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,42.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":60,"s":[100],"e":[0]},{"t":89.0000036250443}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0}],"markers":[]}

1
test/images/test2.json Normal file

File diff suppressed because one or more lines are too long

1
test/images/test3.json Normal file

File diff suppressed because one or more lines are too long

1
test/images/test4.json Normal file
View file

@ -0,0 +1 @@
{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[152,152,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"sr","sy":1,"d":2,"pt":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[5],"e":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[11],"e":[15]},{"t":146.000005946702}],"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[64]},{"t":90.0000036657751}],"ix":5},"ir":{"a":0,"k":106,"ix":6},"is":{"a":0,"k":231,"ix":8},"or":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[102],"e":[142]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[142],"e":[34]},{"t":146.000005946702}],"ix":7},"os":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[79],"e":[265]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[265],"e":[88]},{"t":146.000005946702}],"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]}

1
test/images/test5.json Normal file

File diff suppressed because one or more lines are too long

1
test/images/test6.json Normal file

File diff suppressed because one or more lines are too long

1
test/images/test7.json Normal file

File diff suppressed because one or more lines are too long

1
test/images/test8.json Normal file
View file

@ -0,0 +1 @@
{"v":"5.1.16","fr":15,"ip":0,"op":51,"w":500,"h":500,"nm":"El 28","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Circle Abstract","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[100],"e":[0]},{"t":51}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250.316,250.684,0],"ix":2},"a":{"a":0,"k":[280,0,0],"ix":1},"s":{"a":0,"k":[225,225,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[145,145],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.190695878571,0.889764404297,0.972549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.583]},"o":{"x":[0.01],"y":[0.006]},"n":["0p833_0p583_0p01_0p006"],"t":22.2,"s":[3],"e":[0]},{"t":49.2001953125}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[236,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.99,0.99],"y":[0.997,0.997]},"o":{"x":[1,1],"y":[1,1]},"n":["0p99_0p997_1_1","0p99_0p997_1_1"],"t":0,"s":[0,0],"e":[50,50]},{"i":{"x":[0.833,0.833],"y":[0.676,0.676]},"o":{"x":[0.01,0.01],"y":[0.043,0.043]},"n":["0p833_0p676_0p01_0p043","0p833_0p676_0p01_0p043"],"t":6,"s":[50,50],"e":[75,75]},{"t":49.2001953125}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":1,"k":[{"i":{"x":[0.99],"y":[0.985]},"o":{"x":[1],"y":[2.692]},"n":["0p99_0p985_1_2p692"],"t":0,"s":[0],"e":[18]},{"i":{"x":[0.833],"y":[0.288]},"o":{"x":[0.01],"y":[-0.02]},"n":["0p833_0p288_0p01_-0p02"],"t":21,"s":[18],"e":[0]},{"t":49.2001953125}],"ix":1},"o":{"a":0,"k":5,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[280,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":20,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":0,"op":51,"st":0,"bm":0}],"markers":[]}

1
test/images/test9.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -4,6 +4,7 @@ endif
test_file = [
'testAccessor.cpp',
'testAnimation.cpp',
'testFill.cpp',
'testInitializer.cpp',
'testMain.cpp',

193
test/testAnimation.cpp Normal file
View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <thorvg.h>
#include <fstream>
#include <cstring>
#include "config.h"
#include "catch.hpp"
using namespace tvg;
using namespace std;
TEST_CASE("Animation Basic", "[tvgAnimation]")
{
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
//Negative cases
REQUIRE(animation->frame(0) == Result::InsufficientCondition);
REQUIRE(animation->curFrame() == 0);
REQUIRE(animation->totalFrame() == 0);
REQUIRE(animation->duration() == 0.0f);
}
#ifdef THORVG_LOTTIE_LOADER_SUPPORT
TEST_CASE("Animation Lottie", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 1) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/invalid.json") == Result::InvalidArguments);
REQUIRE(picture->load(TEST_DIR"/test.json") == Result::Success);
REQUIRE(animation->totalFrame() == 120);
REQUIRE(animation->curFrame() == 0);
REQUIRE(animation->duration() == Approx(4).margin(004004));
REQUIRE(animation->frame(20) == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie2", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test2.json") == Result::Success);
REQUIRE(animation->frame(20) == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie3", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test3.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie4", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test4.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie5", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test5.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie6", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test6.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie7", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test7.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie8", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test8.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Animation Lottie9", "[tvgAnimation]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto animation = Animation::gen();
REQUIRE(animation);
auto picture = animation->picture();
REQUIRE(picture->identifier == Picture::identifier);
REQUIRE(picture->load(TEST_DIR"/test9.json") == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
#endif

View file

@ -93,7 +93,6 @@ TEST_CASE("Basic draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Image Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -242,7 +241,6 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(basicPicture7->opacity(100) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture7)) == Result::Success);
// Upscaled images
basicPicture = Picture::gen();
REQUIRE(basicPicture);
@ -307,7 +305,6 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(basicPicture7->opacity(100) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture7)) == Result::Success);
// Downscaled images
basicPicture = Picture::gen();
REQUIRE(basicPicture);
@ -381,7 +378,6 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
free(data);
}
TEST_CASE("Rect Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -440,7 +436,6 @@ TEST_CASE("Rect Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -499,7 +494,6 @@ TEST_CASE("RLE Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -549,7 +543,6 @@ TEST_CASE("Filling Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling Opaque Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -599,7 +592,6 @@ TEST_CASE("Filling Opaque Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling AlphaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -659,7 +651,6 @@ TEST_CASE("Filling AlphaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling InvAlphaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -719,7 +710,6 @@ TEST_CASE("Filling InvAlphaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling LumaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -779,7 +769,6 @@ TEST_CASE("Filling LumaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Filling ClipPath", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -839,7 +828,6 @@ TEST_CASE("Filling ClipPath", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -889,7 +877,6 @@ TEST_CASE("RLE Filling Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling Opaque Draw", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -939,7 +926,6 @@ TEST_CASE("RLE Filling Opaque Draw", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling AlphaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -999,7 +985,6 @@ TEST_CASE("RLE Filling AlphaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling InvAlphaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -1059,7 +1044,6 @@ TEST_CASE("RLE Filling InvAlphaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling LumaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -1119,7 +1103,6 @@ TEST_CASE("RLE Filling LumaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling InvLumaMask", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -1179,7 +1162,6 @@ TEST_CASE("RLE Filling InvLumaMask", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("RLE Filling ClipPath", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
@ -1239,4 +1221,262 @@ TEST_CASE("RLE Filling ClipPath", "[tvgSwEngine]")
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Blending Shapes", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto canvas = SwCanvas::gen();
REQUIRE(canvas);
uint32_t buffer[100*100];
REQUIRE(canvas->target(buffer, 100, 100, 100, SwCanvas::Colorspace::ABGR8888) == Result::Success);
BlendMethod methods[14] = {
BlendMethod::Normal,
BlendMethod::Add,
BlendMethod::Screen,
BlendMethod::Multiply,
BlendMethod::Overlay,
BlendMethod::Difference,
BlendMethod::Exclusion,
BlendMethod::SrcOver,
BlendMethod::Darken,
BlendMethod::Lighten,
BlendMethod::ColorDodge,
BlendMethod::ColorBurn,
BlendMethod::HardLight,
BlendMethod::SoftLight
};
int i = 0;
for (; i < 7; ++i) {
auto shape = tvg::Shape::gen();
REQUIRE(shape);
REQUIRE(shape->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape->fill(255, 255, 255) == Result::Success);
shape->blend(methods[i]);
REQUIRE(canvas->push(std::move(shape)) == Result::Success);
}
for (; i < 14; ++i) {
auto shape = tvg::Shape::gen();
REQUIRE(shape);
REQUIRE(shape->appendCircle(50, 50, 50, 50) == Result::Success);
REQUIRE(shape->fill(255, 255, 255) == Result::Success);
shape->blend(methods[i]);
REQUIRE(canvas->push(std::move(shape)) == Result::Success);
}
//Draw
REQUIRE(canvas->draw() == Result::Success);
REQUIRE(canvas->sync() == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
TEST_CASE("Blending Images", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto canvas = SwCanvas::gen();
REQUIRE(canvas);
uint32_t buffer[100*100];
REQUIRE(canvas->target(buffer, 100, 100, 100, SwCanvas::Colorspace::ABGR8888) == Result::Success);
//raw image
ifstream file(TEST_DIR"/rawimage_200x300.raw");
if (!file.is_open()) return;
auto data = (uint32_t*)malloc(sizeof(uint32_t) * (200*300));
file.read(reinterpret_cast<char *>(data), sizeof (uint32_t) * 200 * 300);
file.close();
//direct clipped image
auto clipper = Shape::gen();
REQUIRE(clipper);
REQUIRE(clipper->appendCircle(100, 100, 100, 100) == Result::Success);
auto picture = Picture::gen();
REQUIRE(picture);
REQUIRE(picture->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(picture->composite(std::move(clipper), CompositeMethod::ClipPath) == Result::Success);
REQUIRE(canvas->push(std::move(picture)) == Result::Success);
//scaled images
auto picture2 = Picture::gen();
REQUIRE(picture2);
REQUIRE(picture2->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture2->scale(2) == Result::Success);
REQUIRE(picture2->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(canvas->push(std::move(picture2)) == Result::Success);
//scaled clipped images
auto clipper2 = Shape::gen();
REQUIRE(clipper2);
REQUIRE(clipper2->appendCircle(100, 100, 100, 100) == Result::Success);
auto picture3 = Picture::gen();
REQUIRE(picture3);
REQUIRE(picture3->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture3->scale(2) == Result::Success);
REQUIRE(picture3->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(picture3->composite(std::move(clipper2), CompositeMethod::ClipPath) == Result::Success);
REQUIRE(canvas->push(std::move(picture3)) == Result::Success);
//normal image
auto picture4 = Picture::gen();
REQUIRE(picture4);
REQUIRE(picture4->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture4->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(canvas->push(std::move(picture4)) == Result::Success);
//texmap image
auto picture5 = Picture::gen();
REQUIRE(picture5);
REQUIRE(picture5->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture5->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(picture5->rotate(45.0f) == Result::Success);
REQUIRE(canvas->push(std::move(picture5)) == Result::Success);
//texmap image with half-translucent
auto picture6 = Picture::gen();
REQUIRE(picture6);
REQUIRE(picture6->load(data, 200, 300, false) == Result::Success);
REQUIRE(picture6->blend(BlendMethod::Lighten) == Result::Success);
REQUIRE(picture6->rotate(45.0f) == Result::Success);
REQUIRE(picture6->opacity(127) == Result::Success);
REQUIRE(canvas->push(std::move(picture6)) == Result::Success);
//Draw
REQUIRE(canvas->draw() == Result::Success);
REQUIRE(canvas->sync() == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
free(data);
}
TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]")
{
REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
auto canvas = SwCanvas::gen();
REQUIRE(canvas);
uint32_t buffer[100*100];
REQUIRE(canvas->target(buffer, 100, 100, 100, SwCanvas::Colorspace::ABGR8888) == Result::Success);
Fill::ColorStop cs[4] = {
{0.0f, 0, 0, 0, 0},
{0.2f, 50, 25, 50, 25},
{0.5f, 100, 100, 100, 125},
{1.0f, 255, 255, 255, 255}
};
//Linear fill Shape
auto linearFill = LinearGradient::gen();
REQUIRE(linearFill);
REQUIRE(linearFill->colorStops(cs, 4) == Result::Success);
REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success);
auto shape1 = tvg::Shape::gen();
REQUIRE(shape1);
REQUIRE(shape1->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape1->fill(std::move(linearFill)) == Result::Success);
REQUIRE(shape1->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape1)) == Result::Success);
//Radial fill shape
auto radialFill = RadialGradient::gen();
REQUIRE(radialFill);
REQUIRE(radialFill->colorStops(cs, 4) == Result::Success);
REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success);
auto shape2 = tvg::Shape::gen();
REQUIRE(shape2);
REQUIRE(shape2->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape2->fill(std::move(radialFill)) == Result::Success);
REQUIRE(shape2->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape2)) == Result::Success);
//Linear fill alpha mask shape
auto linearFill2 = LinearGradient::gen();
REQUIRE(linearFill2);
REQUIRE(linearFill2->colorStops(cs, 4) == Result::Success);
REQUIRE(linearFill2->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success);
auto mask = tvg::Shape::gen();
REQUIRE(mask);
mask->appendCircle(50, 50, 50, 50);
auto shape3 = tvg::Shape::gen();
REQUIRE(shape3);
REQUIRE(shape3->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape3->fill(std::move(linearFill2)) == Result::Success);
REQUIRE(shape3->composite(std::move(mask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(shape3->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape3)) == Result::Success);
//Radial fill alpha mask shape
auto radialFill2 = RadialGradient::gen();
REQUIRE(radialFill2);
REQUIRE(radialFill2->colorStops(cs, 4) == Result::Success);
REQUIRE(radialFill2->radial(50.0f, 50.0f, 50.0f) == Result::Success);
auto mask2 = tvg::Shape::gen();
REQUIRE(mask2);
mask2->appendCircle(50, 50, 50, 50);
auto shape4 = tvg::Shape::gen();
REQUIRE(shape4);
REQUIRE(shape4->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape4->fill(std::move(radialFill2)) == Result::Success);
REQUIRE(shape4->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(shape4->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape4)) == Result::Success);
//Linear fill add mask shape
auto linearFill3 = LinearGradient::gen();
REQUIRE(linearFill3);
REQUIRE(linearFill3->colorStops(cs, 4) == Result::Success);
REQUIRE(linearFill3->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success);
auto mask3 = tvg::Shape::gen();
REQUIRE(mask3);
mask3->appendCircle(50, 50, 50, 50);
auto shape5 = tvg::Shape::gen();
REQUIRE(shape5);
REQUIRE(shape5->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape5->fill(std::move(linearFill3)) == Result::Success);
REQUIRE(shape5->composite(std::move(mask3), tvg::CompositeMethod::AddMask) == Result::Success);
REQUIRE(shape5->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape5)) == Result::Success);
//Radial fill add mask shape
auto radialFill3 = RadialGradient::gen();
REQUIRE(radialFill3);
REQUIRE(radialFill3->colorStops(cs, 4) == Result::Success);
REQUIRE(radialFill3->radial(50.0f, 50.0f, 50.0f) == Result::Success);
auto mask4 = tvg::Shape::gen();
REQUIRE(mask4);
mask4->appendCircle(50, 50, 50, 50);
auto shape6 = tvg::Shape::gen();
REQUIRE(shape6);
REQUIRE(shape6->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape6->fill(std::move(radialFill3)) == Result::Success);
REQUIRE(shape6->composite(std::move(mask4), tvg::CompositeMethod::SubtractMask) == Result::Success);
REQUIRE(shape6->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape6)) == Result::Success);
//Draw
REQUIRE(canvas->draw() == Result::Success);
REQUIRE(canvas->sync() == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}
#endif